我正在处理以下令人沮丧的错误:
Home.js:231未捕获(承诺)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));
}
我有一个直觉,就是诺言链破坏了绑定,原因是我目前不了解。
谢谢您的帮助,
答案 0 :(得分:1)
承诺是有保证的未来,这意味着一旦调用,整个承诺链就会触发,并且您无能为力。
从实际的角度来看,这意味着您需要检查以确保在尝试访问setState之前仍在装入组件实例,因为在此承诺链完成之前,组件可能已卸载。
.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;
答案 1 :(得分:0)
您可以尝试将功能checkIfRunning = () => {}
更改为this
,以将dist
传递给功能
答案 2 :(得分:0)
非常感谢您的帮助。
我通过以下修复方法解决了该问题,尽管不确定为什么现在可以解决该问题:
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});
});
}
请注意this.setState(cState)如何变成this.setState({cState})。
感谢您的宝贵时间,这为我带来了有趣的研究。
答案 3 :(得分:0)
您正在直接更改状态,这是不允许的,在最后一个示例中,您仍在这样做。最好使用Object.assign(…)
创建这样的新对象:
let newState = Object.assign({}, ...this.state, running: response);
然后,仅拨打您的setState()
电话
this.setState(newState);
React的基本原理之一是对State的更改不是直接完成,而是使用setState
函数,该更改会将更改放入队列,并且可以单独进行或通过批处理更新来完成。