我从反应原生开始,在我的项目中,我达到了一切可行的地步,但是有这个警告:
Warning: setState(...): Can only update a mounted or mounting component.
所以,我已经查看了几个QA,尝试了一些解决方案(更改了来自setState()
和componentWillMount
的{{1}}来电)但是...警告始终存在。
以下是代码的一部分:
componentDidMount
REQUEST_URL = 'http://url/users.php';
(...)
module.exports = React.createClass({
getInitialState: function() {
return {
uid: null,
bid: null,
username: null,
}
},
componentDidMount: function() {
this.fetchData();
},
fetchData: function() {
fetch(REQUEST_URL)
.then( (response) => response.json() )
.then( (json) => {
console.log('setState called');
this.setState({
uid: json.users[0].user_id,
bid: json.users[0].building_id,
username: json.users[0].username
});
})
.done();
},
render: function() {
if (!this.state.uid) { //user is not defined
console.log('not rendered');
return <Text>chargement...</Text>
}
// else
console.log('rendered');
var userId = this.state.uid;
var buildingId = this.state.bid;
var username = this.state.username;
return (
<View style={styles.content}>
<Text style={styles.label}>User Id</Text>
<Text>{userId}</Text>
<Text style={styles.label}>Building Id</Text>
<Text>{buildingId}</Text>
<Text style={styles.label}>Username</Text>
<Text>{username}</Text>
</View>
)
},
});
返回json内容类型。
任何线索?
感谢名单。
答案 0 :(得分:2)
The problem may be that react re-mounts certain components multiple times in one render (think that has something to do with the representation of initial values, could not find the question here), therefore your state
would be set to a component that is not mounted.
If you set your state
in a decoupled timeout that can be cleared when the component unmounts, you avoid setting state on a unmounted component.
componentDidMount() {
this.mounted = true;
// this.fetchTimeout = setTimeout(()=>{
this.fetchData();
// });
},
componentWillUnmount() {
// clearTimeouts(this.fetchTimeout);
this.mounted = false;
},
fetchData() {
fetch(REQUEST_URL)
.then( (response) => response.json() )
.then( (json) => {
console.log('setState called');
if (this.mounted === true){
this.setState({
uid: json.users[0].user_id,
bid: json.users[0].building_id,
username: json.users[0].username
});
}
})
.done();
},
I still don't know if we are supposed to use TimerMixins
but this way works without those.
(TimerMixins
take care of clearing any timeout or interval set in the component)
EDIT: update sample to only call setState
of the component is still mounted.
I do not know if there is a better way, but as far as I know until now you can not cancel a fetch request.