Home > Enterprise >  How can I get separated states from multiple child components in React.js?
How can I get separated states from multiple child components in React.js?

Time:06-25

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.

  • Related