useEffect道具回调函数导致无限循环 [英] useEffect props callback function causing infinite loop

查看:1059
本文介绍了useEffect道具回调函数导致无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a problem very similar to this - How do I fix missing dependency in React Hook useEffect.

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

There is one key difference - I am passing a fetch function to a child component to be called from useEffect, so I can't simply move the function into the body of the effect. The fetch function is re-created every render and causes an infinite loop. I have other local component state that I want to cause the effect to fire.

我基本上有一个Container组件和一个Presentational组件。 MyPage是MyGrid的父级,并设置所有redux状态:

I basically have a Container Component and a Presentational component. MyPage is the parent of MyGrid and sets up all the redux state:

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可以更改,并且应使效果触发。

In "MyGrid" "skip" and "sorts" can change, and should make the effect fire.


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

"fetchItems" is re-created everytime and causes an infinite loop. This is my problem.

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

Now, the eslint react-hooks/exhaustive-deps rule is making me put fetchItems in the dependency list. I have prettier setup to autofix on save which makes it worse.

我知道Container / Presentational模式在使用钩子时过时了,但是对我的情况很有用-我可能允许动态地将MyGrid换成MyList,并且不想重复每个子组件中的所有redux内容。

I know the Container/Presentational pattern is out of style with hooks, but it works good for my situation - I may allow swapping out MyGrid for MyList dynamically and don't want to repeat all the redux stuff in each child component.

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

I tried to useCallback and useMemo, but eslint just makes me put all the same dependencies in it's dependency array parameter.

除了禁用eslint规则

Is there a way other than disabling the eslint rule

// eslint-disable-next-line react-hooks/exhaustive-deps

要完成这项工作?

推荐答案

有两种方法可以使它起作用。

There are two ways, you can make it work.

首先,将 useCallback 用于fetchItem之类的

Firstly, using useCallback for fetchItem like

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

第二次使用调度直接在子组件中

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]);

这篇关于useEffect道具回调函数导致无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