在 componentWillUnmount 方法中取消所有订阅和异步,如何?
Cancel All Subscriptions and Asyncs in the componentWillUnmount Method, how?
由于异步方法问题,我收到一条错误消息。在我的终端中,我看到:
Warning: Can't call setState (or forceUpdate) 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 the componentWillUnmount method.
- node_modules/fbjs/lib/warning.js:33:20 in printWarning
- node_modules/fbjs/lib/warning.js:57:25 in warning
- node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:12196:6 in warnAboutUpdateOnUnmounted
- node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:13273:41 in scheduleWorkImpl
- node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:6224:19 in enqueueSetState
- node_modules/react/cjs/react.development.js:242:31 in setState
* router/_components/item.js:51:16 in getImage$
- node_modules/regenerator-runtime/runtime.js:62:44 in tryCatch
- node_modules/regenerator-runtime/runtime.js:296:30 in invoke
- ... 13 more stack frames from framework internals
我注意到它特别指出 getImage$
这是我在该部分使用的代码:
export default class extends Component {
constructor(props) {
super(props);
const { item } = props
const bindThese = { item }
this.boundActionCreators = bindActionCreators(bindThese)
this.state = {
image: require('../../static/logo.png'),
ready: false,
showOptions: this.props.showOptions
}
this.getImage = this.getImage.bind(this)
this.renderNotAdmin = this.renderNotAdmin.bind(this)
this.renderAdmin = this.renderAdmin.bind(this)
this.handleOutOfStock = this.handleOutOfStock.bind(this)
}
async getImage(img) {
let imgUri = await Amplify.Storage.get(img)
let uri = await CacheManager.get(imgUri).getPath()
this.setState({
image: { uri },
ready: true
})
}
componentDidMount() {
this.getImage(this.props.item.image)
}
我正在尝试弄清楚如何将 componentWillUnmount
与此异步方法一起使用。我该怎么做?
谢谢!
Just set a _isMounted property to true in componentDidMount and set it
to false in componentWillUnmount, and use this variable to check your
component’s status.
它接着说,理想情况下,这将通过使用可取消的回调来解决,尽管第一个解决方案在这里似乎合适。
您绝对不应该使用 isMounted() 函数,该函数可能已被弃用。
您可以使用 isMounted
React 模式来避免此处的内存泄漏。
在你的构造函数中:
constructor(props) {
super(props);
this._isMounted = false;
// rest of your code
}
componentDidMount() {
this._isMounted = true;
this._isMounted && this.getImage(this.props.item.image);
}
在你的 componentWillUnmount
componentWillUnmount() {
this._isMounted = false;
}
在你身上getImage()
async getImage(img) {
let imgUri = await Amplify.Storage.get(img)
let uri = await CacheManager.get(imgUri).getPath()
this._isMounted && this.setState({
image: { uri },
ready: true
})
}
使用基于可取消承诺模式的 Axios 的推荐方法。因此,您可以在使用 cancelToken subscription
卸载组件时取消任何网络调用。
这是 Axios Cancellation
的资源
您需要在 componentWillUnmount() 方法中设置 this.mounted = false,在 componentDidMount() 方法中设置 this.mounted = true。
setState更新是有条件的,需要在componentDidMount()方法中声明。
componentDidMount() {
this.mounted = true;
var myVar = setInterval(() => {
let nextPercent = this.state.percentage+10;
if (nextPercent >= 100) {
clearInterval(myVar);
}
if(this.mounted) {
this.setState({ percentage: nextPercent });
}
}, 100);
}
componentWillUnmount(){
this.mounted = false;
}
我通过覆盖 setState
方法解决了错误
isSubscribed = true;
componentWillUnmount() {
this.isSubscribed = false;
}
setState = (state, callback?) => {
if (this.isSubscribed) {
super.setState(state, callback);
}
}
由于异步方法问题,我收到一条错误消息。在我的终端中,我看到:
Warning: Can't call setState (or forceUpdate) 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 the componentWillUnmount method.
- node_modules/fbjs/lib/warning.js:33:20 in printWarning
- node_modules/fbjs/lib/warning.js:57:25 in warning
- node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:12196:6 in warnAboutUpdateOnUnmounted
- node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:13273:41 in scheduleWorkImpl
- node_modules/react-native/Libraries/Renderer/ReactNativeRenderer-dev.js:6224:19 in enqueueSetState
- node_modules/react/cjs/react.development.js:242:31 in setState
* router/_components/item.js:51:16 in getImage$
- node_modules/regenerator-runtime/runtime.js:62:44 in tryCatch
- node_modules/regenerator-runtime/runtime.js:296:30 in invoke
- ... 13 more stack frames from framework internals
我注意到它特别指出 getImage$
这是我在该部分使用的代码:
export default class extends Component {
constructor(props) {
super(props);
const { item } = props
const bindThese = { item }
this.boundActionCreators = bindActionCreators(bindThese)
this.state = {
image: require('../../static/logo.png'),
ready: false,
showOptions: this.props.showOptions
}
this.getImage = this.getImage.bind(this)
this.renderNotAdmin = this.renderNotAdmin.bind(this)
this.renderAdmin = this.renderAdmin.bind(this)
this.handleOutOfStock = this.handleOutOfStock.bind(this)
}
async getImage(img) {
let imgUri = await Amplify.Storage.get(img)
let uri = await CacheManager.get(imgUri).getPath()
this.setState({
image: { uri },
ready: true
})
}
componentDidMount() {
this.getImage(this.props.item.image)
}
我正在尝试弄清楚如何将 componentWillUnmount
与此异步方法一起使用。我该怎么做?
谢谢!
Just set a _isMounted property to true in componentDidMount and set it to false in componentWillUnmount, and use this variable to check your component’s status.
它接着说,理想情况下,这将通过使用可取消的回调来解决,尽管第一个解决方案在这里似乎合适。
您绝对不应该使用 isMounted() 函数,该函数可能已被弃用。
您可以使用 isMounted
React 模式来避免此处的内存泄漏。
在你的构造函数中:
constructor(props) {
super(props);
this._isMounted = false;
// rest of your code
}
componentDidMount() {
this._isMounted = true;
this._isMounted && this.getImage(this.props.item.image);
}
在你的 componentWillUnmount
componentWillUnmount() {
this._isMounted = false;
}
在你身上getImage()
async getImage(img) {
let imgUri = await Amplify.Storage.get(img)
let uri = await CacheManager.get(imgUri).getPath()
this._isMounted && this.setState({
image: { uri },
ready: true
})
}
使用基于可取消承诺模式的 Axios 的推荐方法。因此,您可以在使用 cancelToken subscription
卸载组件时取消任何网络调用。
这是 Axios Cancellation
您需要在 componentWillUnmount() 方法中设置 this.mounted = false,在 componentDidMount() 方法中设置 this.mounted = true。
setState更新是有条件的,需要在componentDidMount()方法中声明。
componentDidMount() {
this.mounted = true;
var myVar = setInterval(() => {
let nextPercent = this.state.percentage+10;
if (nextPercent >= 100) {
clearInterval(myVar);
}
if(this.mounted) {
this.setState({ percentage: nextPercent });
}
}, 100);
}
componentWillUnmount(){
this.mounted = false;
}
我通过覆盖 setState
方法解决了错误
isSubscribed = true; componentWillUnmount() { this.isSubscribed = false; } setState = (state, callback?) => { if (this.isSubscribed) { super.setState(state, callback); } }