开发者问题收集

TypeError:无法读取 null 的属性状态

2018-11-29
1193

我无法从州外获取数据并对其应用映射函数。我一直收到

TypeError: Cannot read property 'financials' of null.

axios 获取以下对象,{symbol: "AAPL", financials: Array(4)},这就是我使用 this.state.financials.financials 的原因

class Fundamentals extends Component {
  state = {
    financials: null,
    headers: null
  };

  async componentDidMount() {
    console.log("componentDidMOunt");
    await axios
      .get("https://api.iextrading.com/1.0/stock/aapl/financials?period=annual")
      .then(res => {
        const financials = res.data;
        this.setState({ financials });
        console.log(financials);
      });

    console.log("componentDidMount finished setting the data for the table");
  }

  render() {
    // const headers = this.getHeaders1();
    return (
      <GridContainer>
        <GridItem xs={12} sm={12} md={12}>
          <Card>
            {this.state.financials.financials.map(items => items)} <-- i want to get the data out of state and later put it into a table. 
          </Card>
        </GridItem>
      </GridContainer>
    );
  }
}
3个回答

组件首次呈现时, this.state.financialsnull ,因为您使用 null 对其进行初始化:

state = {
  financials: null,
  headers: null
};

这就是您收到该错误的原因。下面是一个重现该错误的简单示例:

var state = {
  financials: null,
};

state.financials.financials.map(() => {});

您需要在呈现方法中检查值是否已设置,如果没有设置,则不执行任何操作:

render() {
  // const headers = this.getHeaders1();
  if (!this.state.financials) {
    return null; // or some message that the data is loading
  }

  return (
    <GridContainer>
      <GridItem xs={12} sm={12} md={12}>
        <Card>
          {this.state.financials.financials.map(items => items)} <-- i want to get the data out of state and later put it into a table. 
        </Card>
      </GridItem>
    </GridContainer>
  );
}

或者,您可以改用 {financials: []> 对其进行初始化:

state = {
  financials: {financials: []},
  headers: null
};

然后, render 中的现有代码应该可以“工作”(见下文)。


但仅凭这一点可能不会让您的组件正常工作。您还需要将 this.state.financials.financials 中的条目实际转换为 React 可以呈现的内容。以下是提取日期的示例:

this.state.financials.financials.map(item => item.reportDate)

根据您的需要进行调整。

Felix Kling
2018-11-29

该错误是因为 React 尝试在 API 调用完成之前进行渲染,在这种情况下 this.state.financials 仍被分配了其初始 null 值。

更改 financials 的默认值,如下所示

state = {
    financials: { financials: [] },
    headers: null
};

因此最终代码看起来像

class Fundamentals extends Component {
  state = {
    financials: { financials: [] },
    headers: null
  };

  async componentDidMount() {
    console.log("componentDidMOunt");
    await axios
      .get("https://api.iextrading.com/1.0/stock/aapl/financials?period=annual")
      .then(res => {
         const financials = res.data;
         this.setState({ financials });
         console.log(financials);
      });

      console.log("componentDidMount finished setting the data for the table");
   }

   render() {
     // const headers = this.getHeaders1();
     return (
       <GridContainer>
         <GridItem xs={12} sm={12} md={12}>
           <Card>
             {this.state.financials.financials.map(items => items)} <-- i want to get the data out of state and later put it into a table. 
           </Card>
         </GridItem>
       </GridContainer>
     );
  }
}
Revanth M
2018-11-29

在实际呈现数据之前添加检查。

class Fundamentals extends Component {
  state = {
    financials: null,
    headers: null
  };

  async componentDidMount() {
    console.log("componentDidMOunt");
    await axios
      .get("https://api.iextrading.com/1.0/stock/aapl/financials?period=annual")
      .then(res => {
        const financials = res.data;
        this.setState({ financials });
        console.log(financials);
      });

    console.log("componentDidMount finished setting the data for the table");
  }

  render() {
    const { financials: { financials} } = this.state;

    if(!financials || (financials && !financials.length) {
      return (
        <LoaderComponent />
      )
    }

    return (
      <GridContainer>
        <GridItem xs={12} sm={12} md={12}>
          <Card>
            {financials.map(items => items)} <-- i want to get the data out of state and later put it into a table. 
          </Card>
        </GridItem>
      </GridContainer>
    );
  }
}
sridhar
2018-11-29