Javascript 反应效果挂钩清理

Javascript 反应效果挂钩清理,javascript,reactjs,api,react-hooks,use-effect,Javascript,Reactjs,Api,React Hooks,Use Effect,我正试图了解react Useffect cleanup究竟是如何使用的以及用于什么目的。你能帮我通过添加清理来修复我的代码吗 据我所知,它用于API调用以关闭订阅。仍然无法澄清为什么使用它以及具体使用方式 useEffect(() => { async function onLoad() { try { const examSessions = await loadSess

我正试图了解react Useffect cleanup究竟是如何使用的以及用于什么目的。你能帮我通过添加清理来修复我的代码吗

据我所知,它用于API调用以关闭订阅。仍然无法澄清为什么使用它以及具体使用方式

useEffect(() => {
        async function onLoad() {
        
            try {
              
              const examSessions = await loadSessions(id);
              setSessions(examSessions);
              console.log(`examSession`,examSessions)
            } catch (e) {
            //   onError(e);
                console.log(e)
            }
        
            setIsLoading(false);
        }


        onLoad()
    }, [id])



    function loadSessions(id) {
        const result = API.get("vce", `/session/${id}`)
        return result
    }


这里不需要使用清理钩。你没有订阅任何东西。当您在useEffect中订阅了某个内容并且没有取消订阅组件销毁时,此订阅将继续侦听远程源、设备内存和用户数据

要测试它,您只需将一个单击侦听器附加到一个按钮上,挂载/卸载一个组件(无需页面刷新),然后在chrome开发工具中查看订阅/侦听器列表的增长情况

编辑: 试试这个


如果没有清理,即使组件已卸载,效果也将永远继续执行它们正在执行的操作

这对于可能负责设置网络连接(如Web套接字连接)或使用
fetch
请求数据的复杂组件非常重要。如果您没有取消或关闭这些资源,这些资源将仍然处于打开状态,并且可能会发送信号

考虑下面的例子,在这里我们可以切换一个弹出的
Foo
组件。注释掉清理后,我们仍然可以看到“滴答声”,即使它已卸载,因为我们没有花时间清理间隔

事实上,如果重新打开
Foo
,您将在控制台中看到更多的“滴答声”,因为现在有2个以上的间隔在滴答作响。想象一下,如果这是一个Web套接字,我们每次重新安装时都会安排一个新的心跳节拍;服务器会对我们的应用程序感到非常愤怒

const{
useState,
使用效果,
createElement
}=反应;
常数{
提供
}=反应性;
常量Foo=()=>{
const[t,setT]=useState(0);
useffect(()=>{
常量间隔=设置间隔(()=>{
控制台日志(“勾选”);
setT(电流=>电流+1);
}, 1000);
//如果没有以下内容,您将永远看到“勾号”,因为它没有被清理
//return()=>clearInterval(interval);
}, []);
返回createElement(“div”,{},t);
};
常量应用=()=>{
const[should,setShould]=useState(true);
返回createElement(“div”),null,
createElement(“按钮”{
onClick:()=>setShould(curroshould=>!curroshould)
},“切换”),
是否应?createElement(Foo):null
);
};
渲染(
createElement(应用程序),
document.getElementById('app')
);


我怀疑,有人可能会比我更全面地解释这一点。如果有一些特定的细节您没有抓住,您最好问一个小问题。在这种代码情况下,我如何创建和清理订阅?:)我将辩护地尝试这一点,因为我的应用程序正在给我奇怪的错误消息的内存泄漏,我显然不明白。。。很可能是因为
setIsLoading(false)的缘故,谢谢你的建议由于等待api调用,它有可能在组件销毁后(尝试)运行。在这种情况下…我编辑了我的答案。这很好。我会测试一下。我明白你的意思,我明白你在这里的意思。需要一些时间来消化,但这真的很好
useEffect(() => {
        let unmounted = false;
        async function onLoad() {
        
            try {
              
              const examSessions = await loadSessions(id);
              setSessions(examSessions);
              console.log(`examSession`,examSessions)
            } catch (e) {
            //   onError(e);
                console.log(e)
            }
        
            if(!unmounted)setIsLoading(false);
        }


        onLoad()
        return ()=> unmounted = true;
    }, [id])