首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ReactJS:未捕获(在promise中) this.setState不是函数

ReactJS:未捕获(在promise中) this.setState不是函数
EN

Stack Overflow用户
提问于 2018-07-03 07:08:26
回答 4查看 1.4K关注 0票数 0

我正在处理以下令人沮丧的错误:

Home.js:231未捕获(在promise中) TypeError:_this9.setState不是一个函数。错误来自以下函数的最后一行:

代码语言:javascript
复制
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中,我调用了几个函数:

代码语言:javascript
复制
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打破了绑定,这是我目前不明白的原因。

谢谢你的帮助

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-07-04 08:00:07

你正在直接改变状态,这是不允许的,在最后一个例子中,你仍然在这样做。最好使用Object.assign(…)来创建新对象,如下所示:

代码语言:javascript
复制
let newState = Object.assign({}, ...this.state,  running: response);

然后,只执行setState()调用

代码语言:javascript
复制
this.setState(newState);

React的基本原则之一是,对状态的更改不是直接完成的,而是通过setState函数完成的,该函数将更改放到队列中,并且它将单独完成或通过批处理更新完成。

票数 0
EN

Stack Overflow用户

发布于 2018-07-03 07:36:54

promise是一个有保证的未来,这意味着一旦调用整个promise链就会触发,而您几乎无法阻止它。

在实际层面上,这意味着在尝试访问setState之前,您需要检查以确保您的组件实例仍被挂载,因为组件可能在此promise链完成之前已卸载。

代码语言:javascript
复制
.then(response => {
    ...code here...
    // important! check that the instance is still mounted!
    if (this.setState) {
      this.setState(cState);
    }
});

此外,您不应该像这里那样直接更改本地状态:

代码语言:javascript
复制
// don't mutate state directly, use setState!
let cState = this.state;
cState.running = response;
票数 1
EN

Stack Overflow用户

发布于 2018-07-03 09:43:32

您可以尝试将function checkIfRunning() {}更改为checkIfRunning = () => {},以将this传递给function

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51144701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档