简体   繁体   English

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

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

I'm trying to map through my state, where I have collected data from an external API.我正在尝试通过我的 state 进行 map,我从外部 API 收集了数据。

However, when I do i get this error here: TypeError: this.state.stocks.map is not a function但是,当我这样做时,我在这里收到此错误: TypeError: this.state.stocks.map is not a function

I want to render the results to the frontend, through a function so that the site is dynamic to the state.favorites.我想通过 function 将结果呈现到前端,以便该站点对 state.favorites 是动态的。 Though the console.log(), I can see that the data is stored in the state.通过 console.log(),我可以看到数据存储在 state 中。

I have found others with a similar issue, but the answers did not work out.我发现其他人有类似的问题,但答案没有解决。

UPDATE: I have changed the componentDidMount() and it now produces an array.更新:我已经更改了 componentDidMount(),它现在生成了一个数组。 The issue is that I get no render from the renderTableData() functions.问题是我没有从 renderTableData() 函数中得到任何渲染。

console.log shows this array: 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)

This is my code:这是我的代码:

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;

I would say that this is happening because on the first render, the map looks into state.stock and it's an empty array.我会说这是因为在第一次渲染时,map 会查看 state.stock 并且它是一个空数组。 After the first render, the componentDidMount method is called fetching the data.在第一次渲染之后,调用 componentDidMount 方法来获取数据。

I would suggest to just wrap the map into a condition.我建议将 map 包装成一个条件。 If stock doesn't have any object, then return whatever you wish (null or a loader/spinner for example).如果库存没有任何 object,则返回您想要的任何内容(例如 null 或加载器/微调器)。

It's enough to add it like this for not returning anything in case the array is empty (it will be filled after the first render, but this is useful as well to return error message in case the fetch fails):像这样添加它就足以在数组为空的情况下不返回任何内容(它将在第一次渲染后填充,但这对于在获取失败时返回错误消息也很有用):

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

You should always aim in making single state update, try reducing the state update to single update.您应该始终致力于进行单个 state 更新,尝试将 state 更新减少为单个更新。

I suggest 2 solution:我建议2个解决方案:

  1. Move the data fetch section into a separate function, update a temporary array variable return the variable at the end of the execution.将数据获取部分移动到单独的 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. Use Promise.all() this return a single array value which would be easier to update on to the stock state.使用Promise.all()这将返回单个数组值,这将更容易更新到库存 state。

Suggestion: When not returning any values from the array try using Array.forEach instead of Array.map建议:当不从数组返回任何值时,尝试使用Array.forEach而不是Array.map

Return keyword is missing in renderTableData renderTableData中缺少返回关键字

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

to

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

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

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