akonsu
akonsu

Reputation: 29566

do I have to use this.state in React to maintain component state?

I am unclear about the use of this.state in React components. While I can create this.state.myvar, why should not I just create this.myvar?

class MyComponent extends Component {
    state = {myvar: 123};

    render() {
        return <span>{this.state.myvar}</span>;
    }
}

or

class MyComponent extends Component {
    myvar = 123;

    render() {
        return <span>{this.myvar}</span>;
    }
}

I realize that there are helpers like this.setState, but at the end this.state is just a convenience, right? Or does it play a bigger role in React? Should I avoid setting properties directly on this to store my state? If so, why?

Upvotes: 0

Views: 408

Answers (2)

No, in fact; rather wrong.

this.state in a react component is a special React-backed container that is only acknowledged as having been updated when you use setState, which triggers a re-render, which might cause DOM updates (or not, depending on what React's diff algorithm sees happening in the JS virtual dom).

You can, of course, also use object properties bound to this, but changing them does absolutely nothing for the component itself. React doesn't look at your full component instance for changes, it only looks (internally) at the state, and (when changed by parents) at the props.

As such, you can't "create" things like this.state.myvar and then expect them to actually exist from lifecycle function to lifecycle function: as a special management construct, any values you tack onto state outside of proper this.setState(...) calls have undefined behaviour. They might exist, or they might not. If you really are working with the internal state, then you need to signal changes via this.setState({ myvar: value }).

Of course, that doesn't mean you can't use this.myvar, that'll work fine, but changing it will not "do" anything other than literally just that.

When would you use this.val instead of state? When your component has to perform operations that lead to an "intermediate" state, neither being one renderable state, nor the next. For instance, when code can update a state value multiple times between renders, during those changes your component is in an intermediate state, and so you don't want it to re-render. In fact, expecting it to can lead to huge bugs:

...
doTest() {
  this.setState({ val: this.state.val+1 });
  this.setState({ val: this.state.val+1 });
  this.setState({ val: this.state.val+1 });
},
...

This code will not yield a this.state.val that's 3 higher than before, because state updates are queued, and overwrite each other. Only the last instruction before a re-render "wins". So in that case you'd need something like:

...
doTest() {
  var localval = this.state.val;
  localval++;
  localval++;
  localval++;
  this.setState({ val: localval });
},
...

And then if we also need that value accessible outside of this function, then we finally have a legitimate use for a this property:

...
doTest() {
  this.accessibleval = this.state.val;
  this.updateValueAFewTimes();
  this.setState({ val: this.accessibleval });
},
...

Upvotes: 4

Justin Niessner
Justin Niessner

Reputation: 245449

this.state plays a larger role than you realize.

Setting state via this.setState triggers the component to re-render (among other things). Otherwise, React would have no way of knowing when something it depends on changed.

Upvotes: 2

Related Questions