Javascript &引用;无法读取未定义的属性";在抓取和等待后进行响应

Javascript &引用;无法读取未定义的属性";在抓取和等待后进行响应,javascript,json,reactjs,fetch,Javascript,Json,Reactjs,Fetch,我是React的新手,在获取时遇到问题: 我在react做了一个项目,根据用户选择的公司,我必须从五个不同的URL中获取。 我已经更改了很多次代码,但都不起作用 我尝试使用componentDidMount(但它只被调用一次,我想获取许多URL),使用“while(!this.state)”忙着等待获取数据,然后再对其进行签名,等等 提取功能: async fetch_data() { var sel = this.props.select; symbol = companies

我是React的新手,在获取时遇到问题:

我在react做了一个项目,根据用户选择的公司,我必须从五个不同的URL中获取。 我已经更改了很多次代码,但都不起作用

我尝试使用componentDidMount(但它只被调用一次,我想获取许多URL),使用“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();    
  }
设置值函数(经过修剪,因此不会太长):

渲染函数(也经过修剪):


应用程序并不总是崩溃,它会显示结果,但渲染组件一直在调用它。fetch_data(),它崩溃是因为有时(比如80%的时候)数据还没有到达,我试图访问它。

我想这是因为你调用了这个。fetch_data();内部渲染() 这意味着,首先,您的状态中没有数据,在有数据之后,您正在更新组件,因此您会一次又一次地调用this.fetch_data()

查看React组件生命周期:


另一件事是不需要编写while(),因为您使用的是async wait。

出现此问题的原因是。在您的情况下,这意味着此处所做的状态更改:

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

/* The state change will be observable when setValues() is called via
the callback */
this.setState({data: data, loading: false }, () => {

    this.setValues();    
});

作为组件实现的建议,考虑修改<代码> RANDER()>代码>方法,以便在<代码> ReDead()/<代码>中直接访问和呈现< <代码>日期>代码>、<代码>打开/代码>和<代码>更高版本>代码>,而不是像您正在做的那样缓存其他值。因此,请尝试以下方法:

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>
      );
    }
  }
render(){
此函数为.fetch_data();
if(this.state.loading | | |!this.state | |!this.state.data){
返回装载:D。。。
}否则{
/*不再需要调用setValues()*/
const day=this.state.data[“元数据”][“3.上次刷新”];
const open=this.state.data[“时间序列(每日)”][日期][“1.open”];
const higher=this.state.data[“时间序列(每日)”][日期][“2.high”];
返回(
符号:{Symbol}
Url:{Url}

  • 开盘价:{Open}
  • 更高的价格:{更高}
); } }
我找到了一个解决方案:


只需在render中的return之前放一个if语句,说“符号是否已更改?如果是,请获取,否则不要”

您可以在(!data)时删除
wait
关键字将确保在调用
setState
之前为
data
分配一个值。尝试将this.setValues()替换为requestAnimationFrame(this.setValues())它也不起作用:(我已经按照您所说的修改了函数render,但它以相同的方式崩溃:(你能提供你的
fetch()
请求返回的json响应的副本吗?然后我该怎么做才能在变量“symbol”改变其值时调用函数fetch?谢谢你的回答“symbol是否改变了”是什么意思?你使用了什么方法/解决方案?我的项目中也有同样的问题。
this.setState({data: data, loading: false });
/* The state change will be observable when setValues() is called via
the callback */
this.setState({data: data, loading: false }, () => {

    this.setValues();    
});
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>
      );
    }
  }