Remember when we looked at different ways of creating React component in the first page of this tutorial, we said there are things that component extending can do that a function component cannot do? Well state is one of them. React.Component can have states but function cannot have states.

    Note: There's a new feature in React called hooks that let's us use state within function component but that's still in alpha so if we want to use state right now on a component we still need to use React.Component

    Below is a simple component that has a state.

    state is just an object. If you notice the constructor, we initialized the state with {counter: 0}. And we used the state inside the return of the render function as {this.state.counter}.

    We initialized the state in the constructor but how do we update it? For eg. in the above example how do we change the counter to lets say 1? For that React provides a function called setState. You should always use setState function to change state and never mutate it directly.

    1. //❌ NEVER DO THIS
    2. this.state.counter = 2;
    3.  
    4. // ✅ ALWAYS DO THIS
    5. this.setState({
    6. counter: 2

    Let's look deeper into setState function. First argument of setState function can take either a new state object or a function. It also has a optional second argument, which is a callback which is executed when the state is updated.

    The way setState updates the state is:

    • If the first argument of the setState function is an object, it merges the current state object with whatever you passed to the setState function. For example:
    1. state = { a: 1, b: 2, c: 3} //current state
    2. this.setState({ a: 3 }); //we call setState with just one key value pair
    3.  
    4. //it will **merge** the initial state with the object passed to setState
    5. //as a result only the value for that one key is updated
    6. state = { a: 3, b: 2, c: 3 } //state after setState is flushed

    One thing you must know about setState function is that it may be asynchronous. So do not rely on it to update the state immediately. This is not a bug, it's by design. If you want to read up on the design decision behind setState call being asynchonous, here's a .

    Since setState can be asynchronous below code will not give you the right result because by the time we console.log the state.counter value, it won't be updated.

    1. //❌ WRONG RESULT. Do not rely on setState to be synchronous
    2. console.log(this.state.counter);//prints 0
    3. this.setState({
    4. counter: this.state.counter + 1
    5. }); //this is asynchronous call
    6. console.log(this.state.counter);//still prints 0

    Also if you want to update state using the current state value always use the updater function inside setState instead of passing object. For example below code will not work.

    I know we discussed several things about state and it must be overwhelming. Let's just recap the rules:

    • Never mutate this.state directly. Always use this.setState to update the state.
    • If your new state depends on the old state then use this.setState(function(currentState){ .. }) construct.

    Props and State

    Since we now have looked into both state and props how are they different and how are they similar?

    The difference between state and props is that state is owned by the component itself while props is something that is passed down to the component by it's parent.

    And the similarity (sort of) is that React automatically re-renders your component when either the component's state changes or when the component's props changes.

    Your component's render function is a function of both state and props meaning it defines what your component should look like given the state and props. It should be pure function in a sense that if the component has same state and props it should render exactly same content no matter how many times it's called and shouldn't have any side effects.