Reactjs多次获取 - TypeError:无法读取属性' last'未定义的

时间:2018-02-16 07:13:49

标签: javascript reactjs fetch

我已经有一次获取并希望获得多次获取但第二次获取就像无法读取数据一样。它显示" TypeError:无法读取属性' last'未定义"。

这是我的一次获取代码:

class App extends Component {
constructor(props) {
    super(props);
    this.state = {
        error: null,
        isLoaded: false,
        ticker: []
    };
}

componentDidMount() {
    fetch("https://vip.bitcoin.co.id/api/btc_idr/ticker")
    .then(res => res.json())
    .then(
        (result) => {
            this.setState({
                isLoaded: true,
                tickerBtcIdr: result.ticker
            });
        },
        (error) => {
            this.setState({
                isLoaded: true,
                error
            });
        }
    )
}

render() {
    const {
        error,
        isLoaded,
        tickerBtcIdr,
    }  = this.state;
    if (error) {
        return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
        return (
            <div>
                <div className="App"></div>
                <div className="Loading">
                    <Loading />
                </div>
            </div>
        );
    } else {
        return (
            <div className="App">
                <AppBar />
                <table>
                    <tr>
                        <td><b>IDR MARKETS</b></td>
                    </tr>
                    <tr>
                        <td>BTC/IDR</td>
                        <td>Bitcoin</td>
                        <td>{tickerBtcIdr.last}</td>
                        <td>{tickerBtcIdr.vol_idr}</td>
                    </tr>
                </table>
            </div>
        );
    }
}}

这项工作,但如果我复制像:

这样的提取
    componentDidMount() {
    fetch("https://vip.bitcoin.co.id/api/btc_idr/ticker")
    .then(res => res.json())
    .then(
        (result) => {
            this.setState({
                isLoaded: true,
                tickerBtcIdr: result.ticker
            });
        },
        (error) => {
            this.setState({
                isLoaded: true,
                error
            });
        }
    )

    fetch("https://vip.bitcoin.co.id/api/bch_idr/ticker")
    .then(res => res.json())
    .then(
        (result) => {
            this.setState({
                isLoaded: true,
                tickerBchIdr: result.ticker
            });
        },
        (error) => {
            this.setState({
                isLoaded: true,
                error
            });
        }
    )
}

我渲染它:

    render() {
    const {
        error,
        isLoaded,
        tickerBtcIdr,
        tickerBchIdr,
    }  = this.state;
    if (error) {
        return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
        return (
            <div>
                <div className="App"></div>
                <div className="Loading">
                    <Loading />
                </div>
            </div>
        );
    } else {
        return (
            <div className="App">
                <AppBar />
                <table>
                    <tr>
                        <td>BTC/IDR</td>
                        <td>{tickerBtcIdr.last}</td>
                        <td>{tickerBtcIdr.vol_idr}</td>
                    </tr>
                    <tr>
                        <td>BCH/IDR</td>
                        <td>{tickerBchIdr.last}</td>
                    </tr>
                </table>
            </div>
        );
    }
}

}

它显示&#34; TypeError:无法读取属性&#39; last&#39;未定义&#34;。

1 个答案:

答案 0 :(得分:1)

Fetch的承诺是异步的,因此第二个请求可以在第一个请求之前完成。

如果第二个请求首先返回,则表示您具有以下形状的状态:

{
  isLoaded: true,
  tickerBtcIdr: undefinded,
  tickerBchIdr: { ... },
  ...
}

但是,当tickerBtcIdr真实时,您的渲染函数希望tickerBchIdrisLoaded都包含数据。

由于您需要渲染中的两个数据集,因此在收到一个请求后,您无法将isLoaded设置为true。最简单的解决方案是只检查数据而不是使用不值得信任的isLoading值。

在渲染功能中,您可以更改此内容:

else if (!isLoaded) 

else if (!(tickerBtcIdr && tickerBchIdr))

如果您确实想使用isLoading,可以使用Promise.all()async await,这样可以在将isLoading设置为true之前等待两次获取请求。