如何在React Native中使用componentWillUnmount


componentDidMount () {
this.showPosts();
}
showPosts = async () => {
var userID = await AsyncStorage.getItem('userID');
fetch(strings.baseUri+"getPostWithUserID", {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ 
"user_id": userID
})
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({show: false}); // If I comment this line, then I don't get the warning.
})
.catch((error) => {
console.error(error);
});
}

如何使用componentWillUnmount,因为我收到了下面的警告。当我使用componentWillUnmount时,有没有一种方法可以将State show设置为true?警告

您在代码中混合了一些东西。当您使用this.showPosts()时,您正在使用await,但没有调用await。您也没有像await可以抛出的那样,将await封装在try/catch中。

有几种方法可以解决在未安装的组件上设置状态的问题。尽管这是一种反模式,但最简单的做法是在componentDidMountcomponentWillUnmount中设置一个变量,以跟踪组件的安装状态。

因此,让我们重构您的代码,使其更有意义

这就是您的componentDidMountcomponentWillUnmount现在的样子。

async componentDidMount () {
this._isMounted = true;
await this.showPosts();
}
componentWillUnmount () {
this._isMounted = false;
}

更新showPosts,使其成为纯async/await

showPosts = async () => {
try {
var userID = await AsyncStorage.getItem('userID');
let response = await fetch(strings.baseUri + 'getPostWithUserID', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
'user_id': userID
})
});
let responseJson = await response.json();
if (this._isMounted) {
this.setState({show: false});
}
} catch (err) {
console.error(error);
}
}

或者,如果我们使用您当前的showPost实现,它会是这样的,但修复了等待中缺少try/catch的问题。

showPosts = async () => {
try {
var userID = await AsyncStorage.getItem('userID');
fetch(strings.baseUri + 'getPostWithUserID', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
'user_id': userID
})
})
.then((response) => response.json())
.then((responseJson) => {
if (this._isMounted) {
this.setState({show: false}); // If I comment this line, then I don't get the warning.
}
})
.catch((error) => {
console.error(error);
});
} catch (err) {
console.warn(err);
}
}

另一种选择是一旦做出承诺就取消承诺。这篇文章在一定程度上解释了如何做到这一点https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html

您可以使用一些内部组件对象属性作为-isComponentMounted,然后在异步操作回调期间检查它。

您可以检查组件是否以这种方式安装,然后在异步函数中检查此变量,看看您是否仍可以运行该函数或以其他方式取消它:

componentDidMount() { 
this.mounted = true;
}
componentWillUnmount() {
this.mounted = false;
}
async asyncFunction {
if(this.isMounted){
setState(....);
}else{
return;
}
}

在componentDidMount中设置状态而在构造函数中没有初始状态不是一个好主意,因为它会触发额外的渲染,这可能会导致性能问题。

来自官方文件:

您可以立即在componentDidMount()中调用setState()。它将触发额外的渲染,但它将在浏览器更新屏幕之前发生。这保证了即使在这种情况下render()会被调用两次,用户也不会看到中间状态。请谨慎使用此模式,因为它经常会导致性能问题。在大多数情况下,您应该能够在constructor()中分配初始状态。然而,当您需要在呈现取决于DOM节点大小或位置的东西之前测量DOM节点时,对于模态和工具提示等情况,它可能是必要的。

https://reactjs.org/docs/react-component.html#componentdidmount

但这又回到了为什么要使用componentWillUnmount?这是为了注销事件、推送通知和清理资源。

相关内容

  • 没有找到相关文章

最新更新