useEffect props 回调函数导致无限循环

use*_*757 7 reactjs eslint react-redux create-react-app react-hooks

我有一个与此非常相似的问题 -如何修复 React Hook useEffect 中缺少的依赖项

有一个关键区别 - 我将一个 fetch 函数传递给要从useEffect调用的子组件,所以我不能简单地将该函数移动到效果的主体中。每次渲染都会重新创建 fetch 函数并导致无限循环。我还有其他本地组件状态想要触发效果。

我基本上有一个容器组件和一个演示组件。MyPage 是 MyGrid 的父级并设置所有 redux 状态:

const MyPage = () => {

  const dispatch = useDispatch();
  const items= useSelector(selectors.getItems);
  const fetching = useSelector(selectors.getFetching);
  const fetchItems = opts => dispatch(actions.fetchItems(opts));

  return (
    <>
      {fetching && <div>Loading...</div>}
      <h1>Items</h1>
      <MyGrid
        items={items}
        fetchItems={fetchItems}
        fetching={fetching}
      />
    </>
  );

}

const MyGrid = ({ fetchItems, items, fetching }) => {

  const [skip, setSkip] = useState(0);
  const take = 100;
  const [sorts, setSorts] = useState([]);

  // when query opts change, get data
  useEffect(() => {

    const options = { skip, take };
    const sortString = getSortString(sorts);
    if (sortString) options['sort'] = sortString;
    fetchItems(options);

  }, [fetchItems, skip, sorts]);
Run Code Online (Sandbox Code Playgroud)

在“MyGrid”中“skip”和“sorts”可以改变,并且应该使效果火起来。

每次都重新创建“fetchItems”并导致无限循环。这是我的问题。

现在,eslint react-hooks/exhaustive-deps 规则让我将 fetchItems 放在依赖项列表中。我有更漂亮的设置来自动修复保存,这让情况变得更糟。

我知道 Container/Presentational 模式不适合使用钩子,但它对我的情况很有用 - 我可以允许动态地将 MyGrid 换成 MyList 并且不想在每个子组件中重复所有 redux 的东西。

我试图useCallbackuseMemo,但 eslint 只是让我将所有相同的依赖项放在它的依赖项数组参数中。

除了禁用 eslint 规则之外还有其他方法吗

// eslint-disable-next-line react-hooks/exhaustive-deps
Run Code Online (Sandbox Code Playgroud)

使这项工作?

Shu*_*tri 3

有两种方法,你可以让它发挥作用。

首先,用于useCallbackfetchItem 像

const fetchItems = useCallback(opts => dispatch(actions.fetchItems(opts)), [dispatch, actions]);
Run Code Online (Sandbox Code Playgroud)

其次dispatch直接在子组件中使用

const dispatch = useDispatch();
 useEffect(() => {

    const options = { skip, take };
    const sortString = getSortString(sorts);
    if (sortString) options['sort'] = sortString;
    dispatch(actions.fetchItems(options));

  }, [dispatch, actions, skip, sorts]);
Run Code Online (Sandbox Code Playgroud)

  • 为什么必须将调度函数作为 useEffect 挂钩的第二个参数传递? (2认同)