React

React Hooks – Correct usage of State Hook

state

Let’s get into details of what state hooks are and how to use them in right way in React function components.

function Hotel() {
  const [count, setCount] = useState(0);
  let msg;
  if (count>0) {
    msg = `Hotel Filton - No. of guests checked in - ${count}`;
  }
  else {
    msg = 'Nobody likes your Filton hotel. Give some offers';
  }

  return (
    <div>
       <p>{msg}</p>
       <button onClick = {() => setCount(count+1)}>
        Check-in
       </button>
      <br/>
      <br/>
       <button onClick = {() =>  {
         if (count>0) {
           setCount(count-1);
         }
        }
       }>
        Check-out
       </button>

    </div>
  );
}

If the same thing is written in class, it will be like this.

class Motel extends React.Component {

  constructor(props) {
    super(props);
    this.state = {count : 0};
  }

  render() {
    let msg;
    if (this.state.count>0) {
      msg = `Hotel Filton - No. of guests checked in - ${this.state.count}`;
    }
    else {
      msg = 'Nobody likes your Filton hotel. Give some offers';
    }
    return (
      <div>
         <p>{msg}</p>
         <button onClick = {() => this.setState({count: this.state.count+1})}>
          Check-in
         </button>
        <br/>
        <br/>
         <button onClick = {() =>  {
           if (this.state.count>0) {
             this.setState({count: this.state.count-1});
           }
          }
         }>
          Check-out
         </button>
      </div>
    );
  }
}

Here you can see that state is to be initialized in constructor and we set initial value to count state variable to 0. And then we use React’s this.setState function to update count on click of Check-In and Check-Out buttons.

Here you can see it live in action Hooks vs Classes in action https://codepen.io/anilpank/pen/jOOVZwY

A simple function component looks like this.

function TweetMessage(props) {
   // You can use your hooks here
   return <div>I run my company through twitter.</div>
}

Or in a more arrow like syntax you can also write your function component like this.

const FacebookStatusUpdate = (props) => {
   // You can write your hooks here
   return <div>My photo will get 1000 likes</div>
}

Function components before React 16.8 were stateless components. Now you can add states to Function components using Hooks.

One thing to note is hooks don’t work in classes. But you can use Function components which have hooks inside your classes.

When to use Hook?

Hook is a special function that lets you insert special react functionality, be it making your functional components stateful (using states), or doing any side effects (dom manipulation, event binding, cleanups, etc). If you are writing a function component and then realize that you need to add some state to it, then go ahead and use hooks.

Declaring state variable – Class vs Function

Suppose you want to add a state variable thoughtCount in a class BigThinker. You can do it by setting this.state to object {thoughtCount : 0} in constructor method of BigThinker class.

class BigThinker extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      thoughtCount: 0
    };
  }

Contrast this with doing this in a function component BigThinker. Here we don’t have any this. So we use React hook called useState to do the same. Here thoughtCount is corresponding state variable and useThoughtCount is function callback that can be used for changing thoughtCount value.

function BigThinker(props) {
   const[thoughtCount, setThoughtCount] = useState(0);   
}

Many of you might be thinking how thoughtCount variable is different than any other variable that we declare inside BigThinker function component. The key difference is any other variable that you use inside BigThinker function will disappear as soon as this function exits, but React will preserve thoughtCount value.

What arguments does useState hook accept?

useState hook accepts one argument. That can be string, number or even an object. That is assigned as initial state of variable (thoughtCount in above example). Compare this with class state variables where this.setState always needs a javascript object.

What is useState hook returning?

As explained above useState hook returns two things in a pair. The first thing is state value (thoughtCount in our example) and second thing is a function that can update the state value (setThoughtCount function in our example). I was thinking on why React adopted this, returning two things in a pair. Here React is following destructuring assignment syntax. It is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables. Since thoughtCount and setThoughtCount are related to each other, it makes perfect sense to return them together through a single hook.

How to read state – Class vs Function

When we want to show current thoughtCount in a class, we use this.state.thoughtCount.

  <p>You are thinking {this.state.thoughtCount} times</p>

In a function component when you are using hooks, you can use the variable name thoughtCount directly.

  <p>You are thinking {thoughtCount} times</p>

How to modify state – Class vs Function

In class we need to call React provided this.setState function to change the state variable.

<button onClick={() => this.setState({ thoughtCount: this.state.thoughtCount + 1 })}>
    Improve my thought process  
</button>

In a function we already have thoughtCount variable and setThoughtCount function available using hooks. So need to use the confusing this.

<button onClick={() => setThoughtCount(thoughtCount + 1)}>
    Improve my thought process  
</button>

How to use more than one state variables in a function?

You are not limited to using just one state variable in a function. You can follow this pattern [entity, setEntity] and declare as many state variables as you want.

function HouseWithManyStates() {
  // Declare multiple state variables!
  const [doorCount, setDoorCount] = useState(42);
  const [veggie, setVeggie] = useState('cabbage');
  const [toTravel, setToTravel] = useState([{ text: 'Great Wall of China' }]);

You can see this as departure from what you follow in class where you specify everything in a state variable object. You can follow the same in hooks as well, create an object which holds all your data together. However there is one subtle difference where you need to be careful. this.setState has capability of partially updating/merging the state, but the hook state functionality does not perform any merge but does a full replacement. I’ll cover a detailed article on these gotchas.

Go ahead, try above examples, write your first state hook and show case your awesome react skills.

How useful was this post?

Click on a star to rate it!

Average rating / 5. Vote count:

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tagged ,

About anil

Hi, I'm Anil Verma. I have a passion for teaching and developing awesome front end apps. I was involved in development of post processor for Nastran(built by NASA). More recently I have been building supply chain apps at E2open.
View all posts by anil →

Leave a Reply

Your email address will not be published. Required fields are marked *