0
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;

Child Component

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;

edit, I have tried the solutions proposed, however the state is updated, based on react developer tools, but components are not re-rendering. I suspect the key also has to change for a re-render, but I am not aware of how to do that in state What I would like to do is take the old key and replace it with the same color that's being updated.

I have this colors object in state, it holds key: value pairs of colors, for example colors: {#fff: #fff, #bbb: #bbb}. I am passing a function down to a child component so that when I click on a color it will return that color which is my key in the state object, I want to then find that key and update that keys value to the new random color that will be chosen. I am unable to access that key. How do I do that? Ideally I would possibly like to delete that key and update both the key and value to be the same in my state object.

Altaf
  • 399
  • 1
  • 5
  • 15

3 Answers3

2

You are missing brackets for color. You need a square brackets to set the dynamic key on the object:

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

Hope this helps!

Yash Joshi
  • 2,586
  • 1
  • 9
  • 18
2

assuming your state looks like this:

colors: {
  #fff: '#fff',
  #000: '#000'
}

then just update your setState to

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

the problem was you were appending your new colors state outside of the colors object

Lelouch
  • 910
  • 6
  • 19
1

You can do it this way:

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 })
       }
    }
Muhammad Zeeshan
  • 4,608
  • 4
  • 15
  • 41