11

I want to use useEffect, but when I add getUpperGroup method, I get warning:

React Hook useEffect has a missing dependency: 'getUpperGroups'. Either include it or remove the dependency array"

My code is:

useEffect(() => {
  getUpperGroups();
  setContentData(contentGroupData);
}, [contentGroupData]);


const [contentData, setContentData] = useState<Fundation[]>([] as Fundation[]);
const [upperGroups, setUpperGroups] = useState({});

const getUpperGroups = () => {

   let newUpperGroups = upperGroups;

   contentGroupData.forEach(content=>{
     newUpperGroups = {...newUpperGroups, [content.id]: content.title};
   })

   setUpperGroups(newUpperGroups);
}
Samet Sunman
  • 329
  • 1
  • 4
  • 11

4 Answers4

10

You have two mistakes.

1- You defined getUpperGroups after useEffect, so you can't add it to the list of useEffect dependencies.

2- if you add getUpperGroups to list of useEffect dependencies, useEffect will run on every re-render and you give a loop of re-render error.

So there is two solutions.

1- Add getUpperGroups into useEffect

const [contentData, setContentData] = useState<Fundation[]>([] as Fundation[]);
const [upperGroups, setUpperGroups] = useState({});


useEffect(() => {
  
  const getUpperGroups = () => {

   let newUpperGroups = upperGroups;

   contentGroupData.forEach(content=>{
     newUpperGroups = {...newUpperGroups, [content.id]: content.title};
   })

   setUpperGroups(newUpperGroups);
  }

  getUpperGroups();
}, [contentGroupData]);

2- Disable eslint

useEffect(() => {
  getUpperGroups();
  setContentData(contentGroupData);

  // eslint-disable-line react-hooks/exhaustive-deps
}, [contentGroupData]);


const [contentData, setContentData] = useState<Fundation[]>([] as Fundation[]);
const [upperGroups, setUpperGroups] = useState({});

const getUpperGroups = () => {

   let newUpperGroups = upperGroups;

   contentGroupData.forEach(content=>{
     newUpperGroups = {...newUpperGroups, [content.id]: content.title};
   })

   setUpperGroups(newUpperGroups);
}
Divyesh Kanzariya
  • 3,629
  • 3
  • 43
  • 44
Hossein Mohammadi
  • 1,388
  • 11
  • 16
2

You can either:

  1. Suppress that rule for the entire project: Go to .eslintrc file and change 'react-hooks/exhaustive-deps': 'error' to 'react-hooks/exhaustive-deps': 'warn' or 'react-hooks/exhaustive-deps': 'off'

  2. Supress the rule only in this instance:

useEffect(() => {
    getUpperGroups();
    setContentData(contentGroupData);
}, [contentGroupData]);


const [contentData, setContentData] = useState<Fundation[]>([] as Fundation[]);
const [upperGroups, setUpperGroups] = useState({});

const getUpperGroups = () => {

    let newUpperGroups = upperGroups;

    contentGroupData.forEach(content=>{
        newUpperGroups = {...newUpperGroups, [content.id]: content.title};
    })

    setUpperGroups(newUpperGroups);
} // eslint-disable-line react-hooks/exhaustive-deps
JeannotMn
  • 184
  • 1
  • 9
  • I don't understand. You fix the error by turning off the message? This is what it sounds like for me, unless you can explain that what's happening is not actually a valid warning? Can you please clarify. – Daniel Tkach Sep 10 '21 at 20:41
  • 1
    That is an eslint warning, so it is trying to tell you that this is not "good practice" or this is not recommended as there might be some unexpected/undesired behavior as a result. You can read more here [https://stackoverflow.com/questions/58866796/understanding-the-react-hooks-exhaustive-deps-lint-rule]. I hope that clarifies. – JeannotMn Sep 11 '21 at 16:39
2

This one worked for me.

Just add this comment at the last line of useEffect:

//eslint-disable-next-line

useEffect(() => {
  getUpperGroups();
  setContentData(contentGroupData);
  //eslint-disable-next-line
}, [contentGroupData]);
0

Probably I would try to move the definition of getUpperGroups into useEffect. Also you can use .map() and the previous state of your groups state.

Try as the following:

useEffect(() => {
  const getUpperGroups = () => {
     setUpperGroups(prevUpperGroups => contentGroupData.map((content) => ({
        ...prevUpperGroups,
        [content.id]: content.title
     })))
  }

  getUpperGroups();
  setContentData(contentGroupData);
}, [contentGroupData]);
norbitrial
  • 14,716
  • 7
  • 32
  • 59