Reputation: 806
I have a program where I have a menu that can toggle the view of any item on screen.
I was originally using useState
to toggle each individual component
example:
const [buttonA, setButtonA] = useState(false)
const [buttonB, setButtonB] = useState(false)
//...etc
This functioned correctly when implemented. However, now I've been tasked with using a single object to handle all keys from Props in a class component:
example:
layers:
{
propA: props.propA,
propB: props.PropB,
//..etc
}
I have also implemented a function to show or hide an element on screen. It takes the JSON key and updates the layer view based on the toggle.
showHideHandler = (key, value) => {
const newLayers = { ...layers };
newLayers[key] = value;
this.setState({ layers: newLayers });
};
I use this function in a modal to control the show/hide feature like this:
<Button
className={style.selector}
onClick={() => showHideHandler('propA', !layers.propA)}
> I AM PROP A
</Button>
Finally I am passing the prop values into a component like this for example:
{layers.propA ? (
<p> Visible </p>
):(
<p> Invisible</p>
)}
This toggle function works that I am able to show and hide element. However, the following problem is occurring.
When I first click on any button. The first thing that happens is that all the elements are hidden on the screen as if all the states are being set to hide. If I click the button a second time, the original component I want to hide shows the correct show hide action but all other items are still hidden.
I went back to check my toggle function const newLayers = { ...layers };
and made the following update to the newLayers const: const newLayers = this.setState.layers
showHideHandler = (key, value) => {
const newLayers = this.setState.layers;
newLayers[key] = value;
this.setState({ layers: newLayers });
};
This now returns the error must use restructuring state assignment
which shows the following error in the browser: Use callback in setState when referencing the previous state
I'm a bit stuck at this point and any help in the right direction would be greatly appreciated.
Upvotes: 0
Views: 1430
Reputation: 203587
It looks like a warning is informing you to use a functional state update.
showHideHandler = (key, value) => {
this.setState(prevState => {
// spread previous layers state into new object
const newLayers = { ...prevState.layers };
newLayers[key] = value;
return { layers: newLayers };
});
};
Or more succinctly
showHideHandler = (key, value) => {
this.setState(prevState => {
return {
layers: {
...prevState.layers,
[key]: value,
},
};
});
};
Upvotes: 1
Reputation: 1448
As @Red Baron said, const newLayers = this.setState.layers;
is non-sense.
You should mutate setState
's first argument (representing the previous state) to update your state :
const showHideHandler = (key, value) => {
this.setState((prevState) => ({
layers: {
...prevState.layers,
[key]: value,
}
}));
};
Upvotes: 1