无法更新状态内的嵌套对象

Posted

技术标签:

【中文标题】无法更新状态内的嵌套对象【英文标题】:Unable to update a nested object within state 【发布时间】:2020-05-22 03:50:25 【问题描述】:
import React,  Component  from 'react';
import ColorBox from './ColorBox'
import './ColorBoxes.css'

class ColorBoxes extends Component 
    state =  
        colors: 
    

    clickedColor = (color) => 
        let newColor = this.randomColorGenerator()
        if (color !== newColor) 
            console.log('i am changing state', newColor)
            console.log(color, 'i am current color')
            console.log(this.state.colors)

            const colors = this.state
            this.setState(
                colors: 
                    ...colors,
                    [color]: newColor
                
            )
        

    

    randomColorGenerator = () => 
        let randomColor = '#'+Math.floor(Math.random()*16777215).toString(16)
        return randomColor
    

    renderColors = () => 
        let colors = []
        colors = Object.keys(this.state.colors)
        return colors.map(c => 
        <div key=c><ColorBox color=c clickedColor=this.clickedColor/></div>)
    

    componentDidMount() 
        let colorKey
        let colors = 
        for(let i=0; i < 21; i++) 
            colorKey = this.randomColorGenerator()
            colors[colorKey] = colorKey

        
        this.setState( colors: colors  );
    
    render()  

        return ( 
            <div className="ColorBoxes">
                this.renderColors()
            </div>
        );
    

export default ColorBoxes;

子组件

import React from 'react';
import './ColorBox.css'

const ColorBox = (props) => 
    return <div className='ColorBox' 
    style=backgroundColor: `$props.color`
    onClick=() => props.clickedColor(props.color)>
        props.color
    </div>


export default ColorBox;

编辑,我已经尝试了提出的解决方案,但是状态已更新,基于反应开发人员工具,但组件没有重新渲染。我怀疑密钥也必须更改才能重新渲染,但我不知道如何在状态下执行此操作 我想做的是取旧密钥并将其替换为正在更新的相同颜色。

我有这个颜色对象处于状态,它包含颜色的键:值对,例如颜色:#fff:#fff,#bbb:#bbb。我将一个函数向下传递给一个子组件,这样当我单击一种颜色时,它将返回该颜色,这是我在状态对象中的键,然后我想找到该键并将该键值更新为新的随机颜色将被选中。我无法访问该密钥。我怎么做?理想情况下,我可能想删除该键并将键和值更新为在我的状态对象中相同。

【问题讨论】:

this.randomColorGenerator() 返回什么? 你是如何使用这个状态的?你能展示你的渲染和子组件吗? 【参考方案1】:

假设您的状态如下所示:

colors: 
  #fff: '#fff',
  #000: '#000'

然后只需将您的setState 更新为

const colors = this.state
setState(
  colors: 
    ...colors,
    [color]: newColor
  
)

问题是您将新颜色状态附加到颜色对象之外

【讨论】:

【参考方案2】:

您缺少color 的括号。您需要一个方括号来设置对象上的动态键:

this.setState(prevState => (  
  ...prevState.colors,
  [color]: newColor,                    
));

希望这会有所帮助!

【讨论】:

【参考方案3】:

你可以这样做:

class ColorBoxes extends Component 
    state =  
        colors: 
    

    clickedColor = (color) => 
        let newColor = this.randomColorGenerator()
        if (color !== newColor) 
            console.log('i am changing state', newColor)
            console.log(color)
            console.log(this.state.colors.color)
            let newColors = ...this.state.colors;
            newColors.color = newColor;
            this.setState( colors: newColors )
       
    

【讨论】:

以上是关于无法更新状态内的嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose - 无法更新深度嵌套对象

无法使用嵌套值设置 Apollo 本地状态

在 React 上下文中更新嵌套状态的最佳方法

React:使用 Hooks 为深度嵌套对象设置状态

更新状态 |对象不可迭代(无法读取属性 Symbol(Symbol.iterator))

Vuex getter无法更新状态更改