我的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
数组?
答案 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,
]
}));
}