在 React 中更新嵌套数组中的嵌套对象

Posted

技术标签:

【中文标题】在 React 中更新嵌套数组中的嵌套对象【英文标题】:Updating nested objects in nested arrays in React 【发布时间】:2019-11-02 00:06:40 【问题描述】:

预期效果:

点击按钮->调用函数save->将对象p传递给函数update 更新颜色数组中的第二个对象a: 'purple', desc: 'grt', date: '12 -10-2019 ',它位于products 数组中

更新前:a: 'purple', desc: 'grt', date: '12 -10-2019 '

更新后:a: 'violet', desc: 'gt', date: '12 -12-1980 '

console.log 中的错误:

Uncaught TypeError: this.props.product.colors.map is not a function

应用程序

class App extends Component 
  constructor (props) 
    super(props);
    this.state = 
      products: [  
            
                colors: [a:'orange', desc: 'grtrt',  date: '02-12-2019', a:'purple', desc: 'grt',  date: '12-10-2019']
                desc: 'gfgfg',

            ,
            
                colors: [a:'black', desc: 'g',  date: '12-12-2019',  a: 'white', a:'black', desc: 'grtrt',  date: '12-12-2119', , a:'gray', desc:'', date: '01-01-2000'],
                desc: 'gfgfgfg',

            
        ],
        selectProductIndex: 0 //It is first object in products array
        index: 1  //It is second object in colors array
    
  

  update = (item) => 
    const selectProductIndex = this.state;

    this.setState(prevState => 
      return 
        products: [
          ...prevState.products.slice(0, selectProductIndex),
          Object.assign(, prevState.products[selectProductIndex], colors: item),
          ...prevState.products.slice(selectProductIndex + 1)
        ]
      ;
    );
  

  render () 

    return (
        <div>
          <Items
            product=this.state.products[this.state.selectProductIndex] 
            update = this.update
          /> 
        </div>

    )
  

项目

class Items extends Component 


  render () 

    return (
      <ul>    
                   
              this.props.product.colors
                .map((item, index) => 
                  <Item
                    key= index
                    index = index
                    time = item
                    update = this.props.update        
                  />
                )
            
          </ul>   
      </div>      
    );
  

物品

class Item extends Component 

  save = () => 
    const p = 
      a:'violet', desc: 'gt',  date: '12-12-1980'
    

    this.props.update(p)
  



  render() 

    return (
      <div>
        <button onClick=this.save>Save</button>

      </div>
    )
  

【问题讨论】:

【参考方案1】:

您需要传递颜色项的索引,然后相应地更新它

class Item extends Component 

  save = () => 
    const p = 
      a:'violet', desc: 'gt',  date: '12-12-1980'
    

    this.props.update(p, this.props.index)
  



  render() 

    return (
      <div>
        <button onClick=this.save>Save</button>

      </div>
    )
  

然后在最顶层的父级

 update = (item, colorIndex) => 
    const selectProductIndex = this.state;

    this.setState(prevState => 
      return 
        products: [
          ...prevState.products.slice(0, selectProductIndex),
          Object.assign(, prevState.products[selectProductIndex], colors: prevState.products[selectProductIndex].colors.map((it,idx) => 
                if(idx === colorsIndex)  return item 
                return it;
          )),
          ...prevState.products.slice(selectProductIndex + 1)
        ]
      ;
    );
  

工作演示

const  Component  = React;
class App extends Component 
  constructor (props) 
    super(props);
    this.state = 
      products: [  
            
                colors: [a:'orange', desc: 'grtrt',  date: '02-12-2019', a:'purple', desc: 'grt',  date: '12-10-2019'],
                desc: 'gfgfg',

            ,
            
                colors: [a:'black', desc: 'g',  date: '12-12-2019', a:'black', desc: 'grtrt',  date: '12-12-2119', a:'gray', desc:'', date: '01-01-2000'],
                desc: 'gfgfgfg',

            
        ],
        selectProductIndex: 0,
        index: 1
    
  

   update = (item, colorIndex) => 
      const selectProductIndex = this.state;

      this.setState(prevState => 
        return 
          products: [
            ...prevState.products.slice(0, selectProductIndex),
            Object.assign(, prevState.products[selectProductIndex], colors: prevState.products[selectProductIndex].colors.map((it,idx) => 
                  if(idx === colorIndex)  return item 
                  return it;
            )),
            ...prevState.products.slice(selectProductIndex + 1)
          ]
        ;
      );
    

  render () 

    return (
        <div>
          <Items
            product=this.state.products[this.state.selectProductIndex] 
            update = this.update
          /> 
        </div>

    )
  


class Items extends Component 
  render () 

    return (
      <ul>    
                   
              this.props.product.colors
                .map((item, index) => 
                  <Item
                    key= index
                    index = index
                    time = item
                    update = this.props.update        
                  />
                )
            
          </ul>     
    );
  


class Item extends Component 

  save = () => 
    const p = 
      a:'violet', desc: 'gt',  date: '12-12-1980'
    

    this.props.update(p, this.props.index)
  



  render() 

    return (
      <div>
        <pre>JSON.stringify(this.props.time)</pre>
        <button onClick=this.save>Save</button>

      </div>
    )
  


ReactDOM.render(<App />, document.getElementById('app'));
<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>
<div id="app" />

【讨论】:

我只看到演示中的按钮。我在哪里可以看到结果?在 console.log 我什么都看不到

以上是关于在 React 中更新嵌套数组中的嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章

通过 React 中的输入元素更新对象中的嵌套状态

在 React/Redux reducer 中,如何以不可变的方式更新嵌套数组中的字符串?

如何使用不变性助手更新数组中的嵌套对象?

MongoDB - 基于嵌套数组的字段值更新数组对象中的字段

如何在 React 中使用 useReducer 更新嵌套对象?

更新 mongodb 中的嵌套数组