Search code examples
javascriptreactjsfetchuse-effect

Conditionally render useEffect fetch React


Making a video game clip posting app. I have a controller on the backend that will give me the clips in order of most commented on clips to least. I would like to switch between having the data ordered normally, to from most to least comments by using a select tag (later I will add more filters). I was hoping I could conditionally render both of the fetches based on a state from the select tag onChange, but I got an error.

 Line 18:5:  React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render  react-hooks/rules-of-hooks
  Line 24:5:  React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render  react-hooks/rules-of-hooks

this is my code. Note that I was just testing it with a boolean.

 const boolean = true;
  if (boolean == true) {
    useEffect(() => {
      fetch("/clips")
        .then((r) => r.json())
        .then((data) => setClipData(data));
    }, []);
  } else {
    useEffect(() => {
      fetch("/most_comments")
        .then((r) => r.json())
        .then((data) => setClipData(data));
    }, []);
  }

Solution

  • As the error says, you can't have useEffect called conditionally. Instead, call it a single time regardless, and inside that function, look to see whether you need to fetch the clips or the comments.

    useEffect(() => {
        if (boolean) {
            fetch("/clips")
                .then((r) => r.json())
                .then((data) => setClipData(data));
                // don't forget to .catch errors here
        } else {
            fetch("/most_comments")
                .then((r) => r.json())
                .then((data) => setClipData(data)); // did you mean to call setCommentsData or something here?
                // don't forget to .catch errors here
        }
    }, []);