简体   繁体   English

根据对象数组中存在的属性设置状态:React + Typescript

[英]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. 我想根据对象数组中存在的属性在react中设置状态。

Code Sandbox that looks similar : https://codesandbox.io/s/sleepy-lamarr-0sbdz 看起来类似的代码沙箱: 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 . 这个提交函数在SelectComponent.tsx中以SubmitSelection()的形式出现,在该控制台中,控制台已记录问题的状态。 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". 现在,我需要基于“ 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". 我必须遍历“ selectedOptions”数组,然后基于每个对象的“值”(在这里我将其用作键),我需要在“列”中更新对象的相应“显示”属性。

In this example the columns array should look like after setstate : 在这个例子中,columns数组在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);
}

I'd make a map from selectedOptions let selectedOptionsMap = new Map(selectedOptions.map(option => [option.value, option])) 我会从selectedOptions制作一张地图, let selectedOptionsMap = new Map(selectedOptions.map(option => [option.value, option]))

Then update your function to: 然后将您的功能更新为:

checkboxSubmit = () => {
   let { selectedOptions , columns } = this.state;
   let selectedOptionsMap = new Map(selectedOptions.map(option => [option.value, option]))
    const updatedColumns = columns.map(column => (
      {...column, show: selectedOptionsMap.get(column.accessor) ? selectedOptionsMap.get(column.accessor).show : column.show}
    ))
    this.setState(columns: updatedColumns)
}

If you need the map for other calcs you can add it to the state. 如果您需要其他计算的地图,则可以将其添加到州。

ETA: Based on your code sandbox, here's the code for that function ETA:根据您的代码沙箱,这是该函数的代码

  submitSelection = () => {
    let showMap = new Map(this.state.optionsArr.map(option => [option.value, option.show]))
    let updatedColumns = this.props.data.map(column => (
      {...column, show: showMap.get(column.accessor) != null ? showMap.get(column.accessor) : column.show }
    ))
    this.props.handleSetState(updatedColumns)
  };

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. 我没有在SelectComponent中使用CheckBox数据结构数组,而是使用了映射的布尔数组(仅用于显示值)-这只是我的偏爱。

I think your previous problems were because you were passing the same Array instance to submitSelection. 我认为您之前的问题是因为您将同一Array实例传递给了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. React不了解应更新App,因为只有Array内部的对象已更改,而不是实际的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. 您可以通过在提交之前重新创建Array来使它起作用,但是在这种情况下,您将对SelectComponent中App.columns的值进行突变。 As you know, props aren't supposed to be modified, so this is bad. 如您所知,不应该修改道具,所以这很不好。

I think you may have confused your variables while mapping. 我认为您可能在映射时混淆了变量。 Try this. 尝试这个。

checkboxSubmit = () => {
  this.setState(({columns, selectedOptions}) => {
    const result = columns.map(col => {
      const op = selectedOptions.find(op => col.accessor === op.value);
      return { ...col, show: op.show }
    });
    return result;
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM