媒介
周末尝试了一下React新的hooks功用,来封装一个组件,碰到一个bug,所以纪录一下历程!
报错以下:
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.in Notification
也许意义是组件已卸载了,但在卸载以后还实行了一个对组件更新的操纵,这是一个无效的操纵,但它示意应用程序中存在内存走漏。要修复,请作废useEffect
cleanup function.in Notification 中的一切定阅和异步使命
组件中心代码以下:
function Notification(props){
var timer = null;
const [visible, setVisible] = useState(false);
let {title,description,duration,theme,onClose,}= props;
let leave = (source='') => {
clearTimeout(timer);
setVisible(false);
console.log("注重这里是 leave要领里,timer的id:"+timer,"事宜的泉源:",source);
console.log("leave result:",timer);
onClose&&onClose();
}
let enter = () => {
setVisible(true);
if( duration > 0 ){
let timer = setTimeout(() => {
console.log(`auto carried out`,timer) //timer Number Id
leave(`Time to`);
}, duration*1000);
console.log(`enter要领里,timer的id:`,timer) //timer Number Id
}
}
useEffect(()=>{
enter();
},[])
return (
<div className={`${prefixCls}-notice`} style={{display:`${visible?'':'none'}`}}>
{!!theme&&<p className={`${prefixCls}-notice-icon`}><Svg iconId={`svg-${theme}`} /></p>}
<div className={`${prefixCls}-notice-content`}>
……//首席填坑官∙苏南的专栏 交换:912594095、民众号:honeyBadger8
</div>
<p className={`${prefixCls}-notice-colse`} title="封闭" onClick={()=>leave("手动点击的封闭")}><Svg/></p>
</div>
);
};
简朴剖析:
- 起首
useEffect
要领,是react新增的,它是componentDidMount
,componentDidUpdate
、componentWillUnmount
三个生命周期的合集, - 也就是之前的写法,上面三生命周期里会实行到的操纵,useEffect都邑去做;
enter、leave要领
- 很好明白,
进场
、进场
两函数, - 进场:加了个定时器,在N秒后实行
进场
即leave要领,这个逻辑是一般的, - 题目就出在手动实行
leave
,也就是onclick事宜上,
题目缘由:
- 实在就是在点击事宜的时刻,没有获取到 timer的id,致使了定时器没有清撤除;
!!看图措辞:
处理思绪:
- 当然是看官方文档,hooks对我来讲也是个新玩意,不会~
- 1、
useEffect
要领里return 一个要领,它是能够在组件卸载时实行的, - 2、消灭定时器它有本身的体式格局,
const intervalRef = useRef()
;指定赋值后能同步更新,之前的timer手动实行没有拿到timer所以没有清撤除;
参考链接:
中文,英文的没有找到
文档英文的也补一下吧
react github也有人提到这个题目,进修了
圆满处理:
function Notification(props){
var timer = null;
const [visible, setVisible] = useState(false);
let {title,description,duration,theme,onClose,}= props;
const intervalRef = useRef(null);
let leave = (source='') => {
clearTimeout(intervalRef.current);
setVisible(false);
console.log("leave result:",source,intervalRef);
onClose&&onClose();
}
let enter = () => {
setVisible(true);
if( duration > 0 ){
let id = setTimeout(() => {
console.log(`auto carried out`,intervalRef) //timer Number Id
leave(`Time to`);
}, duration*1000);//首席填坑官∙苏南的专栏 交换:912594095、民众号:honeyBadger8
intervalRef.current = id;
}
}
useEffect(()=>{
enter();
return ()=>clearTimeout(intervalRef.current);
},[])
return (
<div className={`${prefixCls}-notice`} style={{display:`${visible?'':'none'}`}}>
{!!theme&&<p className={`${prefixCls}-notice-icon`}><Svg iconId={`svg-${theme}`} /></p>}
<div className={`${prefixCls}-notice-content`}>
……//首席填坑官∙苏南的专栏 交换:912594095、民众号:honeyBadger8
</div>
<p className={`${prefixCls}-notice-colse`} title="封闭" onClick={()=>leave("手动点击的封闭")}><Svg/></p>
</div>
);
};
热点引荐
作者:
苏南 – 首席填坑官链接:
https://blog.csdn.net/weixin_…交换:912594095、民众号:
honeyBadger8
本文原创,著作权归作者一切。贸易转载请联络
@IT·平头哥同盟
取得受权,非贸易转载请说明原链接及出处。