const SideAd = () => {
const [sideAd, setSideAd] = useState([])
useEffect(() => {
query()
}, [])
const query = async () => {
const res = await getSideAd()
Array.isArray(res) && setSideAd(res)
}
return (
<div className="sideAdComponent">
</div>
)
}
我只想在安装时发出请求,然后设置一个新状态。但是相反,我遇到了错误react hook cant perform setstate in an unmounted component
答案 0 :(得分:3)
您可以在这里做两件事。
首先是使用清理功能(useEffect
的回调中的返回值)来对抗useEffect
中的比赛条件
const SideAd = () => {
const [sideAd, setSideAd] = useState([])
useEffect(() => {
const isMounted = true;
getSideAd().then(res => Array.isArray && isMounted && setSideAd(res))
return () => {isMounted = false;}
}, [])
return (
<div className="sideAdComponent">
</div>
)
}
检查nice article at hackernoon以获得更详细的说明。在我看来,这种方法比取消请求更好(因为它不需要您修改请求者的代码)。
另一件事:也许最好在响应出现之前检查一下为什么卸载组件的原因。可能有正当的理由(例如,您已经离开,而尚未收到回应)。
但是也可能有一些HOC声明了内联组件构造函数,并导致重新创建所有子树而不是进行更新。因此值得花一些时间进行调查-因为可能存在尚未发现的隐藏错误(example)。
答案 1 :(得分:0)
您可以编写一个名为useIsMounted的自定义钩子:
const useIsMounted = () => {
const isMounted = useRef(false);
useEffect(() => {
isMounted.current = true;
return () => isMounted.current = false;
}, []);
return isMounted;
};
const SideAd = () => {
const [sideAd, setSideAd] = useState([]);
useEffect(() => {
query();
}, []);
const mounted = useIsMounted();
const query = async () => {
const res = await getSideAd();
Array.isArray(res) && mounted.current && setSideAd(res);
};
return <div className="sideAdComponent"></div>;
};