Search code examples
javascriptreactjsdestructuring

React hooks: How do I update state on a nested object with useState()?


I have a component that receives a prop that looks like this:

const styles = {
    font: {
        size: {
            value: '22',
            unit: 'px'
        },
        weight: 'bold',
        color: '#663300',
        family: 'arial',
        align: 'center'
    }
};

I'm trying to update the align property, but when I try to update the object, I wind up replacing the whole object with just the align property.

this is how I'm updating it:

const { ...styling } = styles;
const [style, setStyle] = useState(styling);

return (
        <RadioButtonGroup
            onChange={(event) => {
                setStyle({ ...style, font: { align: event.target.value } });
                console.log(style);
            }}
        />);

When I console.log style I just get {"font":{"align":"left"}} back. I expected to see the whole object with the updated value for align. I'm new to destructuring so what am I doing wrong here?


Solution

  • You need to use spread syntax to copy the font object properties too. Also while trying to update current state based on previous, use the callback pattern

    <RadioButtonGroup
      onChange={(event) => { 
        setStyle(prevStyle => ({
            ...prevStyle,
            font: { ...prevStyle.font, align: event.target.value }
        }));
        console.log(style);
      }}
    />