如何在React中使用fetch()API来设置setState

时间:2018-04-06 02:13:27

标签: reactjs promise fetch

我正在尝试在React中编写一个组件,它将使用fetch()API从网站获取数据,然后使用setState设置一个等于数据的状态,然后最终渲染数据。我的代码如下所示:

const aaa = new DLOinterval<number, DLOnumber>(new DLOnumber(3),new DLOnumber(5),null)

但是,这会导致错误,说我无法设置undefined的State。我最终在HTML上呈现'default'。我到底错在了什么?

4 个答案:

答案 0 :(得分:9)

您的错误消息确切地告诉您问题所在:

  

无法设置未定义的状态

因此,您正在尝试调用setState作为此时不存在的对象的方法。作为您尝试将setState作为方法调用的对象的属性?

  

this.setState({apiInfo:jsonStr});

是的,这是你的this问题所在。在您尝试调用它时 - 即在.then() fetch调用内this实际上未定义。您可以在Chrome Devtools中看到这一点:

Chrome Devtools shows this=undefined 我担心this在JavaScript中是一个滑溜溜的客户;它的值可以(并且确实)根据应用的当前上下文而变化。

有几种方法可以解决这个问题。一个稍微笨重(但它有效!)的方法是在输入.fetch()调用之前捕获this值,并将其分配给另一个变量。您经常会看到用于此目的的thatself变量,但它们只是惯例。您可以根据需要调用变量。

以下是我将您的componentDidMount()方法重新设计为thisthat并在that内调用.then()的方法:

componentDidMount() {
    const that = this;
    fetch("https://fcctop100.herokuapp.com/api/fccusers/top/recent")
        .then(function(response) {
            return response.json();
        })
        .then(function(jsonData) {
            return JSON.stringify(jsonData);
        })
        .then(function(jsonStr) {
            that.setState({ apiInfo: jsonStr });
            console.log(jsonStr);
        });
}

如果你习惯使用箭头功能,那么另一种方法是用一个替换你的“普通”函数调用,如下所示:

.then(jsonStr => {
    this.setState({ apiInfo: jsonStr });
    console.log(jsonStr);
});

箭头函数的this始终是其父级定义的this

答案 1 :(得分:1)

它说setState未定义,因为您在错误的上下文中访问它。您可以将函数转换为箭头函数或将其绑定到正确的上下文。 Here是一篇关于何时以及为什么要将它与React组件方法绑定的文章。

在您的代码中,可以进行的更改是绑定它

.then(function(jsonStr){
          this.setState({apiInfo: jsonStr});
          console.log(jsonStr);
      }.bind(this));

或使用箭头功能

.then((jsonStr)=>{
          this.setState({apiInfo: jsonStr});
          console.log(jsonStr);
      });

答案 2 :(得分:0)

 componentDidMount() {
    fetch('https://fcctop100.herokuapp.com/api/fccusers/top/recent')
      .then(response => response.json())
      .then(data => this.setState({ apiInfo: data }));
  }

在渲染功能中,您不能只执行this.state.apiInfo。此数据是一个对象数组,每个对象都有username img等键。如果console.log(this.state.apiInfo)功能位于render功能区内且位于return之外,则可以看到。

要访问并显示数组值中的每个对象,您可以map通过apiInfo数组。

render() {
const { apiInfo } = this.state;
apiInfo && console.log(apiInfo.map(item => item.img));
return (
  <div>
    {apiInfo &&
      apiInfo.map(item =>  <div> {item.img} </div> )}
  </div>
);
}

浏览器附带的本机提取API使用JavaScript承诺来解析异步响应。

成功获取数据后,它将使用React的this.setState()方法存储在本地状态。然后render()方法将再次触发,您可以显示获取的数据。

箭头函数在ES6中引入,箭头函数没有自己的上下文,而是使用与定义它的上下文相同的this。我们可以使用这个事实并将箭头函数传递给回调。

答案 3 :(得分:0)

  • this是指调用该函数的对象。
  • 每个普通函数都有其自己的this,但是箭头函数没有(this指的是外部上下文,即this在函数外部)。

所以可能的解决方案是

  • 使用箭头功能
componentDidMount = () => {
    fetch('https://fcctop100.herokuapp.com/api/fccusers/top/recent').then(
            function(response){
                return response.json();
            }
            ).then(function(jsonData){
                return JSON.stringify(jsonData);
            }
            ).then(function(jsonStr){
                this.setState({apiInfo: jsonStr});
                console.log(jsonStr);
            });
}
  • 更早地将this保存在其他变量中,并将其作为参数传递。
  • this绑定到函数

https://reactjs.org/docs/handling-events.html