DEV Community

Cover image for How to use React Hooks - 2 most commonly used Hooks explained ✨
Sushmita Pandey
Sushmita Pandey

Posted on • Edited on • Originally published at sushmita.hashnode.dev

How to use React Hooks - 2 most commonly used Hooks explained ✨

Hey there!

Welcome to my first post :D. In this post, I'm gonna introduce you to React Hooks, and then teach you two of the most used hooks - the state hook and the effect hook. Let's dive right in!

What are Hooks?

Hooks were introduced for the first time in React v16.8. They let you write components without using JavaScript classes. Which is actually really cool, because that means that you get to use state, lifecycle methods and other awesome things inside a regular JavaScript function!

Note: It's still absolutely fine to write class components. React has no plans to deprecate them as of now. But, Hooks are increasingly becoming the more effective way to write react code, so I'd suggest you try it out and I'm sure you'll get Hooked!

Let's look at a simple component coded using both class components and hooks:

// using Class Components
class CounterComponent extends React.Component {
  constructor() {
    super();

    this.state = {
      count: 0
    };
  }

  componentDidMount() {
    console.log("Component mounted");
  }

  componentDidUpdate(prevProps, prevState) {
    console.log("Component rendered");

    if (prevState.count !== this.state.count) {
      console.log("current count is", this.state.count);
    }
  }

  componentWillUnmount() {
    console.log("Unmounting the component...");
  }

  render() {
    return (
      <>
        <div>
          <button
            onClick={() => this.setState({ count: this.state.count + 1 })}
          >
            Increase
          </button>
          <button
            onClick={() => this.setState({ count: this.state.count - 1 })}
          >
            Decrease
          </button>
        </div>
        <div>
          <p>Current count: {this.state.count}</p>
        </div>
      </>
    );
  }
}

Enter fullscreen mode Exit fullscreen mode
// using Hooks
const Counter = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("Component mounted");
  }, []);

  useEffect(() => {
    console.log("Component rendered");
    return () => console.log("Unmounting the component...");
  });

  useEffect(() => {
    console.log("current count is", count);
  }, [count]);

  return (
    <>
      <div>
        <button onClick={() => setCount(count + 1)}>Increase</button>
        <button onClick={() => setCount(count - 1)}>Decrease</button>
      </div>
      <div>
        <p>Current count: {count}</p>
      </div>
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

As we can see, the code written using hooks is much more concise, and we don't have to worry about 'this' anymore.

Why hooks?

React class components don't minify well, and this makes hot reloading unreliable. Minification of functions in Javascript is much better.

Also, the useEffect hook combines many lifecycle methods of class components like componentDidMount, componentDidUpdate and componentWillUnmount. Which means we don't have to split our work in different methods anymore.

With hooks, it becomes easy to reuse stateful logic, by making your own hooks, known as custom hooks.

React hooks make our code cleaner and shorter, which provides a good development experience!

The useState Hook

The purpose of this hook is to let you use state in functional components. The basic syntax of a useState declaration is:

const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

Here I have declared a state variable called count and set it to 0. For updating username, we will call setCount. UseState always returns two values, a state variable and a function to update it.

return (
<div>
  <button onClick={() => setCount(count + 1)}>Increase</button>
  <button onClick={() => setCount(count - 1)}>Decrease</button>
</div>
...
)
Enter fullscreen mode Exit fullscreen mode

To display the state, we directly use count:

return (
...
<div>
  <p>Current count: {count}</p>
</div>
)
Enter fullscreen mode Exit fullscreen mode

Whenever the user clicks on Increase or Decrease, setCount updates count with the new value, and React re-renders the component. Let's look at the complete component:

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
  <>
    <div>
      <button onClick={() => setCount(count + 1)}>Increase</button>
      <button onClick={() => setCount(count - 1)}>Decrease</button>
    </div>
    <div>
      <p>Current count: {count}</p>
    </div>
  </>
  )
}
Enter fullscreen mode Exit fullscreen mode

You can create multiple state variables, and use them as per your liking.

The useEffect Hook

This hook lets you use lifecycle methods like componentDidMount(), componentDidUpdate() and componentWillUnmount() in functional components.

Let's take a look at a simple example:

useEffect(() => {
  // This runs at the first render and after every render by default
  console.log('Component rendered');

  // This runs just before React unmounts the component 
  return () => console.log('Unmounting the component...');
})
Enter fullscreen mode Exit fullscreen mode

If you want to control how many times a particular useEffect runs, you can specify a second argument, a dependency array, which is an array of values to it. The useEffect will run only when atleast one of the values in this array have changed since the last time. To demonstrate, we will take the help of our previous 'count' example. Let's see how this works:

useEffect(() => {
  console.log('current count is', count)
}, [count])
Enter fullscreen mode Exit fullscreen mode

If you pass an empty array, useEffect will run only once, on mount:

useEffect(() => {
  console.log('Component mounted');
}, [])
Enter fullscreen mode Exit fullscreen mode

You can view the full code on this codesandbox link.

To summarize, hooks are a powerful way to write your React code. To get started, you can start using hooks in the new components you make. Happy Coding!

Top comments (8)

Collapse
 
andrewbaisden profile image
Andrew Baisden

Welcome great post. By the way you can use syntax highlighting in your code blocks to make them more readable github.com/adam-p/markdown-here/wi...

Collapse
 
sushmita094 profile image
Sushmita Pandey

Great tip! I've implemented this in this post. Thanks a ton :)

Collapse
 
djnadackal profile image
djnadackal

What does useEffect with no dependency array means?
When are they used ?
Will it go to a state of infinite loop?

Collapse
 
sushmita094 profile image
Sushmita Pandey

useEffect with no dependency array will run at the first render and after every render. It's used when we might want to run some code on every single render, although this scenario isn't used a lot.
No it won't go in a state of infinite loop unless you are changing any state values inside useEffect, in that case:
state change -> useEffect triggered -> state change -> ....goes on in an infinte loop

Collapse
 
sebalr profile image
Sebastian Larrieu • Edited

Empty array means only execute after mount. The value in the arrays is what react check for execution. Empty array means nothing to check

Thread Thread
 
djnadackal profile image
djnadackal

Hi Larrieu, I was referring to the scenario when we dont give a dependency array. 🙂

Collapse
 
djnadackal profile image
djnadackal

And one more doubt, why return a call back method inside the useEffect?

Thread Thread
 
sebalr profile image
Sebastian Larrieu

That's executed before the next useEffect, for example if you set a timeout inside useEffect, you must cancel it as return callback, so in the next execution, before setting the new timeout, the previously one is good to be cleared