出现反应状态,但只能访问第一个数组

时间:2019-09-07 15:32:00

标签: javascript arrays reactjs state

我需要遍历嵌套在我的React State数组中的数组。我在开发工具中看到两个数组都填充了状态,当我使用Object.keys(this.state.products).map遍历父数组时,我得到了所有值。问题是,当我尝试循环遍历子数组或从子数组中提取任何值时,例如this.state.products [0] [3],我得到未定义的错误。

还有什么是什么,当我在ComponenetDidUpdate中console.log this.state.products [0] [3]时,我得到了值,就像React在设置状态,但不是一路走来吗?

const { Component } = React;

class App extends Component {
  state = { products: [] };

  componentDidMount() {
    this.apiSearch();
  }

  apiSearch = () => {
    // api call is made here
    const API = `http://localhost:5000/products`;
    fetch(API)
      // api response log
      // .then(response => console.log(response))
      .then(response => response.json())
      .then(data => {
        this.setState({ products: data }, () =>
          this.setState({ products: data })
        );
      })
      .catch(err => {
        console.log(err);
      });
  };

  render() {
    return (
      <div className="App">
        {<div>{typeof this.state.products[0]}</div>}
        
        {/* issue is here !!!! */}
        {<div>{typeof this.state.products[0][3]}</div>}
        {/* issue is here !!!! */}

        {this.state.products.forEach(function(element) {
          console.log(element);
        })}
        <br></br>
        Listings:
        {Object.keys(this.state.products).map((keyName, i) => (
          <li className="listingItem_Parent" key={i}>
            <span className="listingItem">
              {i} Name: {this.state.products[keyName]}
            </span>
          </li>
        ))}
        <br></br>
      </div>
    );
  }
}

ReactDOM.render(<App/>, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

我需要遍历处于状态的“产品”中的子数组,并像第一个数组中的map一样生成一个漂亮的列表。

3 个答案:

答案 0 :(得分:1)

render发生之前,将调用组件的fetch。那时,您的状态仅包含{ products: [] },因此自然this.state.products[0][3]会失败,因为此时this.state.products[0]尚未定义。您需要初始化状态以使this.state.products[0][3]有意义,或者更新render以便在this.state.products中没有任何内容时不会失败。

答案 1 :(得分:0)

有很多可能性。首先,检查控制台输出,很可能会收到警告,说明正在发生的事情。

首先,检查状态是否确实是数组,而不是错误或其他对象。

第二,您正在初始状态下显式检查某些内容(刚刚发布的其他答案表明了这一点)。

第三,确保在遍历列表时使用密钥/ ID,如果没有密钥/ ID,它可能无法工作(它会生成警告)。

//something like this
{ this.state.products.map( p => {
    return (<span key={p.id}>{p.name /*whatever*/}</span>) 
} )

基本上确保render方法可以处理所有数据,现在没有适当的检查来验证源,因此您可能会意外地使应用程序崩溃。高度怀疑硬编码索引。

答案 2 :(得分:0)

componentDidMount()在第一个渲染之后运行。因此,在执行首次返回时甚至还没有完成获取,这意味着this.state.products仍然是一个空数组。 此时,您正在对空数组执行操作。这就是为什么 this.state.products[0][3]将失败。

此刻:

this.state.products =[]
this.state.products[0] = undefined
this.state.products[0][3] -> error since you are checking for [3] of undefined. 

您需要检查数组是否为空,然后仅在数组不为空时执行操作。