Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move useEffect from component to custom hook

I have multiple components with the same useEffect code.

fucntion MyComponent1 (props) {

 const {
        handleApiCall,
        data,
        isLoading,
        isError,
        isSuccess,
  } = useCustomAsyncHook();

 React.useEffect(() => {
   if (isSuccess && !isEmpty(data)) {
      setSnackbar({
        show: false,
        message: '',
      });
      dispatch({
        type: ACTION_TYPES.UPDATE_METADATA,
        payload: { data },
      });
    }
 }, [data, isSuccess, setSnackbar]);

 const onSave = () => {
     handleApiCall()
 }

 return (
   <button onClick={onSave}> Save </button>
 )

}

I have this useEffect hook code repeating in multiple components. I just want to move this useEffect hook into custom hook so that I need not repeat it in multiple components.

const useMetadataUpdate = ({ data, isSuccess, setSnackbar, dispatch }) => {
    React.useEffect(() => {
        if (isSuccess && !isEmpty(data)) {
            setSnackbar({
                show: false,
                message: '',
            });
            dispatch({
                type: ACTION_TYPES.UPDATE_METADATA,
                payload: { data },
            });
        }
    }, [data, isSuccess, setSnackbar, dispatch]);
};

fucntion MyComponet1 (props) {
   const {
        handleApiCall,
        data,
        isLoading,
        isError,
        isSuccess,
  } = useCustomAsyncHook();

  useMetadataUpdate({ data, isSuccess, setSnackbar, dispatch });

  const onSave = () => {
     handleApiCall()
 }

 return (
   <button onClick={onSave}> Save </button>
 ) 
}

Refactoring useEffect to a separate function works. I can't find documentation explicitly stating a hook needs to return anything, however, I cannot find an example of a hook not returning something. Can someone advise on if this approach is correct?

like image 935
shrinidhi kulkarni Avatar asked Oct 22 '25 12:10

shrinidhi kulkarni


1 Answers

To clean up your component, you can move useEffect to a custom hook that contains the same logic as the original.

For example

// useCodeSelection.js
...
export const useCodeSelection = () => {
    useEffect(() => {
        console.log('useCodeSelection')
    }
}
...

Then inside your component just call it after you import it, like:

...
useCodeSelection()
...