0

When implementing the hook code from here

https://blog.logrocket.com/patterns-for-data-fetching-in-react-981ced7e5c56/

I get the following warning, what does this actually mean?

./src/components/Users.tsx Line 20:6: React Hook useEffect has a missing dependency: 'data.users'. Either include it or remove the dependency array. You can also replace multiple useState variables with useReducer if 'setData' needs the current value of 'data.users' react-hooks/exhaustive-deps

code:

import React, { useEffect, useState } from "react";
import axios from "axios";
const USER_SERVICE_URL = "https://jsonplaceholder.typicode.com/users";

export function List() {
  const [data, setData] = useState({ users: [], isFetching: false });

  useEffect(() => {
    const fetchUsers = async () => {
      try {
        setData({ users: data.users, isFetching: true });
        const response = await axios.get(USER_SERVICE_URL);
        setData({ users: response.data, isFetching: false });
      } catch (e) {
        console.log(e);
        setData({ users: data.users, isFetching: false });
      }
    };
    fetchUsers();
  }, []);

  console.log(data)
Terry
  • 1,621
  • 4
  • 25
  • 45
  • Does this answer your question? [How to fix missing dependency warning when using useEffect React Hook?](https://stackoverflow.com/questions/55840294/how-to-fix-missing-dependency-warning-when-using-useeffect-react-hook) – Ardenne May 11 '20 at 15:05
  • No, the function is already declared inside use effect, so according to that post I should'nt be seeing this issue. – Terry May 11 '20 at 16:38

1 Answers1

3

It means that since you use data.users in the code inside the useEffect block, and you've define an empty dependencies array, data.users might be stale.

To solve that problem use the setState updater function. Which allows you to use the previous state, while creating the new one:

    setData(data => ({ users: data.users, isFetching: true }));

Or

    setData(data => ({ users: data.users, isFetching: false }));

Another options is to create a simple reducer, that will work like setState(), but will override changed items, and not the entire state:

const reducer = (state, payload) => ({ ...state, ...payload });

export function List() {
  const [data, setData] = useReducer(reducer, { users: [], isFetching: false });

  useEffect(() => {
    const fetchUsers = async () => {
      try {
        setData({ isFetching: true });
        const response = await axios.get(USER_SERVICE_URL);
        setData({ users: response.data, isFetching: false });
      } catch (e) {
        console.log(e);
        setData({ isFetching: false });
      }
    };
    fetchUsers();
  }, []);

  console.log(data)
Ori Drori
  • 183,571
  • 29
  • 224
  • 209