简体   繁体   中英

In React how can I set state variables in a loop?

I have a number of state variables (I am only showing 3):

class IntroductionPage extends React.Component<SomePageProps, {inId: string,
  i1: string,
  i2: string
}> {
  constructor(props: any) {
    super(props);
    this.state = {inId:'',
      i1:'',
      i2:''
    };
  }

and I am reading key-value pairs from a DB:

+------------+------------+------------+
| start_type | field_name | start_text |
+------------+------------+------------+
| 0          | i1         | hi         |
+------------+------------+------------+
| 0          | i2         | it's me!   |
+------------+------------+------------+
| 0          | i3         | Schoon     |
+------------+------------+------------+


for (var key in response.data) {
  var dat = response.data[key];
  getStartType=dat['start_type']//JSON.stringify(dat['start_type']);
  for (var inner_key in dat) {
    console.log('key=' + inner_key + ' value=' + dat[inner_key]);
  }

gives

key=start_type value=0
key=field_name value=i1
key=start_text value=hi
...

Now is there any way I can loop through these retrieved value and set state, for example something like a loop or map version of this:

this.setState({dat['field_name']:dat['start_text']});

so the first row returned would be fieldname= i1, start_text ='hi' and so the loop would setState ({i1:'hi'}) ?

React Docs:

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be >batched for performance gains

don't call setState in a loop, just update a local variable inside aloop and then call the setSate method on that variable it will save you some rerenders

As a technical question of "can I do this?" the answer is "Yes". It is ok to call setState inside a loop in your example because each state update is independent of each other and does not rely on previous values of the state. React will likely batch the setState updates together so that you won't have multiple re-renders.

for (var key in response.data) {
  var dat = response.data[key];
  this.setState({ [dat.field_name]: dat.start_text });
}

You use brackets around [dat.field_name] because it is a variable property key. But variable property names are a problem for Typescript because it assumes that they are string instead of a valid key.


I would probably do what @Sharon Geller suggests and call setState once with a combined value.

const changes = response.data.reduce(
  (acc, curr) => ({ ...acc, [curr.field_name]: curr.start_text }),
  {}
);
this.setState(changes);

Technically this doesn't require an assertion because the type of changes is the empty object {} , but you might want to assert a type on the initial value {} as State .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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