I have a custom hook, it will fire two actions in my Redux slice "myTestSlice", action1 and action2, behind each action, I have reducer function to get new state.
const useSetMyObjects = (
actions,
{ object1Name, object1Id, object2Name, object2Id }, // here throws the error cannot read property of undefined when I call the function converted from this custom hook
) => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(actions.action1({ object1Name, object1Id }));
}, [object1Name, object1Id, actions, dispatch]);
useEffect(() => {
dispatch(
actions.action2({
object2Name,
object2Id
}),
);
}, [object2Name, object2Id, actions, dispatch]);
};
export default useSetMyObjects;
I have a react component, I want to use this custom hook in an array loop and also in an event handler. So I have to turn this custom hook to a function to use it, otherwise I get warning:
React Hook "useSetMyObjects" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function
But I have no idea how to convert this custom hook to a function.
Here is how I will use the function converted from the custom hook:
I want to use function setTwoObjects in an useEffect:
useEffect(() => {
myData.map((data) =>
useSetMyObjects(myTestSlice.actions, {//supposed to use that converted function instead of useSetMyObjects here, but no idea how
object1Name: data.object1Name,
object1Id: data.object1Id,
object2Name: data.object2Name,
object2Id: data.object2Id
}),
);
}
}, [myData, useSetMyObjects]);
And I also use the function setTwoObjects in an event handler:
const handleSelect = (e, value) => {
const newData = value;
useSetMyObjects(myTestSlice.actions, {//supposed to use that converted function instead of useSetMyObjects here, but no idea how
object1Name: newData.object1Name,
object1Id: newData.object1Id,
object2Name: newData.object2Name,
object2Id: newData.object2Id,
});
}
};
How can I convert the custom hook to a function so I can call it in the callback or an event handler?
Instead of the useSetMyObjects
hook taking the arguments, you want the hook to return a function that takes the arguments and wraps the actions in the call to dispatch
for you.
const useSetMyObjects = () => {
const dispatch = useDispatch();
const setTwoObjects = (
actions,
{ object1Name, object1Id, object2Name, object2Id },
) => {
dispatch(actions.action1({ object1Name, object1Id }));
dispatch(actions.action2({ object2Name, object2Id }));
};
return setTwoObjects;
};
Usage:
const setTwoObjects = useSetMyObjects();
...
useEffect(() => {
myData.map((data) =>
setTwoObjects(
myTestSlice.actions,
{
object1Name: data.object1Name,
object1Id: data.object1Id,
object2Name: data.object2Name,
object2Id: data.object2Id
},
)
);
}, [myData, useSetMyObjects]);
...
const handleSelect = (e, value) => {
const newData = value;
setTwoObjects(
myTestSlice.actions,
{
object1Name: newData.object1Name,
object1Id: newData.object1Id,
object2Name: newData.object2Name,
object2Id: newData.object2Id,
},
);
};