gpt4 book ai didi

reactjs - 在 useEffect 中调用事件处理程序 Prop 的好模式是什么?

转载 作者:行者123 更新时间:2023-12-04 15:02:39 27 4
gpt4 key购买 nike

让我们假设一个组件:

const Foo = ({id, onError}) => {
useEffect(() => {
subscribe(id).catch(error => onError(error));
return () => cleanup(id);
}, [id, onError]);

return <div>...</div>;
}

想法很简单——运行一个使用当前“id”订阅的效果。如果订阅失败,调用事件处理程序 onError 作为 prop 传递。

但是,要使其正常工作,传递的 onError 属性必须是引用稳定的。换句话说,如果我的组件的消费者尝试了以下操作,他们可能会遇到为每个渲染运行效果的问题:

const Parent = () => {
// handleError is recreated for each render, causing the effect to run each time
const handleError = error => {
console.log("error", error);
}

return <Foo id="test" onError={handleError} />
}

相反,他们需要做类似的事情:

const Parent = () => {
// handleError identity is stable
const handleError = useCallback(error => {
console.log("error", error);
},[]);

return <Foo id="test" onError={handleError} />
}

有效,但我有点不满意。 Foo 的使用者需要意识到 onError 必须是稳定的,除非您查看其底层实现,否则这并不是显而易见的事情。它打破了组件封装,消费者很容易在没有意识到的情况下遇到问题。

是否有更好的模式来管理可能在 useEffect 中调用的事件处理程序等 Prop ?

最佳答案

您需要从依赖项列表中删除 onError,但如果它发生变化仍会调用。为此,您可以使用 ref,并在每次渲染时通过 useEffect 更新它。

您还可以使用 optional chaining ?.避免调用 undefined 的函数。

const Foo = ({ id, onError }) => {
const onErrorRef = useRef();

useEffect(() => {
onErrorRef.current = onError;
});

useEffect(() => {
subscribe(id).catch(error => onErrorRef.current?.(error));
return () => cleanup(id);
}, [id]);

return <div>...</div>;
}

关于reactjs - 在 useEffect 中调用事件处理程序 Prop 的好模式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66699265/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com