我正在处理以下令人沮丧的错误:
Home.js:231未捕获(在promise中) TypeError:_this9.setState不是一个函数。错误来自以下函数的最后一行:
checkIfRunning() {
return fetch('/api/following/iscurrentlyrunning', {
credentials: 'include',
})
.then(response => {
console.log(response.status);
if (response.status === 200) {
return response.json();
}
})
.then(response => {
let cState = this.state;
cState.running = response;
this.setState(cState);
});
}我确实在组件构造函数中绑定了函数,当我单独调用它时,它工作得很好。当我尝试调用计时器(setInterval)中的函数时,问题就出现了。在componentWillMount中,我调用了几个函数:
componentWillMount() {
this.checkIfFirstTimeLogin()
.then(() => {
// user already exists
if (!this.state.firstLogin) {
this.Name();
this.getRole();
setInterval(() => this.checkIfRunning(), 10000);
}
})
.then(() => {
let cState = this.state;
cState.pageLoading = false;
this.setState(cState);
})
.catch(error => console.log(error));
}我有一种直觉,promise chain打破了绑定,这是我目前不明白的原因。
谢谢你的帮助
发布于 2018-07-04 08:00:07
你正在直接改变状态,这是不允许的,在最后一个例子中,你仍然在这样做。最好使用Object.assign(…)来创建新对象,如下所示:
let newState = Object.assign({}, ...this.state, running: response);然后,只执行setState()调用
this.setState(newState);React的基本原则之一是,对状态的更改不是直接完成的,而是通过setState函数完成的,该函数将更改放到队列中,并且它将单独完成或通过批处理更新完成。
发布于 2018-07-03 07:36:54
promise是一个有保证的未来,这意味着一旦调用整个promise链就会触发,而您几乎无法阻止它。
在实际层面上,这意味着在尝试访问setState之前,您需要检查以确保您的组件实例仍被挂载,因为组件可能在此promise链完成之前已卸载。
.then(response => {
...code here...
// important! check that the instance is still mounted!
if (this.setState) {
this.setState(cState);
}
});此外,您不应该像这里那样直接更改本地状态:
// don't mutate state directly, use setState!
let cState = this.state;
cState.running = response;发布于 2018-07-03 09:43:32
您可以尝试将function checkIfRunning() {}更改为checkIfRunning = () => {},以将this传递给function
https://stackoverflow.com/questions/51144701
复制相似问题