我试图了解新的React hooks API(目前我正在使用React 16.8.x
)。
我发现useEffect()
钩使得当用户执行导致不再显示组件的操作时,很容易丢弃服务器调用的结果,如(A)< / strong>:
useEffect(()=>{
let mounted = true;
setInvocation("processing");
MuiServiceApi.instance.
invokeProcessingMethod(details.endpoint, parsedPayload).
then(result=> mounted && setInvocation(result)).
catch(e=> setInvocation({message: "while updating DB", problem: e}));
return ()=>{mounted = false};
}, []);
但是,根据(B):
,当我从常规表单事件中进行呼叫时如何实现类似的行为:<form onSubmit={()=>{
setInvocation("processing");
MuiServiceApi.instance.
invokeProcessingMethod(details.endpoint, parsedPayload).
then(result=> setInvocation(result)).
catch(e=> setInvocation({message: "while updating DB", problem: e}));
}}>
如果用户在首次显示组件时正在执行调用时将其关闭(即(A)逻辑),则结果将被彻底丢弃。
如果用户在处理过程中关闭了组件,则在单击实际的提交按钮((B)逻辑)后,将出现控制台警告,例如:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
这并不是什么大不了的事情-实际上,在预钩class
API下,我从来没有理会丢弃未安装组件的结果,因为这太麻烦了。
但是此练习的重点是学习Hooks
API,所以我想知道如何为onSubmit
处理程序执行此操作。
我尝试用mounted
定义useState()
,但是我看不到它的工作方式,
const [mounted, setMounted] = React.useState(false);
useEffect(()=>{
setMounted(true);
setInvocation("processing");
MuiServiceApi.instance.
invokeProcessingMethod(details.endpoint, parsedPayload).
then(result=> {
if( mounted ){
console.log("result used");
setInvocation(result);
}
else {
console.log("result ignored because dismounted");
}
}).
catch(e=> setInvocation({message: "while updating DB", problem: e}));
return ()=>{
console.log("dismounted");
setMounted(false)
};
}, []);
我现在回想起来,它是行不通的,因为mounted
的{{1}}值是由闭包捕获的;因此false
处理程序将永远不会看到then
。
应该在这里使用“减少器”或“回调”吗?该文档在“基本”钩子之后变得非常模糊,因此我不确定是否应该这样做。
要重新陈述问题:应如何重构以下组件,以使mounted == true
then()
内的form
处理程序不会导致有关更新状态的警告(如果该组件已经存在)被卸载?
下面的完整组件(在onSubmit
中)
Typescript
答案 0 :(得分:0)
一种解决方法是通过React useRef API将mounted
从变量更改为引用。
使用const mounted = React.useRef(false)
声明引用,然后在以前的代码使用变量的任何地方使用mounted.current
。
始终通过Ref
访问current
值意味着该组件的效果和事件处理程序都绑定到Ref
所指向的单个“当前”值,而不是呈现组件时变量的副本。