简体   繁体   English

我如何正确使用 useEffect 进行异步获取调用和反应? 反应钩子/详尽的deps

[英]How do i properly use useEffect for a async fetch call with react? react-hooks/exhaustive-deps

Hi i'm facing a problem with the useEffect hook in React.嗨,我在 React 中遇到了useEffect钩子的问题。 The code below works like it should but es-lint suggests that i need to provide dependencies in the dependency array from the useEffect .下面的代码可以正常工作,但 es-lint 建议我需要在useEffect的依赖数组中提供依赖项。

Working code with // eslint-disable-next-line react-hooks/exhaustive-deps使用// eslint-disable-next-line react-hooks/exhaustive-deps工作代码

export default function UsersList() {
   const [users, setUsers] = useState<User[]>([]);
   
   const { setError } = useContext(errorContext);
   const { isLoading, setIsLoading } = useContext(globalContext);
   
   useEffect(() => {
       if (users.length < 1) {
         fetchUsers();
       }
       // eslint-disable-next-line react-hooks/exhaustive-deps
     }, []);

     async function fetchUsers () {
       try {
         setIsLoading(true);
         const fetchedUsers = await api.getUsers();
         setUsers(fetchedUsers);
       } catch (error) {
         setError(error);
       } finally {
         setIsLoading(false);
       }
     }
}

Infinite looping code无限循环代码

i tried to write it like this the code triggers a infinite loop.. (because the states get constantly changed inside the function and triggers the useEffect every time because of the declared dependencies)我试着这样写代码触发了一个无限循环..(因为状态在 function 内不断变化,并且由于声明的依赖关系每次都会触发useEffect

 useEffect(() => {
    async function fetchUsers () {
      try {
        setIsLoading(true);
        const fetchedUsers = await api.getUsers();
        setUsers(fetchedUsers);
      } catch (error) {
        setError(error);
      } finally {
        setIsLoading(false);
      }
    }

    if (users.length < 1) {
      fetchUsers();
    }
  }, [setIsLoading, setError, users]);

i also tried putting the fetchUsers() inside the dependencies array but this had no effect.我还尝试将fetchUsers()放在依赖项数组中,但这没有效果。

How do i properly set up a async call when the component mounts without having to use // eslint-disable-next-line react-hooks/exhaustive-deps ?我如何在组件安装时正确设置异步调用而不必使用// eslint-disable-next-line react-hooks/exhaustive-deps

Your fetchUsers function is recreating itself with every render triggering use effect.您的fetchUsers function 正在通过每个渲染触发使用效果重新创建自己。 You have to keep its reference the same across renders by wrapping it with useCallback , see https://reactjs.org/docs/hooks-reference.html#usecallback您必须通过使用useCallback将其包装在渲染中保持其引用相同,请参阅https://reactjs.org/docs/hooks-reference.html#usecallback

Furthermore, to ensure that we call this useEffect only once (when the first render occurs) we can use useRef to store a boolean value which will prevent useEffect from infinite loop此外,为了确保我们只调用这个 useEffect 一次(当第一次渲染发生时),我们可以使用 useRef 来存储一个 boolean 值,这将防止 useEffect 无限循环

export default function UsersList() {
  const [users, setUsers] = useState<User[]>([]);
  
  const { setError } = useContext(errorContext);
  const { isLoading, setIsLoading } = useContext(globalContext);

  const fetchUsers = useCallback(async function () {
    try {
      setIsLoading(true);
      const fetchedUsers = await api.getUsers();
      setUsers(fetchedUsers);
    } catch (error) {
      setError(error);
    } finally {
      setIsLoading(false);
    }
  }, [setIsLoading, setUsers, setError]);

  // Added a ref here to ensure that we call this function only once in initial render
  // If you need to refetch the users on error, just call fetchUsers
  const isFetchedRef = useRef(false);
  useEffect(() => {
    if (!isFetchedRef.current) {
      isFetchedRef.current = true;
      fetchUsers();
    }
  }, [isLoading, fetchUsers]);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 反应 useEffect 带有警告的钩子 react-hooks/exhaustive-deps - React useEffect hook with warning react-hooks/exhaustive-deps useEffect 和 &#39;react-hooks/exhaustive-deps&#39; linting - useEffect and 'react-hooks/exhaustive-deps' linting 如何解决`react-hooks/exhaustive-deps`的`React Hook useEffect缺少依赖`? - How to solve `React Hook useEffect has a missing dependency` of `react-hooks/exhaustive-deps`? ESLint 希望 setSate 作为 useEffect 的依赖,但这会导致无限循环(react-hooks/exhaustive-deps) - ESLint wants setSate as a dependency for useEffect but this causes an infinite loop (react-hooks/exhaustive-deps) 带有自定义 IntersectionObserver 钩子的 react-hooks/exhaustive-deps 警告 - react-hooks/exhaustive-deps warning with custom IntersectionObserver hook 未找到规则“re​​act-hooks/exhaustive-deps”的定义 - Definition for rule 'react-hooks/exhaustive-deps' was not found 如何在React中使用钩子实现componentDidMount以使其符合EsLint规则“ react-hooks / exhaustive-deps”:“ warn”? - How to implement componentDidMount with hooks in React to be in line with the EsLint rule “react-hooks/exhaustive-deps”: “warn”? React Hook useEffect 缺少依赖项。 包括它们或删除依赖数组 react-hooks/exhaustive-deps - React Hook useEffect has missing dependencies. Either include them or remove the dependency array react-hooks/exhaustive-deps React Hook useEffect 缺少依赖项:&#39;formValues&#39;。 包括它或删除依赖数组 react-hooks/exhaustive-deps - React Hook useEffect has a missing dependency: 'formValues'. Either include it or remove the dependency array react-hooks/exhaustive-deps React Hook useEffect 缺少依赖项:“roomID”和“sotreId”。 要么包含它们,要么删除依赖数组 react-hooks/exhaustive-deps - React Hook useEffect has missing dependencies: 'roomID 'and 'sotreId'. Either include them or remove the dependency array react-hooks/exhaustive-deps
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM