You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apollo Client订阅中this.setState报TypeError的原因咨询

解决Apollo Client订阅回调中this.setState报错的问题

这个报错的核心原因很明确——你在subscribe的next回调里用了普通函数,导致this的指向不是你的React组件实例,自然就找不到setState方法了。

下面给你几种可行的解决方案,按推荐程度排序:

方案1:改用箭头函数(最推荐)

箭头函数不会创建自己的this,会继承外层作用域的this(也就是你的组件实例),直接修改回调函数即可:

componentDidMount() { 
  const SUBSCRIBE_POST = gql` 
    subscription{ 
      postAdded{ 
        id 
        message 
        type 
        created 
        customers_ID 
        customer{id,firstName} 
      } 
    } 
  `; 
  const {client} = this.props 
  client.subscribe({query: SUBSCRIBE_POST}) 
    .subscribe({ 
      next: (data) => { // 这里改成箭头函数
        const response = data.data.postAdded 
        console.log(response) 
        this.setState({list: response}) 
      }, 
      error(err) {console.error('err', err);}, 
    }) 
}

方案2:提前保存组件的this

在回调函数外部把组件的this存到一个变量里,比如that,然后在回调里用这个变量调用setState:

componentDidMount() { 
  const SUBSCRIBE_POST = gql` 
    subscription{ 
      postAdded{ 
        id 
        message 
        type 
        created 
        customers_ID 
        customer{id,firstName} 
      } 
    } 
  `; 
  const {client} = this.props;
  const that = this; // 保存组件实例的引用
  client.subscribe({query: SUBSCRIBE_POST}) 
    .subscribe({ 
      next(data) { 
        const response = data.data.postAdded 
        console.log(response) 
        that.setState({list: response}) // 使用保存的that
      }, 
      error(err) {console.error('err', err);}, 
    }) 
}

方案3:用bind绑定this

通过bind方法把组件的this绑定到回调函数上,强制改变它的指向:

componentDidMount() { 
  const SUBSCRIBE_POST = gql` 
    subscription{ 
      postAdded{ 
        id 
        message 
        type 
        created 
        customers_ID 
        customer{id,firstName} 
      } 
    } 
  `; 
  const {client} = this.props 
  client.subscribe({query: SUBSCRIBE_POST}) 
    .subscribe({ 
      next(function(data) { 
        const response = data.data.postAdded 
        console.log(response) 
        this.setState({list: response}) 
      }.bind(this)), // 绑定组件的this
      error(err) {console.error('err', err);}, 
    }) 
}

另外提个小建议:你原来代码里在外部声明的response变量其实没必要,可以直接在回调里声明,避免不必要的变量污染~

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 19:13:14