首页 > 解决方案 > 如何在数组依赖中正确使用 useEffect 挂钩。我从 redux 商店传递了状态,但我的组件仍然无限渲染

问题描述

我正在使用 useEffect 钩子并使用函数getStoreUsers通过 fetch 调用获取用户数据列表,该函数在响应中调度操作并将shopUsers(这是一个数组)存储在 redux 存储中。

在数组依赖中,我正在写[shopUsers]。我不知道为什么它会导致无限渲染。

这是我如何使用 useEffect 钩子:

useEffect(() => {
    const { getStoreUsers, shopUsers } = props;
    setLoading(true);
    getStoreUsers().then(() => {
      setLoading(false);
    }).catch(() => {
      setLoading(false);
    });
  }, [shopUsers]);

我只想在 shopUsers 数组中的数据发生变化时重新渲染组件。

如果我在数组依赖项中编写 shopUsers.length 。它停止重新渲染。

但是,假设我有一个页面,当用户单击 userList 并在下一页更新用户数据时会打开该页面。更新后,我希望用户返回到以前未卸载的相同组件。因此,在这种情况下,数组长度保持不变,但数组索引中的数据会更新。所以 shopUsers.length 在这种情况下不起作用。

标签: javascriptreactjsreact-nativereduxreact-hooks

解决方案


您可以制作自定义挂钩来做您想做的事:

在此示例中,我们替换数组中的最后一个元素,并在控制台中查看输出。

import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
import { isEqual } from "lodash";

const usePrevious = value => {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
};

const App = () => {
  const [arr, setArr] = useState([2, 4, 5]);
  const prevArr = usePrevious(arr);

  useEffect(() => {
    if (!isEqual(arr, prevArr)) {
      console.log(`array changed from ${prevArr} to ${arr}`);
    } 
  }, [prevArr]);

  const change = () => {
    const temp = [...arr];
    temp.pop();
    temp.push(6);
    setArr(temp);
  };

  return (
      <button onClick={change}>change last array element</button>
  )
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

现场示例在这里


推荐阅读