I am trying to create a custom hook to wrap about Notistack (https://github.com/iamhosseindhv/notistack), a library for snackbars.
My hook looks like this:
import { useCallback } from 'react';
import { useSnackbar as useNotistackSnackbar } from 'notistack';
import { SNACKBAR_TYPES } from '../constants/properties';
const useSnackbar = () => {
const { enqueueSnackbar } = useNotistackSnackbar();
const showSnackbarVariant = useCallback(
({ text, action_text, onActionClick, variant }) =>
enqueueSnackbar(
{
variant,
text,
action_text,
onActionClick,
},
{ autoHideDuration: action_text && onActionClick ? 9000 : 4000 }
),
[enqueueSnackbar]
);
return {
showSuccessSnackbar: ({ text, action_text, onActionClick }) =>
showSnackbarVariant({
variant: SNACKBAR_TYPES.SUCCESS,
text,
action_text,
onActionClick,
}),
showErrorSnackbar: ({ text, action_text, onActionClick }) =>
showSnackbarVariant({
variant: SNACKBAR_TYPES.ERROR,
text,
action_text,
onActionClick,
}),
showWarningSnackbar: ({ text, action_text, onActionClick }) =>
showSnackbarVariant({
variant: SNACKBAR_TYPES.WARNING,
text,
action_text,
onActionClick,
}),
showDownloadSnackbar: ({ text, action_text, onActionClick }) =>
showSnackbarVariant({
variant: SNACKBAR_TYPES.DOWNLOAD,
text,
action_text,
onActionClick,
}),
showPlainSnackbar: ({ text, action_text, onActionClick }) =>
showSnackbarVariant({
variant: SNACKBAR_TYPES.PLAIN,
text,
action_text,
onActionClick,
}),
};
};
export default useSnackbar;
I need to use it in 2 places:
- outside of useEffect (but still within the component)
- inside of useEffect
However, even if I just add it as just a dependency on useEffect, it causes the infinite loop inside useEffect:
export default function MyComponent() {
const { showSuccessSnackbar, showErrorSnackbar } = useSnackbar();
const { mutate: activateConnectedAccount } =
useCustomHook({
onSuccess: async () => {
showSuccessSnackbar({
text: 'Direct deposit has been enabled.',
});
},
onError: () => {
showErrorSnackbar({
text: 'An error occurred. Please double check your bank information.',
});
},
});
useEffect(
() => {
activateConnectedAccount()
console.log("yooo");
},
[
// showSuccessSnackbar
]
);
return (
<div>
Foobar
</div>
);
}
Codesandbox link: If you comment in line 30, it will cause the browser to freeze because it keeps running that loop
https://codesandbox.io/s/currying-browser-5vomm?file=/src/MyComponent.js