繁体   English   中英

映射到 state: (TypeError): this.state.[something].map 不是 ZC1C4145Z7E1783

[英]Mapping through state: (TypeError): this.state.[something].map is not a function

我正在尝试通过我的 state 进行 map,我从外部 API 收集了数据。

但是,当我这样做时,我在这里收到此错误: TypeError: this.state.stocks.map is not a function

我想通过 function 将结果呈现到前端,以便该站点对 state.favorites 是动态的。 通过 console.log(),我可以看到数据存储在 state 中。

我发现其他人有类似的问题,但答案没有解决。

更新:我已经更改了 componentDidMount(),它现在生成了一个数组。 问题是我没有从 renderTableData() 函数中得到任何渲染。

console.log 显示了这个数组:

0: {symbol: "ARVL", companyName: "Arrival", primaryExchange: "AESMSBCDA)LNKOS/ TLTE(N GAEQLGAR ", calculationPrice: "tops", open: 0, …}
1: {symbol: "TSLA", companyName: "Tesla Inc", primaryExchange: " RNK EAASGTDACLN)LE/OGMELAQSTB (S", calculationPrice: "tops", open: 0, …}
2: {symbol: "AAPL", companyName: "Apple Inc", primaryExchange: "AMTGS/C) AALGDRSTNLEOEL(S BAE NQK", calculationPrice: "tops", open: 0, …}
length: 3
__proto__: Array(0)

这是我的代码:

import React, { Component } from 'react'
import './Table.css';


class Table extends Component {
  constructor (props) {
     super(props);
      this.state = {
         favorites: ['aapl', 'arvl', 'tsla'],
         stocks: []
     };
 }

  componentDidMount() {
   this.state.favorites.map((favorites, index) => {
   fetch(`API`)
       .then((response) => response.json())
       .then(stockList => {
         const stocksState = this.state.stocks;
         const stockListValObj = stockList;
         console.log(stocksState)
         console.log(stockListValObj)
         this.setState({
            stocks: [
                ... stocksState.concat(stockListValObj)
            ]
          }, () => { console.log(this.state.stocks);});
      })
   })
 }


renderTableData() {
    this.state.stocks.map((stocks, index) => {
      const { companyName, symbol, latestPrice, changePercent, marketCap } = stocks //destructuring
      return (
        <div key={symbol} className='headers'>
          <div className='first-value'>
            <h4>{companyName}</h4>
            <h4 className='symbol'>{symbol}</h4>
          </div>
          <div className='align-right'>
            <h4>{latestPrice}</h4>
          </div>
          <div className='align-right'>
            <h4 className='changePercent'>{changePercent}</h4>
          </div>
          <div className='align-right'>
            <h4>{marketCap}</h4>
          </div>
        </div>
      );
   })
}


   render() {
      return (
         <div className='table'>
            <h1 id='title'>Companies</h1>
            <div className='headers'>
              <h4 className='align-right'></h4>
              <h4 className='align-right'>Price</h4>
              <h4 className='align-right'>+/-</h4>
              <h4 className='align-right'>Market Cap</h4>
            </div>

            <div>
              {this.renderTableData()}
            </div>

         </div>
      )
   }
 }

export default Table;

我会说这是因为在第一次渲染时,map 会查看 state.stock 并且它是一个空数组。 在第一次渲染之后,调用 componentDidMount 方法来获取数据。

我建议将 map 包装成一个条件。 如果库存没有任何 object,则返回您想要的任何内容(例如 null 或加载器/微调器)。

像这样添加它就足以在数组为空的情况下不返回任何内容(它将在第一次渲染后填充,但这对于在获取失败时返回错误消息也很有用):

this.state.stocks.length > 0 && this.state.stocks.map((stocks, index) => {

您应该始终致力于进行单个 state 更新,尝试将 state 更新减少为单个更新。

我建议2个解决方案:

  1. 将数据获取部分移动到单独的 function 中,更新一个临时数组变量,在执行结束时返回该变量。

  async dataFetch() {
    const sampleData = this.state.stocks || [];
    await this.state.favorites.forEach((favorites, index) => {
      fetch(`API`)
        .then((response) => response.json())
        .then((stockList) => {
          sampleData.push(stockList);
          // const stocksState = this.state.stocks;
          // const stockListValObj = stockList;
          // console.log(stocksState);
          // console.log(stockListValObj);
          //  this.setState({
          //     stocks: [
          //         ... stocksState.concat(stockListValObj)
          //     ]
          //   }, () => { console.log(this.state.stocks);});
        });
    });
    return Promise.resolve(sampleData);
  }

  componentDidMount() {
    this.dataFetch().then((stockValues) => {
      this.setState({ stocks: stockValues });
    });
  }

  1. 使用Promise.all()这将返回单个数组值,这将更容易更新到库存 state。

建议:当不从数组返回任何值时,尝试使用Array.forEach而不是Array.map

renderTableData中缺少返回关键字

renderTableData() {
    this.state.stocks.map((stocks, index) => { ...});

renderTableData() {
   return this.state.stocks.map((stocks, index) => { ...});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM