【问题标题】:setState from an API response using superagent and React使用 superagent 和 React 从 API 响应中设置状态
【发布时间】:2016-09-02 21:03:13
【问题描述】:

尝试更改组件状态时出现错误。

未捕获的类型错误:无法读取未定义的属性“setState”

constructor(props){
    super(props);

    this.state={
        r:'',
        message:''
    };
    this.setStateMessage = this.setStateMessage.bind(this);
}
setStateMessage (e){
    e.preventDefault();
    var test = this.state.message;

    request
      .post('http://127.0.0.1:5000/api/db')
      .send({message: this.state.message})
      .accept('application/json')
      .withCredentials()
      .end(function(err, res){
        if(err)
            throw err;
        this.setState({ r: res.body.message });
      });
}

render() {
    return (
        <div>
            <div className='response'>
                {this.state.r}
            </div>
            //form with input
        </div>
    )}

【问题讨论】:

    标签: reactjs superagent


    【解决方案1】:

    这是因为您在函数内调用 this.setState,所以 this 实际上是对您所在函数的引用。您需要存储对正确 this 的引用或使用箭头没有自己的上下文并从父上下文继承。所以:

    setStateMessage (e){
      e.preventDefault();
      var test = this.state.message;
      var self = this;
    
      request
        .post('http://127.0.0.1:5000/api/db')
        .send({message: this.state.message})
        .accept('application/json')
        .withCredentials()
        .end(function(err, res){
          if(err) throw err;
          self.setState({ r: res.body.message });
      });
    }
    

    或者:

    setStateMessage (e){
      e.preventDefault();
      var test = this.state.message;
    
      request
        .post('http://127.0.0.1:5000/api/db')
        .send({message: this.state.message})
        .accept('application/json')
        .withCredentials()
        .end((err, res) => {
          if(err) throw err;
          this.setState({ r: res.body.message });
      });
    }
    

    【讨论】:

    • 我今天醒来,想到this 实际上与回调函数有关,所以这是问题的罪魁祸首。我最好的猜测是写var res = request.post('......);之类的东西,然后可能在回调函数之外的setState中使用res?这会是第三种选择吗?
    • 最后一个问题...如果我使用 Redux,我可以使用 dispatch,这样可以吗?是不是因为 Redux 的函数是全局定义的?
    • dispatch 未在全局范围内定义。如果您使用的是 redux,您应该使用 redux-thunk 从异步操作中调用 API。用一个例子来回答你的问题有点困难。但是因为你不会在这个回调中调用this.setState,所以你不会有这个问题。这就是说你应该在 JS 中阅读 this。否则你会在别处感到困惑。
    【解决方案2】:

    要添加到@aray12 的答案,您也可以绑定回调。

    setStateMessage (e){
      e.preventDefault();
      var test = this.state.message;
    
      request
        .post('http://127.0.0.1:5000/api/db')
        .send({message: this.state.message})
        .accept('application/json')
        .withCredentials()
        .end((function(err, res) {
          if(err) throw err;
          this.setState({ r: res.body.message });
      }).bind(this));
    }
    

    【讨论】:

      【解决方案3】:

      在这上面花了太多时间后,我的最终代码就在这里

      class Data extends React.Component{
      
           constructor(){
              super()
              this.state={
                  name:''
              }
          }
      
          componentDidMount(){
              console.log('componentDidMount');
      
              var url = "http:\//localhost:3000/order/test";
              Request
              .get(url)
              .query(null)
              .set('Accept', 'application/json')
              .end ((error, response)=>{
                  const title=response.text
                  console.log(JSON.stringify(title));
      
                  this.setState({
                    name:title
                  });
              });
      
          }
      
          render(){
              return <div>World {this.state.name}</div>;
          }
      
      }
      

      注意:如果回复是文本,您必须使用 response.text,就像我在我的案例中使用的那样

      如果您想了解更多详情click here

      【讨论】:

        猜你喜欢
        • 2021-02-23
        • 1970-01-01
        • 2022-01-16
        • 2020-07-24
        • 2022-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-16
        相关资源
        最近更新 更多