Search code examples
javascriptreactjstypescriptecmascript-6setstate

Updating the state of a parent in child component in a immutable way


I have an array of objects with following properties.

columns = [
           {Header: ƒ, Cell: ƒ, sortable: false, show: true},
           {Header: ƒ, accessor: "firstName", sortable: false, show: true},
           {Header: ƒ, accessor: "status", sortable: false, show: true},
           {Header: ƒ, accessor: "visits", sortable: false, show: true}
          ]

This array of objects I am sending it to the child component and also a method that will be use to set the state of parent from child

Parent Component

<Child columns={this.props.child} handleSetState={this.handleSetState}/>

handleSetState = columns => {
    this.setState({ columns });
};


I have a dropdown component in the child component where I am showing checkboxes as options extracted from the props. Also I select some of the options and when I click on Apply , the property that matches the object should get updated and correspondingly the parents state

For Example on click of Apply , I form this array

value = ['firstName','status'];

So I need the parents state 'show' property should get updated to its inverted value. Basically show is used to show/hide columns

Child Component

  value = ['firstName','status'];
  submitSelection = () => {
    let updatedObj = this.props.columns.map((obj, i) => {
      if (obj.accessor === value[i]) {
        obj.show = !obj.show;
      }
      return obj;
    });
    this.props.handleSetState(updatedObj);
  };


On the first selection , I want the state should be updated as:

[
           {Header: ƒ, Cell: ƒ, sortable: false, show: true},
           {Header: ƒ, accessor: "firstName", sortable: false, show: false},
           {Header: ƒ, accessor: "status", sortable: false, show:false},
           {Header: ƒ, accessor: "visits", sortable: false, show: true}
]

I am unable to map the indices properly inside 'submitSelection()'. Is there a cleaner logic than can be implemented here?

Help would be appreciated


Solution

  • You can make your submitSelection function cleaner by writting it in this manner:

      values = ['firstName','status'];
    
      submitSelection = () => {
        const updatedObj = this.props.columns.map(o => 
          values.some(val => val === o.accessor) 
          ? { ...o, show: !o.show } 
          : {...o}
        );
        this.props.handleSetState(updatedObj);
      };