为了账号安全,请及时绑定邮箱和手机立即绑定

在获取并等待之后,React中的“无法读取未定义的属性”

在获取并等待之后,React中的“无法读取未定义的属性”

白猪掌柜的 2021-04-17 18:11:37
我是React的新手,并且在获取时遇到问题:我一直在做一个反应项目,根据用户选择的公司,我必须从五个不同的URL中获取。我已经多次更改了代码,但无法正常工作。我尝试了componentDidMount(但它只被调用过一次,并且我想获取许多网址),并使用“ while(!this.state)”忙于等待获取以在分配数据之前获取数据,等等。提取功能:async fetch_data() {    var sel = this.props.select;    symbol = companies[sel];    url = 'https://www.alphavantage.co/query?function=' + func + '&symbol=' + symbol + '&outputsize=' + osize + '&apikey=' + api_key;    var response = await fetch(url);    var data = await response.json();    while(!data);    this.setState({data: data, loading: false });    this.setValues();      }设置值功能(已修剪,因此不会太长):setValues() {    day = this.state.data["Meta Data"]["3. Last Refreshed"];    open = this.state.data["Time Series (Daily)"][day]["1. open"];    higher = this.state.data["Time Series (Daily)"][day]["2. high"];  }渲染功能(也已修剪):render() {    this.fetch_data();    if(this.state.loading || !this.state || !this.state.data) {      return <div>Loading :D...</div>    } else {      return (        <div>          <h2>Symbol: {symbol}</h2>          <p>Url: {url}</p>          <ul>            <li>              Open price: {open}            </li>            <li>              Higher price: {higher}            </li>          </ul>        </div>      );    }  }当用户选择公司时,我实际上已经完成了该部分,并且符号(和url)发生了变化……但是问题是,this.state.data["Time Series (Daily)"][day]["1. open"];例如,当程序要访问时,它由于获取和接收数据而崩溃。错误提示:Unhandled Rejection (TypeError): Cannot read property '3. Last Refreshed' of undefined:  42 | setValues() {> 43 |   day = this.state.data["Meta Data"]["3. Last Refreshed"];     | ^  44 |   open = this.state.data["Time Series (Daily)"][day]["1. open"];  45 |   higher = this.state.data["Time Series (Daily)"][day]["2. high"];该应用程序并不总是崩溃,它会显示结果,但是渲染组件会继续调用this.fetch_data(),并且它崩溃是因为有时(如80%的时间)数据没有到达,而我试图访问它。
查看完整描述

3 回答

?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

我找到了一个解决方案:

只需在返回之前在渲染中放置if语句,说“符号是否已更改?如果是,则获取,否则不”


查看完整回答
反对 回复 2021-04-22
?
MMTTMM

TA贡献1869条经验 获得超4个赞

此问题的原因setState()是异步的。在您的情况下,这意味着状态已在此处进行更改:


this.setState({data: data, loading: false });

在随后的调用this.setValues();(它本身依赖于data组件状态中定义的对象)上不是立即可观察到的。这些情况的解决方案是在setState()方法上使用第二个回调参数来运行依赖于相应状态更改的逻辑:


/* The state change will be observable when setValues() is called via

the callback */

this.setState({data: data, loading: false }, () => {


    this.setValues();    

});

至于你的组件实现的建议,考虑修改render()方法,这样day,open和higher被访问和渲染render()直接,因为你似乎是做,而不是在其他地方缓存这些值。所以尝试这样的事情:


render() {


    this.fetch_data();

    if(this.state.loading || !this.state || !this.state.data) {

      return <div>Loading :D...</div>

    } else {


      /* Call to setValues() no longer needed */


      const day = this.state.data["Meta Data"]["3. Last Refreshed"];

      const open = this.state.data["Time Series (Daily)"][day]["1. open"];

      const higher = this.state.data["Time Series (Daily)"][day]["2. high"];


      return (

        <div>

          <h2>Symbol: {symbol}</h2>

          <p>Url: {url}</p>

          <ul>

            <li>

              Open price: {open}

            </li>

            <li>

              Higher price: {higher}

            </li>

          </ul>

        </div>

      );

    }

  }


查看完整回答
反对 回复 2021-04-22
  • 3 回答
  • 0 关注
  • 245 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信