luk*_*az7 5 javascript promise reactjs
在我的很多组件中,我需要做这样的事情:
handleSubmit() {
this.setState({loading: true})
someAsyncFunc()
.then(() => {
return this.props.onSuccess()
})
.finally(() => this.setState({loading: false}))
}
Run Code Online (Sandbox Code Playgroud)
该onSuccess功能
loading应该保持真实,直到解决)如果函数卸载组件,this.setState({loading: false})显然会触发警告Can't call setState (or forceUpdate) on an unmounted component.
我的两个问题:
_isMounted变量componentDidMount和componentWillUnmount,然后检查它需要在我的大多数组件的时候,再加上我可能会忘记做下一次写这样的事情...it indicates a memory leak in my application但在这种情况下它不是内存泄漏,是吗?也许忽略警告就可以了......编辑:第二个问题对我来说比第一个问题更重要一点。如果这真的是一个问题并且我无法调用setState未安装的组件,我可能会自己找到一些解决方法。但我很好奇我是否不能忽略它。
问题的现场示例:
handleSubmit() {
this.setState({loading: true})
someAsyncFunc()
.then(() => {
return this.props.onSuccess()
})
.finally(() => this.setState({loading: false}))
}
Run Code Online (Sandbox Code Playgroud)
const someAsyncFunc = () => new Promise(resolve => {
setTimeout(() => {
console.log("someAsyncFunc resolving");
resolve("done");
}, 2000);
});
class Example extends React.Component {
constructor(...args) {
super(...args);
this.state = {loading: false};
}
componentDidMount() {
setTimeout(() => this.handleSubmit(), 100);
}
handleSubmit() {
this.setState({loading: true})
someAsyncFunc()
/*
.then(() => {
return this.props.onSuccess()
})
*/
.finally(() => this.setState({loading: false}))
}
render() {
return <div>{String(this.state.loading)}</div>;
}
}
class Wrapper extends React.Component {
constructor(props, ...rest) {
super(props, ...rest);
this.state = {
children: props.children
};
}
componentDidMount() {
setTimeout(() => {
console.log("removing");
this.setState({children: []});
}, 1500)
}
render() {
return <div>{this.state.children}</div>;
}
}
ReactDOM.render(
<Wrapper>
<Example />
</Wrapper>,
document.getElementById("root")
);Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper {
max-height: 100% !important;
}Run Code Online (Sandbox Code Playgroud)
不幸的是,您必须自己跟踪“isMounted”。为了简化控制流程,您可以使用async/await:
handleSubmit() {
this.setState({loading: true})
try {
await someAsyncFunction()
await this.props.onSuccess()
} finally {
if (this._isMounted) {
this.setState({loading: false})
}
}
}
Run Code Online (Sandbox Code Playgroud)
这实际上在反应文档中提到,它指向这个解决方案:https://gist.github.com/bvaughn/982ab689a41097237f6e9860db7ca8d6
如果您支持取消,您应该按照本文的鼓励在componentWillUnmountsomeAsyncFunction中执行此操作。但随后 - 当然 - 检查返回值并最终不调用。this.props.onSuccess