ReactJS不会按存储顺序打印数组吗?

时间:2018-08-10 19:59:28

标签: reactjs

我的reactjs代码有一个问题,其中render()函数不会按存储在状态对象中的顺序打印数组。

这是我的代码,非常简单:

import React from "react";

export default class DonationDetail extends React.Component {
  constructor(props) {
    super(props);
    this.state = { content: [] };
  }

  componentDidMount() {
    let state = this.state;
    state.content.push({ food: "burger" });
    state.content.push({ food: "pizza" });
    state.content.push({ food: "tacos" });
    this.setState(state);
  }

  addPaymentItem() {
    const item = { food: "" };
    let state = this.state;
    state.content.unshift(item);
    this.setState(state);
  }

  render() {
    console.log(this.state);
    let ui = (
      <div>
        <button type="button" onClick={() => this.addPaymentItem()}>
          add to top
        </button>
        {this.state.content.map((item, key) => (
          <input type="text" key={key} defaultValue={item.food} />
        ))}
      </div>
    );
    return ui;
  }
}

当按下按钮add to top时,新项目将放置在state.content数组的前面,您可以从console.log(this.state)语句中进行验证。但是不寻常的是,生成的HTML不会将此新项添加到用户界面输出的顶部。而是将另一个带有taco词的输入字段放在用户界面中列表的底部。

为什么ReactJS不按实际存储的顺序打印我的state.content数组?

2 个答案:

答案 0 :(得分:1)

当数组中元素的顺序不变时,您可以将数组索引用作key,但是将元素添加到数组的开头时,顺序会更改。

您可以在所有食物中添加唯一的id,然后将其用作key

示例

class DonationDetail extends React.Component {
  state = { content: [] };

  componentDidMount() {
    const content = [];

    content.push({ id: 1, food: "burger" });
    content.push({ id: 2, food: "pizza" });
    content.push({ id: 3, food: "tacos" });

    this.setState({ content });
  }

  addPaymentItem = () => {
    const item = { id: Math.random(), food: "" };
    this.setState(prevState => ({ content: [item, ...prevState.content] }));
  };

  handleChange = (event, index) => {
    const { value } = event.target;
    this.setState(prevState => {
      const content = [...prevState.content];

      content[index] = { ...content[index], food: value };

      return { content };
    });
  };

  render() {
    return (
      <div>
        <button type="button" onClick={this.addPaymentItem}>
          add to top
        </button>
        {this.state.content.map((item, index) => (
          <input
            type="text"
            key={item.id}
            value={item.food}
            onChange={event => this.handleChange(event, index)}
          />
        ))}
      </div>
    );
  }
}

ReactDOM.render(<DonationDetail />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>

答案 1 :(得分:0)

代替:

componentDidMount() {
  let state = this.state;
  state.content.push({ food: "burger" });
  state.content.push({ food: "pizza" });
  state.content.push({ food: "tacos" });
  this.setState(state);
}

尝试

componentDidMount() {
  this.setState(prevState => ({
    content: [
      ...prevState.content,
      { food: "burger" },
      { food: "pizza" },
      { food: "tacos" },
    ]
  }));
}

addPaymentItem() {
  const item = { food: "" };
  let state = this.state;
  state.content.unshift(item);
  this.setState(state);
}

addPaymentItem() {
  this.setState(prevState => ({
    content: [
      { food: "" },
      ...prevState.content,
    ]
  }));
}