【问题标题】:React State Appears but Only first array is accessible反应状态出现但只能访问第一个数组
【发布时间】:2020-01-10 02:33:11
【问题描述】:

我需要遍历一个嵌套在我的 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>

我需要遍历设置为 state 的“products”中的子数组,并生成一个很好的列表,就像第一个数组中的 map 一样。

【问题讨论】:

  • 感谢您提供 minimal reproducible example 来演示问题。我已让您的 Stack Snippet 可运行。下次你可以这样做:meta.stackoverflow.com/questions/338537
  • 虽然我刚刚注意到 fetch,但您需要将其替换为占位符才能使其真正可运行。
  • 抱歉,我的后端基本上是用两个数组填充状态:{ "products": [ [ 1, 1, "2019-09-06", "Tackle Amazon Machine Image", "ami" , 1000 ], [ 2, 1, "2019-09-06", "Tackle for GovCloud", "saas", 5000 ] }

标签: javascript arrays reactjs state


【解决方案1】:

componentDidMount() 在第一次渲染后运行。因此,在执行第一次 return 时甚至还没有完成获取,这意味着 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. 

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

【讨论】:

    【解决方案2】:

    有很多可能性。首先,检查控制台输出,您可能会收到一条警告,说明发生了什么。

    首先,检查状态是否真的是一个数组,而不是错误或其他对象。

    其次,您在初始状态下明确检查超出范围的内容(刚刚发布的另一个答案建议这样做)。

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

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

    基本上确保渲染方法适用于任何和所有数据,现在没有检查来验证源,因此您可能会遇到一些意外的应用程序崩溃。硬编码索引越界是高度可疑的。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-21
        • 1970-01-01
        • 1970-01-01
        • 2022-01-23
        • 2022-11-27
        • 1970-01-01
        • 1970-01-01
        • 2018-11-13
        相关资源
        最近更新 更多