I am fetching data using RTK Query but when errors occur I create a toast using react-toastify library that shows a toast message multiple times how to prevent this? when I consol log I see that part of 'if' condition render multiple times.
import FoodBox from "../components/FoodBox";
import styled from "styled-components";
import { useFetchFoodsQuery } from "../store";
import { useSelector } from "react-redux";
import Skeleton from "./Skeleton";
import { toast } from "react-toastify";
const Foods = styled.div`
overflow-y: auto;
overflow-x: hidden;
height: 370px;
padding: 0 30px;
`;
function FoodList({ shopId }) {
let { data: foods, error, isFetching } = useFetchFoodsQuery(shopId);
const user = useSelector((state) => state.user.currentUser);
let content;
if (isFetching) {
content = (
<Foods>
<Skeleton w="22.5rem" h="3.5rem" times={5} />
</Foods>
);
} else if (error) {
toast('Error');
return <div>Error in loading food</div>;
} else {
if (!user) {
foods = foods?.filter((food) => food.isVisible);
}
content = (
<Foods>
{foods?.map((food) => (
<FoodBox key={food?._id} food={food} />
))}
</Foods>
);
}
return content;
}
export default FoodList;
The code is calling toast
as an unintentional side-effect outside the React component lifecycle. The React component render method (yes, the entire React function component body is the "render method") is to be considered a pure function, free of side-effects. "Double rendering" most likely is happening from rendering the app into the React.StrictMode
component where it intentionally double invokes specific lifecycle methods and double mounts the component as a debugging method to help you find issues in your code, like unexpected side-effects.
See:
Dispatch the toast from an expected lifecycle method, e.g. the useEffect
hook. The useEffect
is "one side-effect per component render to the DOM".
Example:
function FoodList({ shopId }) {
const { data: foods, error, isFetching } = useFetchFoodsQuery(shopId);
const user = useSelector((state) => state.user.currentUser);
// Issue intentional side effect
React.useEffect(() => {
if (error) {
toast('Error');
}
}, [error]);
if (isFetching) {
return (
<Foods>
<Skeleton w="22.5rem" h="3.5rem" times={5} />
</Foods>
);
} else if (error) {
return <div>Error in loading food</div>;
} else {
return (
<Foods>
{foods?.filter((food) => !!user || food.isVisible
.map((food) => <FoodBox key={food?._id} food={food} />)
}
</Foods>
);
}
}