1

Quick question, how do I fix the warning that I get when I try to use useEffect in my app. Here is my code:

 const userUrl = `${process.env.REACT_APP_API_URL}/${id}`;


const [newUser, setNewUser] = useState({
    name: "",
    email: "",
    status: "",
    gender: "",
  });

  useEffect(() => {
    if (id) {
      const getUser = async () => {
        try {
          const response = await axios.get(userUrl);
          const apiData = response.data.data;
          setNewUser({
            ...newUser,
            name: apiData.name,
            email: apiData.email,
            status: apiData.status,
            gender: apiData.gender,
          });
        } catch (err) {
          console.error(err);
        }
      };
      getUser();
    } else {
      setNewUser({
        ...newUser,
        status: "active",
        gender: "male",
      });
    }
  }, [userUrl, id]);

This is the full warning message: React Hook useEffect has a missing dependency: 'newUser'. Either include it or remove the dependency array. You can also do a functional update 'setNewUser(n => ...)' if you only need 'newUser' in the 'setNewUser' call

I tried adding the newUser inside the second parameter of the useEffect hook, but then I get the maximum depth error, so if anyone know how to fix this, I would gladly appreciate that.

2
  • 2
    try using the callback approach setNewUser(prev => ({...prev, YOUR_UPDATES})) Commented Oct 20, 2021 at 16:24
  • It worked, thank you Commented Oct 20, 2021 at 16:33

1 Answer 1

2

Issue

The issue here is that you are referencing the newUser state within the useEffect callback, thus making it a dependency. But you can't unconditionally update any value that is a dependency as this leads to the render looping you see when you added newUser state as a dependency.

Solution

You should use a functional state update on the state updater so you can remove the outer newUser dependency. The functional update enqueues a state update and passes the previous state value to the callback that can be used to compute the next state value.

useEffect(() => {
  if (id) {
    const getUser = async () => {
      try {
        const response = await axios.get(userUrl);
        const { email, gender, name, status } = response.data.data;
        setNewUser(newUser => ({ // <-- previous state
          ...newUser,            // <-- shallow merge
          name,
          email,
          status,
          gender,
        }));
      } catch (err) {
        console.error(err);
      }
    };
    getUser();
  } else {
    setNewUser(newUser => ({     // <-- previous state
      ...newUser,                // <-- shallow merge
      status: "active",
      gender: "male",
    }));
  }
}, [userUrl, id]);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.