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

alb*_*ert 8 fetch promise reactjs

我正在尝试在React中编写一个组件,它将使用fetch()API从网站获取数据,然后使用setState设置一个等于数据的状态,然后最终渲染数据.我的代码看起来像这样:

import React from 'react';

export default class Test extends React.Component {
    constructor(props){
        super(props);
        this.state = {apiInfo: 'default'};
    }

    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);
            });
    }

    render(){
        return(
                <tr>
                    <td>{this.state.apiInfo}</td>
                </tr>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Chi*_*uin 18

您的错误消息正在告诉您问题的确切原因:

无法设置undefined的State

因此,您正在尝试将调用setState作为此时不存在的对象的方法.作为一个属性,您试图将哪个对象setState称为方法?

this.setState({apiInfo:jsonStr});

是的,这是你this的问题.在你试图把它叫做点-即内.then()一的fetch电话- this实际上是不确定的.你可以在Chrome Devtools中看到这个:

Chrome Devtools显示此= undefined 我担心这this是一个滑稽的JavaScript客户; 它的值可以(并且确实)根据应用的当前上下文而变化.

有几种方法可以解决这个问题.一个稍微笨重(但它有效!)的方法是this在输入.fetch()调用之前捕获您的值,并将其分配给另一个变量.您经常会看到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);
        });
}
Run Code Online (Sandbox Code Playgroud)

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

.then(jsonStr => {
    this.setState({ apiInfo: jsonStr });
    console.log(jsonStr);
});
Run Code Online (Sandbox Code Playgroud)

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