Search code examples
javascriptreactjstypescriptecmascript-6setstate

Set state based on an a property present in array of objects : React+Typescript


I want to set state in react based on property that is present in the array of objects.

Code Sandbox that looks similar : https://codesandbox.io/s/sleepy-lamarr-0sbdz

This submit function is present as submitSelection() inside SelectComponent.tsx where I have console logged the state in the question . It is identical

I have a state object that looks this like this:

this state = {
               columns : [
                          {Header: ƒ, accessor: "firstName",show: true},
                          {Header: ƒ, accessor: "status", show: true},
                          {Header: ƒ, accessor: "visits", show: true}
                         ]
             }

I have list of checkboxes that displays column names and based on the "show" flag I hide/show them. I create one more of array of objects based on checkboxes selection that something looks like:

this.state = { 
              selectedOptions: [
                                {name: "firstName", value: "firstName", show: true},
                                {name: "status", value: "status", show: false},
                                {name: "visits", value: "visits", show: true}
                                ]
            } 

Now I need to set the state of "columns" based on the value of "selectedOptions". I have to iterate through the "selectedOptions" array and then based on "value"(here I am using it as key) of each object, I need to update the corresponding "show" property of an object in the "columns".

In this example the columns array should look like after setstate :


columns : [
            {Header: ƒ, accessor: "firstName",show: true},
            {Header: ƒ, accessor: "status", show: false}, // because the value for this in selectedOptions is true
            {Header: ƒ, accessor: "visits", show: true}
          ]


I used the following approach, but it did not work


checkboxSubmit = () => {
   let { selectedOptions , columns } = this.state;
    const updatedObj = columns.map(object =>
      value.some(columns => columns.value === object.accessor)
        ? { ...object, show: columns.show  }
        : { ...object }
    );
    this.setState(columns: updatedObj);
}


Solution

  • Here's my solution.

    Instead of using a CheckBox data-structure Array in SelectComponent, I used a mapped Array of booleans (just for the show values) - this is just my preference.

    I think your previous problems were because you were passing the same Array instance to submitSelection. React doesn't understand that App should be updated, because only the objects inside the Array have been changed, instead of the actual Array.

    You could probably get it to work by just recreating the Array before submitting, but in this case you'd be mutating the values of App.columns in SelectComponent. As you know, props aren't supposed to be modified, so this is bad.