Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are state and props mutable?

Tags:

reactjs

Let's say I have a react component - a button - that increments a value when I click it.

For example

var Component = React.createClass({
    getInitialState: function() {
        return {count: 0}
    },

    increment: function() {
        this.setState({count: this.state.count + 1})
    },

    render: function() {
        return (<button onClick={this.increment}>{this.state.count}</button>);
    }
})

React.render(<Component />, document.getElementById('react-container'));

The state is mutable!

I can do a similar thing with props

var Component = React.createClass({
    increment: function() {
        this.setProps({count: this.props.count + 1})
    },

    render: function() {
        return (<button onClick={this.increment}>{this.props.count}</button>);
    }
})

React.render(<Component count={0}/>, document.getElementById('react-container'));

The state is mutable!

Some of the resources I have checkouted out say props are immutable, but then go and do something like setProps. The different resources keep contradicting each other. This is making it difficult for me to grasp the difference between state and props.

Are props mutable? If not why can I change them? It seems like changing props is not good practice, is this true? If yes, why does setProps exist?

like image 959
Ryan-Neal Mes Avatar asked Dec 02 '22 14:12

Ryan-Neal Mes


2 Answers

setProps is a holdover from the early days of React, and it's been deprecated for a long time now. You're correct, changing props from within the component isn't a good practice - think of them as like the arguments to a function. Rather than mutating props, you should either:

  • Use a callback prop to notify the parent that something has happened - the parent can then mutate the data it owns and pass it back into the child through props.
  • Make use of component state as you did in your first example.

What both of these solutions have in common is that a single component owns the data, and that's the only component that's allowed to modify it - this is commonly referred to as there being a 'Single Source of Truth'. The great thing about structuring your code this way is that it means that you don't get stuck in tangles of spaghetti code trying to work who's mutating a piece of data.

like image 31
Joe Clay Avatar answered Dec 06 '22 10:12

Joe Clay


this.props and this.state can be be mutated but this is really just a consequence of the mutability of objects in JS.

Your assertion that this.setState mutates the current state is false; a new object representing the state is created, with the changes applied.

To be honest I didn't even know that setProps existed but it sounds like a complete anti-pattern! The whole point of props is that they are passed through to the component, enforcing the unidirectional data flow. If the component can change its own props, this flow is broken.

You should really aim to store as much of your application state as possible at the top level i.e. in a store, rather than using component state. If all the state is in one place, it becomes a lot easier to reason about it.

like image 103
Tom Fenech Avatar answered Dec 06 '22 12:12

Tom Fenech