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?
The current issue as I can see here is that you have 3 functions namely isEmpty
, setSnackbar
, and dispatch
tightly coupled to your components here. This restricts you from directly moving this useEffect
to your custom hook. The best solution that I can think of right now is moving these functions to a custom hook(you can combine this with context API as well). After that, you can do the following in your custom hook
const useCustomAsyncHook = () => {
// code to fetch dependenices like `data`, `isSuccess` goes here
const { setSnackbar, isEmpty, dispatch } = useAnotherCustomHook();
React.useEffect(() => {
if (isSuccess && !isEmpty(data)) {
setSnackbar({
show: false,
message: '',
});
dispatch({
type: ACTION_TYPES.UPDATE_METADATA,
payload: { data },
});
}
}, [data, isSuccess, setSnackbar]);
};
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()
...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.