3

I am learning react and trying to understand how to better deal with updating state of a component with arrays. Here is the function I call on componentWillMount() of a component to generate components that I render later in this parent component:

  generateThings = () => {
    let newThings = [];
    for (let j = 0; j < this.state.numberOfThings; j++) {
      const pos = this.generatePosition(1, 1);
      const thingComp = <Thing key={j} position={pos} />;
      newThings.push(thingComp);
    }
    this.setState({
      things: newThings
    });
  };

I thought a better way would be to push() to the state field directly (this.state.things.push(thingComp);) instead of the storing in a temp variable which seems messier. But that doesn't seem to trigger a UI update, so I'm guessing this is the way to do it, but i'm not sure.

Sammy Guergachi
  • 1,986
  • 4
  • 26
  • 52
  • 1
    You could push to the state directly and use the functional `setState` syntax instead. EG: `this.setState((prevState) => { prevState.things.push(...); return prevState; })`. Just note that mutating state outside of a `setState` call won't trigger an update. – CRice Dec 28 '17 at 22:05
  • Duplicated of https://stackoverflow.com/q/26253351/4333038 – Cristóvão Trevisan Dec 28 '17 at 22:07

2 Answers2

2

What you are doing is correct.

When you call setState, it causes the components to rerender: According to React Docs

setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

If you need to update/push to the existing things array:

let things = this.state.things.slice(); // make a copy

//push or do whatever to the array
things.push(thingComp)

this.setState({ things: newThings });
Sumama Waheed
  • 3,579
  • 3
  • 18
  • 32
0

In addition, if you want, you can set the state without pushing and slicing to a different array.

CodeSandbox: https://codesandbox.io/s/jn8w8w34n3

the additional array solution is commented

Tomas Eglinskas
  • 845
  • 2
  • 12
  • 25