setState中的嵌套项(非变异)

问题描述 投票:0回答:1

我试图(没有变异状态)更新嵌套的值。

结果应该来自:[{ 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>
    );
  }
}
javascript reactjs
1个回答
1
投票

由于您正在更新一个也恰好有另一个嵌套数组的数组,您可以根据需要通过项目和传播道具来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>
© www.soinside.com 2019 - 2024. All rights reserved.