DEV Community

loading...
Cover image for What are React Hooks? 🎣

What are React Hooks? 🎣

Maxine Meurer
Fullstack Engineer/Fullstack Mom
Updated on ・7 min read

Table Of Contents

Introduction

React is a free and open-source front-end JavaScript library for UI components, maintained by Facebook and a group of individual developers. However it's used, React is only concerned with state management and rendering that state to the DOM, initially through React state and lifecycle methods.

But that all changed when React 16.8 was introduced, its new addition of Hooks allow the use of state and other React features without writing a class. Hooks were developed to solve a bunch of unconnected problems in React. Some of the problems (are not limited too) include:

  1. It’s hard to reuse stateful logic between components

  2. Complex components become hard to understand

  3. Classes confuse both people and machines

What are Hooks?

Hooks are simply just functions that let you “hook into” React state and lifecycle features. Unlike lifecycle methods, Hooks don’t work inside classes. Which can make working with them super flexible, since they let you use lifecycle features in function components. While React provides a few built-in Hooks like useState, you can also create your own Hooks to reuse stateful behavior between components.

useState

This example was taken from and can be seen in the React Documentation for Hooks.

If you are familiar with React, then you may use to seeing state handled like so:

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

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

But with React Hooks, that turns into this:

// This example renders a counter. When you click the button, it increments the value:
import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

The first Hook we'll be examining, is the State Hook. useState is a Hook called inside a function component to add local state. Once added, React uses the Hook to preserve this state between re-renders by returning two things: the current state value and a function for updating it. This function can be called from anywhere, such as an event handler. If you familiar with React, compare it to this.setState in a class, without merging the old and updated state together.

"useState" only takes in one initial argument, which is only used during the first render. In the previous example, this argument is "0" because the counter starts from zero. Keep in mind that unlike this.state, the state here doesn’t have to be an object.

You can understand out how to declare multiple variables with the "useState" hook here.

useEffect

When coding with React, you may perform data fetching, subscriptions, or manually changing the DOM. The React developers like to call these “side effects” since they affect other components, and can’t be done while rendering.

The Effect Hook, useEffect, adds the ability to effect from, you guessed it, a function component. Similar to componentDidMount, componentDidUpdate, and componentWillUnmount in React classes, "useEffect" is unified into a single API.

Going off the example before, after React updates the DOM, the component sets the document title:

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

By calling "useEffect", you’re telling React to run the “effect” function you created after pushing changes to the DOM. Effects are declared inside the component, so they have access to props and state. By default, React runs the effects after every render, starting with the first one. Effects can also optionally specify actions to take after by returning a function. Hooks let you organize side effects in a component by what ideas are related, rather than forcing a split based on lifecycle methods.

Unlike the lifecycle methods, componentDidMount or componentDidUpdate, effects scheduled with useEffect don’t block the browser from updating the screen. This cut back on processing time, since the majority of effects don’t need to happen synchronously, making your app feel more responsive. In a case where effects do need to occur synchronously(such as measuring the layout), there is a separate useLayoutEffect Hook with an API identical to useEffect. You can learn more about that in the Additional Hooks and API Reference section.

Rules of Hooks

Despite Hooks being Javascript functions, there are still several rules they must follow in order to maintain the black magic that gives them lifecycle features.

  1. Only Call Hooks at the Top Level

    • Always use Hooks at the top level of your React function, before any early returns. This means don’t call Hooks inside loops, conditions, or nested functions. This ensures that Hooks are called in the same order each time a component renders, which allows React to correctly preserve the state of Hooks between varying useState and useEffect calls.
  2. Only Call Hooks from React Functions

    • Don’t call Hooks from regular JavaScript functions. Try the following instead:
      • Call Hooks from custom Hooks
      • Call Hooks from React function components.

To make things easy, the React developers made this plugin that automatically enforces these rules. But, that doesn't mean you should skip over knowing proper Hook etiquette.

Building your own Hooks

What if you want to go beyond just the Effect Hook? Well, there's an answer for that, build your own! By building your own Hooks, you can extract component logic into reusable functions. You may be use to doing this in React through: render props and higher-order components. But with the addition of Hooks, you can solve many of the same problems without adding more components to the tree. No one likes cluttered code!

