我如何在反应中取消订阅
Posted
技术标签:
【中文标题】我如何在反应中取消订阅【英文标题】:how can I cancel subscriptions in react 【发布时间】:2021-03-03 22:41:44 【问题描述】:我的代码显示轮播时收到此警告。 警告:无法对未安装的组件执行 React 状态更新。这是一个空操作,但它表明您的应用程序中存在内存泄漏。要修复,请在 componentWillUnmount 方法中取消所有订阅和异步任务。
我尝试使用 componentWillUnmount 取消订阅,但警告仍然存在。下面是我的代码。
constructor(props)
super(props);
const idxStart = 0;
this.state =
current: idxStart,
prev: this.getPrevIndex(idxStart),
next: this.getNextIndex(idxStart),
Text: Text
;
// To disable autoplay, change to false
this.autoPlay = true;
getPrevIndex = (idx) =>
if (idx <= 0)
return pics.length - 1;
return idx - 1;
getNextIndex = (idx) =>
if (idx >= pics.length - 1)
return 0;
return idx + 1;
setIndexes = (idx, dir) =>
this.setState(
current: idx,
prev: this.getPrevIndex(idx),
next: this.getNextIndex(idx),
dir
);
transitionSlide = (direction) =>
if (this.moving) return;
// start animation
this.setState(
dir: direction,
move: true
);
this.moving = true;
//stop animation
setTimeout(() =>
this.setState(
move: false
);
if (direction === 'next')
this.setIndexes(this.getNextIndex(this.state.current), 'next');
else
this.setIndexes(this.getPrevIndex(this.state.current), 'prev');
this.moving = false;
, 500);
componentDidMount()
if (this.autoPlay)
setInterval(this.handleNext, 6000);
componentWillUnmount()
this.autoplay === false
clearInterval(setInterval(this.handleNext, 6000));
clearTimeout(setTimeout(() =>
this.setState(
move: false
);
if (direction === 'next')
this.setIndexes(this.getNextIndex(this.state.current), 'next');
else
this.setIndexes(this.getPrevIndex(this.state.current), 'prev');
, 500))
handlePrev = () =>
this.transitionSlide('prev');
handleNext = () =>
this.transitionSlide('next');
```
I have tried to fix this perhaps there is something I am not doing right.
【问题讨论】:
【参考方案1】:clearInterval(setInterval(this.handleNext, 6000));
安排一个新间隔计时器并立即取消它,让您的旧间隔计时器仍在运行。
你需要做的是记住你在componentDidMount
中从setInterval
获得的计时器句柄,可能是一个实例属性,并使用它:
componentDidMount()
if (this.autoPlay)
this.intervalHandle = setInterval(this.handleNext, 6000);
componentWillUnmount()
if (this.intervalHandle)
clearInterval(this.intervalHandle);
this.intervalHandle = 0; // Not strictly necessary, but I like to do
// this so I know looking at the handle whether
// I've cancelled it. (The value from
// `setInterval` will never be 0.)
// ...
【讨论】:
我更喜欢将null
用于不活动的间隔/计时器句柄,或者只是使用delete
。将其设置为 0 需要开发人员了解此实现细节,而 null 或 delete 将传达句柄未激活 (IMO)
@r3wt - 当然,无论你喜欢什么。 null
的实现细节并不比 0
少;在这两种情况下,您都必须知道 A) setInterval
永远不会返回它,如果您这样做 clearInterval
盲目(就像某些人一样) B) 您必须知道它对这些值是无效的。但同样,是的,风格真的...... :-)以上是关于我如何在反应中取消订阅的主要内容,如果未能解决你的问题,请参考以下文章