useEffect道具回调函数导致无限循环 [英] useEffect props callback function causing infinite loop
问题描述
我有一个与此非常相似的问题-我该如何解决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屋!