【问题标题】:useEffect props callback function causing infinite loopuseEffect props 回调函数导致无限循环
【发布时间】:2019-11-01 14:48:54
【问题描述】:

我有一个与此非常相似的问题 - How do I fix missing dependency in 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]);

在“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

要完成这项工作吗?

【问题讨论】:

    标签: reactjs react-redux eslint create-react-app react-hooks


    【解决方案1】:

    有两种方法,你可以让它工作。

    首先,使用useCallback 获取类似物品

    const fetchItems = useCallback(opts => dispatch(actions.fetchItems(opts)), [dispatch, actions]);
    

    其次直接在子组件中使用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]);
    

    【讨论】:

    • 为什么 dispatch 函数必须作为 useEffect 钩子的第二个参数传递?
    • @PeeJee 它没有,但我的 eslint/prettier 为我把它放在那里!
    • useDispatch 到底是什么?尝试调用 useDispatch 导致未定义。
    • @Tyk useDispatch 是 react-redux 暴露的函数。
    • 啊,我没有意识到这是 react-redux 特有的。我试图更多地了解 useEffect() 的一般工作原理。
    猜你喜欢
    • 2020-08-27
    • 2020-11-16
    • 2021-06-12
    • 2021-11-01
    • 2021-09-27
    相关资源
    最近更新 更多