我试图(没有变异状态)更新嵌套的值。
结果应该来自:[{ name: "hello", id:20, genre: [{ name: 'baz', id: 2 }, { name: 'foo', id: 200 }] }, { name: "hi", id:12, genre: [] }]
到[{ name: "hello", id:20, genre: [{ name: 'test', id: 2 }, { name: 'foo', id: 200 }] }, { name: "hi", id:12, genre: [] }]
我找到了我要更新的项目的index
-nestedIndex
。虽然,使用ID
匹配也会被发现(如果index
不是一个好主意)。
我试图在这里:
return item.name === x.name ? { ...item, name: e.target.value, genre[nestedIndex].name: 'test' } : item
如何更新setState中的嵌套项?
这是一个有效的例子:https://codesandbox.io/s/rl6yoyz1rm
这是我的完整代码:
state = {
search: "",
items: [{ name: "hello", id:20, genre: [{ name: 'baz', id: 2 }, { name: 'foo', id: 200 }] }, { name: "hi", id:12, genre: [] }]
};
onChange(e, x) {
const { items } = this.state
const index = items.findIndex(itm => itm.name === x.name)
const nestedIndex = [items[index]].map(e => e.genre).pop().findIndex(itm => itm.id === 2)
this.setState({
items: items.map(item => {
return item.name === x.name ? { ...item, name: e.target.value } : item
})
});
}
render() {
const { items } = this.state;
return (
<div>
{items.map((x) => {
return (
<div>
{" "}
{x.name}
{x.genre.map((itm) => {
return <i> {itm.name}</i>;
})}
<input onChange={e => this.onChange(e, x)} type="text" />
</div>
);
})}
</div>
);
}
}
由于您正在更新一个也恰好有另一个嵌套数组的数组,您可以根据需要通过项目和传播道具来map。
class App extends React.Component {
constructor() {
super()
this.state = {
items: [{
name: 'hello',
id: 20,
genre: [{ name: 'baz', id: 2 }, { name: 'foo', id: 200 }],
},
{ name: 'hi', id: 12, genre: [] },]
}
this.onChange = this.onChange.bind(this)
}
onChange(event, clickedItem) {
const { items } = this.state
const index = items.findIndex(item => item.name === clickedItem.name)
const nestedIndex = items[index].genre.findIndex(genre => genre.id === 2)
const { value } = event.target
this.setState(prevState => ({
items: prevState.items.map((item, itemIndex) => {
if (index !== itemIndex) {
return item
}
return {
...item,
genre: item.genre.map((genre, gIndex) => {
if (gIndex !== nestedIndex) {
return genre
}
return {
...genre,
name: value,
}
})
}
})
}))
}
render() {
const { items } = this.state;
return (
<div>
{items.map((x) => {
return (
<div>
{" "}
{x.name}
{x.genre.map((itm) => {
return <i> {itm.name}</i>;
})}
<input onChange={e => this.onChange(e, x)} type="text" />
</div>
);
})}
</div>
);
}
}
ReactDOM.render(
<App />,
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>