react-redux useCallback infinite render



我正在尝试将"动作调度"传递给子组件,并陷入无限渲染循环,这是我拥有的简单示例:

const ParentComponent = () => {
const dispatch = useDispatch();
const error = useSelector(getError);
const fetching = useSelector(getFetching);
const things = useSelector(getThings);
const fetchData = useCallback(arg => { dispatch(fetchThings(arg)); });
return (
{error && <span>{error}</span>}
{fetching &&< <span>Fetching...</span>}
{!fetching && (
<ChildComponent fetchData={fetchData} data={things} />
})
);
};
const ChildComponent = ({fetchData, data, ...otherStuff}) => {
const [arg, setArg] = useState();
useEffect(() => { fetchData(arg); }, [fetchData, arg]);
return (
... MARKUP ...
);
};
export default ChildComponent;

"arg"是子变量中的一个变量,我可以在 UI 中更改,我希望数据在更改时得到反映。在初始渲染(和无限渲染(上,我可以看到它永远不会改变。 根据文档,对我来说看起来还可以;我做错了什么?

正如@azundo在评论中指出的那样,这里的问题是useCallback缺乏依赖关系。

如果未传递依赖项,useCallback将在每次渲染中创建函数的新引用。当函数传递给ChildComponent时,它实际上是一个新的函数引用。因此,每个渲染useEffect(() => { fetchData(arg); }, [fetchData, arg]);都会收到一个新的fetchData函数并运行它。

要解决它,只需将依赖项传递给useCallback。在这种情况下,如果useCallback中的函数在第一次渲染后不会更改(我假设既不更改fetchThings也不dispatch更改,如果它们更改,请传递它们(,我们可以传递一个空数组。

const fetchData = useCallback(arg => { dispatch(fetchThings(arg)); }, []);

也就是说,如果没有记住ChildComponent,我不确定您是否获得了useCallback的好处,因为无论如何,每次父母这样做时,它都会呈现。

相关内容

  • 没有找到相关文章

最新更新