I have this code
// snackbar.js
import { isString } from 'lodash';
import { useCallback, useMemo, useState } from 'react';
import toast from 'react-hot-toast';
const useSnackBar = () => {
const [keys, setKeys] = useState([]);
const closeSnackbar = useCallback(() => {
toast.remove();
}, []);
const toastLoading = useCallback(message => {
const key = toast.loading(message, { duration: 0 });
setKeys(current => [...current, key]);
}, []);
const toastSuccess = useCallback(message => {
toast.success(message);
}, []);
const toastInfo = useCallback(message => {
toast(message);
}, []);
const toastError = useCallback(error => {
if (error.response) {
toast.error(error.response.data.message);
} else if (isString(error)) {
toast.error(error);
} else {
toast.error(
'Something unexpected happened, we are investigating this issue right now',
);
}
}, []);
const displaySnackbar = useCallback((variant, data, options = {}) => {
const closeLoading = () => {
if (keys.length >= 1) {
keys.map(() => closeSnackbar());
}
};
closeSnackbar();
switch (variant) {
case 'error':
toastError(data);
break;
case 'success':
toastSuccess(data);
break;
case 'loading':
toastLoading(data);
break;
case 'info':
toastInfo(data);
break;
default:
closeLoading();
}
}, []);
return [displaySnackbar, closeSnackbar];
};
export default useSnackBar;
and use it like this
// import and upper code
const [displaySnackbar, closeSnackbar] = useSnackbar();
useEffect(() => {
if (loading.data) {
displaySnackbar('loading', 'Searching batch disbursement data');
}
}, [loading.data, displaySnackbar]);
// return components
if I remove displaySnackbar
deps from useEffect it works perfectly, but because it need to be deps (linter error) it keep looping when it got triggered.
Any solution?
Update:
https://codesandbox.io/s/red-resonance-m8h2vi
CodePudding user response:
You are updating keys
infinitely, I just added a condition to show you where the loop is
const toastLoading = useCallback((message) => {
const key = toast.loading(message, { duration: 0 });
if (message !== "Loading") {
setKeys((current) => [...current, key]);
}
}, []);