我有一段可以触发警告的代码(代码应该登录到REST并关闭Activity Indicator)。我不明白我的组件是如何卸载的,因为我在按钮点击上绑定了onLoginPressed,之后所有可能的安装都应该已经完成。请帮助我摆脱它,并了解警告的原因...
UPD:感谢评论,我发现组件已卸载,并且调用了componentWillUnmount ......但我不明白为什么以及何时发生......
“警告:setState(...):只能更新已安装或已安装 零件。这通常意味着您在已卸载时调用了setState() 零件。这是一个无操作。请检查未定义的代码 部件“。
以下是我的代码,警告由第二个setState
触发:
onLoginPressed(){
console.log('Attempted to login with: '+this.state.username);
this.setState({showProgress: true});
AuthService.login({
login: this.state.username,
password: this.state.password
}, (results)=> {
this.setState(Object.assign({ // have to create a solid Object with all states to be changed at once
showProgress: false // turning off ActivityIndicator
}, results));
if(results.success && this.props.onLogin){
this.props.onLogin(); // Yey! We logged in! Let's move to the next View
}
});
}
... AuthService.js:
login (creds, callback) {
fetch(CFG.AUTH_URL)
.then((response)=> {
if((response.status >= 200) && (response.status < 300)){
return response.json();
}
throw {
serverError: (response.status == 500) || (response.status == 501),
unknownError: (response.status != 500) || (response.status != 501)
};
})
.then((result)=> {
AsyncStorage.multiSet([ // Have to save login+password and session_hash for later use...
[authKey, JSON.stringify(creds)],
[sessionKey, result.data.session_hash]
], (err)=> {
if (err) throw err;
});
return callback({success: true});
}
})
.catch((err)=> {
return callback(err);
});
}// end of login
答案 0 :(得分:4)
ФедорУсаков,我也遇到了这个问题。我发现由于在AuthService.login()
的回调函数中设置状态,组件正在重新渲染。问题(在这种情况下)与setState
:
来自React docs的无法保证对setState的调用同步操作 并且可以批量调用以获得性能提升。
我的猜测是没有立即设置状态,然后调用this.props.onLogin()
。这可以在设置状态之前取消组件,瞧,警告。
为了让我的工作,我删除了条件和onLogin()
的调用,并向shouldComponentUpdate()
类添加了Login
方法。在shouldComponentUpdate()
我放置了删除的条件和调用。像这样:
onLoginButtonPress() {
// some code
AuthService.login({
username: this.state.username,
password: this.state.password
}, (results) => {
this.setState({
...results,
showProgress: false
});
});
}
shouldComponentUpdate() {
if (this.state.loginSuccess && this.props.onLogin) {
this.props.onLogin();
}
return true;
}
这确保了状态已设置,然后组件重新呈现,并且因为this.state.loginSuccess
现在为真,请调用this.props.onLogin()
,这会导致Login
卸载。