[英]useEffect props callback function causing infinite loop
I have a problem very similar to this - How do I fix missing dependency in React Hook useEffect . 我有一个与此非常相似的问题 - 如何修复React Hook useEffect中缺少的依赖项 。
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. 有一个关键区别 - 我将一个fetch函数传递给要从useEffect调用的子组件,所以我不能简单地将该函数移动到效果体中。 The fetch function is re-created every render and causes an infinite loop.
每次渲染都会重新创建fetch函数,并导致无限循环。 I have other local component state that I want to cause the effect to fire.
我有其他本地组件状态,我想导致效果触发。
I basically have a Container Component and a Presentational component. 我基本上有一个容器组件和一个演示组件。 MyPage is the parent of MyGrid and sets up all the redux state:
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]);
In "MyGrid" "skip" and "sorts" can change, and should make the effect fire. 在“MyGrid”中,“跳过”和“排序”可以改变,并且应该使效果起火。
"fetchItems" is re-created everytime and causes an infinite loop.
每次都会重新创建“fetchItems”并导致无限循环。 This is my problem.
这是我的问题。
Now, the eslint react-hooks/exhaustive-deps rule is making me put fetchItems in the dependency list. 现在,eslint react-hooks / exhaustive-deps规则让我把fetchItem放在依赖列表中。 I have prettier setup to autofix on save which makes it worse.
我有更漂亮的设置自动修复保存,这使它变得更糟。
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. 我知道容器/演示模式与钩子不合适,但它适用于我的情况 - 我可能允许动态地交换MyGrid for MyList并且不想重复每个子组件中的所有redux内容。
I tried to useCallback and useMemo , but eslint just makes me put all the same dependencies in it's dependency array parameter. 我尝试使用Callback和useMemo ,但是eslint只是让我把所有相同的依赖项放在它的依赖数组参数中。
Is there a way other than disabling the eslint rule 除了禁用eslint规则之外还有其他方法吗?
// eslint-disable-next-line react-hooks/exhaustive-deps
to make this work? 使这项工作?
There are two ways, you can make it work. 有两种方法,你可以使它工作。
Firstly , using useCallback
for fetchItem like 首先 ,将
useCallback
用于fetchItem之类的
const fetchItems = useCallback(opts => dispatch(actions.fetchItems(opts)), [dispatch, actions]);
Secondly using dispatch
directly in child component 其次直接在子组件中使用
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]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.