I am fetching a list of series from the MySQL db using Express API. I checked on Express logs and see the request is made 2 times. I console logged the react component and the useEffect hook and see the component itself is rendered 5-6 times and the useEffect his rendered 2 times (based on the console log outputs in the chrome browser). What am i doing wrong? Here is my code:
import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from "react-redux";
import { fetchSeries } from '../../Redux/Actions/SeriesActions';
const MyList = () => {
const [isSeriesOpen, setIsSeriesOpen] = useState(false);
const dispatch = useDispatch();
const series = useSelector((state) => state.seriesList.series);
const userId = useSelector((state) => state.auth.user_id);
const companyId = 3;
console.log("Log from the component");
useEffect(() => {
dispatch(fetchSeries(userId, companyId));
console.log("Log for Effect called");
}, [dispatch]);
return (
<div>
<p> Test Content</p>
</div>
);
};
export default MyList;
I tried checking if there is anything making the component re-render. The component is imported in the Routes which is imported in the App.js which is imported in index.js. But this is a normal structure for React, isnt it? I dont undertsnad why useEffect is called 2 times and hence 2 requests are made to the api causeing it to run query on the db 2 times.
4
Answers
React renders twice while in development.
See:
Source: React Docs: Strict Mode
Also, you should add all the variables that are used inside the useEffect, into the dependency array at the end
Currently, you have [dispatch] as the dependency array, which means the effect will be re-executed whenever dispatch changes. Since dispatch is a function provided by Redux, it will change on every render, leading to the effect being executed multiple times.
To fix this issue, you should include all dependencies that affect the effect inside the dependency array. In your case, userId and companyId are likely the dependencies that should trigger the effect to re-run when they change. Here’s how you can modify your useEffect hook:
In your code, the useEffect is set up to run whenever the dispatch function changes. Since dispatch is a function created by useDispatch, it will always change between renders. This is a common pitfall with Redux when used with React hooks.
Here’s a modified version of your code that should resolve the issue:
export default MyList;
By adding userId and companyId to the dependency array, you’re ensuring that the effect will only run when these values change. This should help prevent unnecessary API calls and resolve the issue of useEffect being called multiple times.
1.Without Dependencies:
If you pass an empty dependency array ([]) to useEffect, it runs once after the initial render.
If you omit the dependency array entirely, it runs after every render.
2.With Dependencies:
If you provide dependencies in the dependency array, useEffect will run after the initial render and whenever any of the specified dependencies change.
This helps in controlling when the effect should run based on the changes in specific variables.
3.Without Dependencies Array:
If you don’t pass any dependencies array to the useEffect, it means the effect will run after every render of the component it means infinity times. This is similar to having a dependency array with no dependencies.
The effect will run after the initial render.It will run again whenever the component re-renders, regardless of the reason for the re-render.It’s useful for situations where you want the effect to run after every update or if the effect doesn’t depend on any specific values.