I've created a React component with an array state state.colors
that contains three hex values (initial state is ['#aaaaaa', '#aaaaaa', '#aaaaaa']
). Each value in the state.colors
array can be updated using color pickers. As a test, I've updated the first color to red, second to green, and third to blue. This works as expected in a class component (as shown in the screenshot below).
class EditArtworkClass extends React.Component {
constructor(props) {
this.state = {
colors: initialPalette
};
}
setColor(index, hex) {
const clonedColors = _.clone(this.state.colors);
clonedColors[index] = hex;
this.setState(
{
colors: clonedColors
},
() => {
console.log("updated");
}
);
}
// other code here
}
Class Component - Before choosing colors:
Class Component - After choosing colors (state.colors
have the correct hex values):
However, I am facing an issue when using a functional component. Every time I update a color using the color picker, all other values in the colors
state array are reset to the initial value (#aaaaaa
). If I set the first color to red, second to blue, and third to green, only the last value in the colors
array will have the correct hex since the other two values are reset to #aaaaaa
when updating the third color.
export default function EditArtworkFunctional() {
const [colors, setColors] = useState(initialPalette);
const setColor = (index, hex) => {
const clonedColors = _.clone(colors);
clonedColors[index] = hex;
return clonedColors;
};
// Other code here
}
Functional Component - Before choosing colors:
Functional Component - After choosing colors (only the last color I pick has a correct hex in the state):
Note that the color picker is an uncontrolled component and will display the colors you pick, not the color in the colors
state array.
I have created a reproducible mini-app in the Codesandbox Link below.
Condesandbox Link: https://codesandbox.io/s/class-vs-functional-component-array-state-8lnzd
I have zero ideas as to why this is happening, so any help or guidance would be greatly appreciated .
UPDATE: I've fixed the problem using @TalOrlanczyk's answer. The trick was to retrieve the previous state using the optional parameter when updating. You can view the CodeSandbox repo of the working version here.