我试图用react钩子(Hook)构建一个redux进程,下面的代码是我想用getUsers(redux action)调用模拟一个ComponentDidMount函数,这是一个获取数据的http请求。

第一个版本是这样的

const { state, actions } = useContext(StoreContext);
const { getUsers } = actions;

useEffect(() => {
  getUsers();  // React Hook useEffect has a missing dependency: 'getUsers'.
}, []);

但我收到了警告:“React Hook useEffect具有缺少的依赖项:'getUsers'。要么包含它,要么删除依赖项数组”在useEffect中,

然后我将getUsers添加到依赖项数组,但是在那里出现无限循环
useEffect(() => {
  getUsers();
}, [getUsers])

现在,我通过使用useRef找到了解决方案
const fetchData = useRef(getUsers);

useEffect(() => {
  fetchData.current();
}, []);

不确定这是否是正确的方法,但是确实解决了棉绒和无限循环(暂时吗?)

我的问题是:
在第二版代码中,到底是什么导致了无限循环?每次渲染后,依赖数组中的getUsers是否会发生变化?

最佳答案

您的函数具有依赖关系,React认为不列出依赖关系是不安全的。说您的功能取决于名为users的属性。在Dependencies数组中明确列出隐式依赖项将不起作用:

useEffect(() => {
  getUsers();
}, [users]); // won't work

但是,React says that the recommended way to fix this会将函数移到useEffect()函数内部。这样,警告不会说它缺少getUsers依赖项,而是getUsers依赖的一个或多个依赖项。
function Example({ users }) {

  useEffect(() => {
    // we moved getUsers inside useEffect
    function getUsers() {
      console.log(users);
    }
    getUsers();
  }, []); // users dependency missing
}

因此,您可以指定users依赖项:
useEffect(() => {
    function getUsers() {
      console.log(users);
    }
    getUsers();
  }, [users]); // OK

但是,您是从props获得该功能的,而组件中未定义该功能。

那该怎么办呢?解决您的问题的方法是memoize您的函数。



您无法在组件中记住它,因为会出现相同的警告:
const memoizedGetUsers = useCallback(
  () => {
    getUsers();
  },
  [], // same warning, missing the getUsers dependency
);

解决方案是在定义getUsers的位置记住它,然后您将能够列出依赖项:
// wrap getUsers inside useCallback
const getUsers = useCallback(
  () => {
    //getUsers' implementation using users
    console.log(users);
  },
  [users], // OK
);


在您的组件中,您将能够执行以下操作:
const { getUsers } = actions; // the memoized version

useEffect(() => {
    getUsers();
  }, [getUsers]); // it is now safe to set getUsers as a dependency


至于为什么存在无限循环以及useRef起作用的原因。我猜想您的函数会导致重新渲染,并且在每次迭代中,都会重新创建getUsers,最终导致一个无限循环。 useRef返回一个对象{ current: ... },而使用useRef和自己创建该对象{ current: ... }之间的区别是useRef返回相同的对象,而不创建另一个对象。因此,您可能使用了相同的功能。

关于reactjs - 关于使用中的无限循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59235461/

10-09 21:14