我正在尝试将“动作分派”传递给子组件,并陷入无限渲染循环中,这是我所拥有的一个简单示例:
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中进行更改,并且希望在更改时重新感染数据。在初始渲染(和无限渲染)时,我可以看到它永远不会改变。 Per the docs,对我来说还不错;我在做什么错了?
答案 0 :(得分:0)
正如@azundo在评论中指出的,这里的问题是useCallback
中缺少依赖项。
如果未传递任何依赖项,则useCallback
将在每个渲染器中创建该函数的新引用。当函数传递给ChildComponent
时,它实际上是一个新的函数引用。因此,每个渲染useEffect(() => { fetchData(arg); }, [fetchData, arg]);
都会收到一个新的fetchData
函数并运行它。
要解决此问题,只需将依赖项传递给useCallback
。在这种情况下,如果useCallback
中的函数在第一次渲染后不会改变(我假设fetchThings
或dispatch
都没有改变,如果他们改变了,则传递它们),我们可以传递一个空数组。
const fetchData = useCallback(arg => { dispatch(fetchThings(arg)); }, []);
也就是说,如果没有记下ChildComponent
,我不确定您会从useCallback
那里受益,因为无论如何,每次父母都会这样做。