在ReactJS中卸载组件时取消承诺
我有一个名为“Item”的组件,它在安装时创建并调用承诺在ReactJS中卸载组件时取消承诺,reactjs,promise,cancellation,Reactjs,Promise,Cancellation,我有一个名为“Item”的组件,它在安装时创建并调用承诺 class Item extends React.Component{ constructor(props){ super(props) this.onClick = this.onClick.bind(this) this.prom = new Promise((resolve, reject) => { setTimeout(() => re
class Item extends React.Component{
constructor(props){
super(props)
this.onClick = this.onClick.bind(this)
this.prom = new Promise((resolve, reject) => {
setTimeout(() => resolve("PROMISE COMPLETED "+this.props.id),6000)
})
}
componentDidMount(){
this.prom.then((success) => {
console.log(success)
})
}
componentWillUnmount(){
console.log("unmounted")
}
onClick(e){
e.preventDefault()
this.props.remove(this.props.id)
}
render(){
return (
<h1>Item {this.props.id} - <a href="#" onClick={this.onClick}>Remove</a></h1>
)
}
}
卸载组件时,我必须取消承诺。您不能取消本机ES6承诺。阅读更多
但是,您可以使用非本机的promise库,如或,它们为您提供可以取消的承诺。您可以做很多事情。最简单的方法是拒绝承诺:
this.prom = new Promise((resolve, reject) => {
this.rejectProm = reject;
...
});
然后
componentWillUnmount(){
if (this.rejectProm) {
this.rejectProm();
this.rejectProm = nil;
}
console.log("unmounted")
}
这种变化似乎对我有用。
我使用装载的实例变量创建了一个HOC,并将所有异步组件包装在其中
下面是我的代码大致如下
export function makeMountAware(Component) {
return class MountAwareComponent extends React.Component {
mounted = false;
componentDidMount() {
this.mounted = true;
}
componentWillUnmount() {
this.mounted = false;
}
return (
<Component
mounted = {this.mounted}
{...this.props}
{...this.state}
/>
);
}
}
class AsyncComponent extends React.Component {
componentDidMount() {
fetchAsyncData()
.then(data => {
this.props.mounted && this.setState(prevState => ({
...prevState,
data
}));
});
}
}
export default makeMountAware(AsyncComponent);
导出函数makeMountAware(组件){
返回类MountAwareComponent扩展React.Component{
安装=错误;
componentDidMount(){
这是真的;
}
组件将卸载(){
这是错误的;
}
返回(
);
}
}
类AsyncComponent扩展了React.Component{
componentDidMount(){
fetchAsyncData()
。然后(数据=>{
this.props.mounted和this.setState(prevState=>({
…国家,
数据
}));
});
}
}
导出默认makeMountAware(异步组件);
由于本例中使用的是超时,因此在卸载时应将其清除
class Item extends React.Component{
constructor(props){
super(props)
this.onClick = this.onClick.bind(this)
// attribute for the timeout
this.timeout = null;
this.prom = new Promise((resolve, reject) => {
// assign timeout
this.timeout = setTimeout(() => resolve("PROMISE COMPLETED "+this.props.id),6000)
})
}
componentDidMount(){
this.prom.then((success) => {
console.log(success)
})
}
componentWillUnmount(){
// clear timeout
clearTimeout(this.timeout);
console.log("unmounted")
}
我猜这将导致拒绝,您将看不到控制台日志。我想我们无法检查此答案:,也请检查此答案:您是否试图在
this.prom
处仅调用Promise
构造函数一次?我不确定是否完全理解此问题,但是否有帮助?第8行和第28行是查看js承诺的部分,但承诺与使用的库无关,@chitharanjan das,你的意思是说本机js承诺不能取消吗?这不会导致内存泄漏吗?因为即使在卸载组件时,承诺仍然保留对它的引用?
export function makeMountAware(Component) {
return class MountAwareComponent extends React.Component {
mounted = false;
componentDidMount() {
this.mounted = true;
}
componentWillUnmount() {
this.mounted = false;
}
return (
<Component
mounted = {this.mounted}
{...this.props}
{...this.state}
/>
);
}
}
class AsyncComponent extends React.Component {
componentDidMount() {
fetchAsyncData()
.then(data => {
this.props.mounted && this.setState(prevState => ({
...prevState,
data
}));
});
}
}
export default makeMountAware(AsyncComponent);
class Item extends React.Component{
constructor(props){
super(props)
this.onClick = this.onClick.bind(this)
// attribute for the timeout
this.timeout = null;
this.prom = new Promise((resolve, reject) => {
// assign timeout
this.timeout = setTimeout(() => resolve("PROMISE COMPLETED "+this.props.id),6000)
})
}
componentDidMount(){
this.prom.then((success) => {
console.log(success)
})
}
componentWillUnmount(){
// clear timeout
clearTimeout(this.timeout);
console.log("unmounted")
}