I am trying to get states from multiple checkbox child components to one parent component.
I attached the link here
Checkbox states of each child components working okay and checkbox also changes accordingly.
However when I try to send those states up and integrate inside of parent component, it does not work as I expected.
I want to combine those states as an object literal inside of parent state according to toggle state.
For instance, when all vegetable and some of Languages are checked, I want to set state in parent component like below.
{
Vegetables-Carrot: true,
Vegetables-Potato: true,
Vegetables-Tomato: true,
Languages-EN: true,
Languages-ESP: true,
}
On the other hand, when Vegetables options are unchecked, I want to remove those options in parent state or make values to false.
{
Languages-EN: true,
Languages-ESP: true,
}
or
{
Vegetables-Carrot: false,
Vegetables-Potato: false,
Vegetables-Tomato: false,
Languages-EN: true,
Languages-ESP: true,
}
I thought it would work out with proper use of prevState inside of setState but it only add unnecessary options whenver checkboxes are toggled.
{
Vegetables-Carrot: true,
Vegetables-Potato: true,
Vegetables-Tomato: true,
Languages-EN: true,
Languages-ESP: true,
Vegetables-Carrot: true,
Vegetables-Potato: true,
Vegetables-Tomato: true,
}
Many hours of trying but no progress at all. How can I manipulate those states inside of parent component?
CodePudding user response:
You can pass down a setState function, and all you need to do is to make sure to create a new object and toggle the state for a specific checkbox.
Parent component
const [states, setStates] = useState({});
<CheckboxComp func={setStates} name="Vegetables-Tomato"/>
now in your Checkbox you can flip the state
CheckboxComp :
export default function CheckboxComp({func, name}){
const toggleFunc = useCallback(() => func(states => {...states, name: !states[name] ?? true}, [])
return (
<input type="checkbox" onChange={toggleFunc}/>
)
}
CodePudding user response:
The simplest solution for your example would be to only have state management under App
component like in this solution.
You could have 2 states, one in App
and the other in MyCheckbox
but this would require you to change a little bit the logic under MyCheckbox
like this:
// instead of doing this
useEffect(() => {
onChangeData(selected);
}, [ selected ]);
// you should be updating `selected` state based on a property
// here named `value` and directly call `onChangeData` in `handleChange`
useEffect(() => {
setSelected(value);
}, [ value ]);
But doing this kind of approach tends to create issues of re-rendering and needs to be extra careful. So, when possible, it's best to avoid having 2 states to synchronize.