0
votes

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)
1
No, the function is already declared inside use effect, so according to that post I should'nt be seeing this issue.Terry

1 Answers

2
votes

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)