How to pass the parameters to a function converted from custom hook?

Viewed 3360

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?

1 Answers

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,
    },
  );
};
Related