Think about how share logic between two JavaScript functions, you extract it into yet another function. And since components and Hooks are functions, this works for them too!

A custom Hook is a JavaScript function whose name starts with ”use” and has the ability to call other Hooks.

You can write custom Hooks that cover a variety of cases such as form handling, animation, timers, and much more. Don't be afraid to experiment with creating your own Hooks, because you might find yourself making a meaningful contribution to others down the line. React even provides documentation on how to contribute to the open source project.

For more information about building your own custom Hooks and some examples, see the React Documentation for creating custom Hooks.

As an additional resource, here is another recent blog post that further explains how to build your own Hooks, and supplies you with some great examples such as a "useFetch" custom hook. Check it out here!

Additional Hooks and API Reference

If you're interested in learning about the Hooks API reference, the React documentation provides a reader friendly explanation for the basic hooks:

You can also use additional Hooks which are either variants of the basic ones, or only needed for specific edge cases. While helpful, they are just additions, so don't worry about learning them right away. These Hooks include:

Conclusion

React is constantly changing, and programmers who are focused on developing products may not have the time to learn and use every new API released. Hooks are still fairly new, so while they may come in handy, there's no rush to adopt them into your every day practices, unless that's what your heart desires.

Hooks were made to work side-by-side with existing code, which allows you to adopt them gradually, meaning there is no rush to migrate to Hooks. Do not feel the need to do some “big rewrite”, especially for existing, complex class components. It's a bit of a learning curve to start “thinking in Hooks”. So practice using Hooks in your unimportant work first, and once you, and anyone you're working with, feel comfortable with them, give them a go!

Hooks were made in hopes to one day cover all existing use cases for classes, but don't worry because class components aren't going anywhere soon. If you don't believe me, I'll quote the React developers themselves,

"At Facebook, we have tens of thousands of components written as classes, and we have absolutely no plans to rewrite them. Instead, we are starting to use Hooks in the new code side by side with classes."

Hopefully this article has inspired you to hook into your full React potential, or maybe you decided to not bother learning and using yet another API. Either way, let me know your opinion about Hooks, and where you see them going in the future. ✨ Happy Hooking! ✨

Discussion (11)

Collapse
majhar profile image
Amy S.

I always messed up with useState, and causing multiple render.
Happy Hooking!

Collapse
mmeurer00 profile image
Maxine Meurer Author

Bugs/Errors are sometimes our best teachers :)

Collapse
majhar profile image
Amy S.

Hi, do you use multer in your express project?

Thread Thread
mmeurer00 profile image
Maxine Meurer Author

You most certainly can, are you looking to do a file upload?

Thread Thread
mmeurer00 profile image
Maxine Meurer Author

Feel free to PM me, I would be happy to help you out if I can.

Thread Thread
majhar profile image
Amy S.

Yes, I'm working on a project and uploading users profile images, but now I'm confuse where should I save them. Should I save them on mongo as type of Buffer, or in the directory?

Thread Thread
mmeurer00 profile image
Maxine Meurer Author

I think using Buffers can get very confusing itself (so don't feel alone in that!), I can't say exactly since I don't know the extent of everything, but try this stackoverflow post. Here's also a post that goes into Buffers in Mongo DB. I hope that helps. (I personally think it may be easier to save to a directory, but I don't want to discourage you from using buffers in mongo since that could also be a really great learning experience and you are capable of doing either!)

Thread Thread
majhar profile image
Amy S.

Thank you so much!

Collapse
majhar profile image
Amy S.

Sure, it is!

Collapse
zbretz profile image
Zach

This is dope. I'm a bootcamp student and am going to be looking at using hooks in my current project - but I don't know anything about them. I'm bookmarking this to read tomorrow.

Collapse
mmeurer00 profile image
Maxine Meurer Author

Thanks @zbretz ! I think that's really awesome you are already looking to use Hooks.

They're not scary I promise, plus there are tons of youtube tutorials you can watch to get a better grasp on them too.

Best of luck with your project, as well as your bootcamp :)