In this article, Ill try to showcase the possible best practices that came with Hooks, and How to Better Use React Hooks as a developer in your future projects, so, to follow with me, you only need a background in reactJs.🔗

React v16.8 included Hooks and started letting you manage state and other react features without writing a class.

But first, why using functional components with Hooks in React ?🙄 can we just keep using classes? The answer is yes, But think twice before doing that, because using FC will allow you to:

  • Easily separate container and presentational components
  • write readable and testable components.
  • write less code.
  • boost your app’s performance 🚀

React provide developers with built-in hooks, such as useState, useEffect, useContext … and let you also create your own hooks, you can check this article to see what kind of hooks you can build, so you can use in your project:

This example focuses on useState and useEffect. The same rules apply to other hooks.

import React, { useState } from 'react'; // call the useState hook

const SimpleComponent = () => { // Hooks are used inside function components
  const [count, setCount] = useState(0)
  return (
    <div>
      <p>Click Number : {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Click     
      </button>
    </div>
  )
}

ReactDOM.render(<SimpleComponent />, document.getElementById('app'))

The code above shows the use of setState Hooks. It’s a simple component that lets user increment a number when the click event is fired, In the old school React, we could write something similar to (see the code below) to initialize our values in the constructor, inside the class.

this.state = {
   count:0 
}

With Hooks we can do the same thing inside a function component by writing this line of code

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

The click event fired the useState function, and that incremented the number.

The same problem could be solved while producing more code if we use classes, and imagine the complexity if the state gets bigger 🤷‍♂️

Using Hooks also can lead to complexity, and the aim of this article is to show you that with a few steps. You will be writing complex apps, and managing their complexity using Hooks😉

Now, lets see how we can do it.

Based on React’s beautiful doc 😍 there are few rules to follow when you start writing hooks based apps.

1 – Know Where to Hook, and Respect the Order.

Lets be clear about the first rule, do not ever call Hooks in:

❌ class components 
❌ Event Handlers 
❌ Loops
❌ Inside functions passed to useMemo, useReducer, or useEffect
if (true) { // the useEffect hook is called based on a condition 😦
  useEffect(myFunction() => {
    console.log('rendering this part')
  });
}

Write Hooks only inside functions

Or, checking StackOverflow to solve the invalid hooks call error will be your next step🤷‍♂️

Now you know where to not hook, the first rule is about respecting order and calling hooks in the top level of your function component, in plain English this means: react needs to know that hooks are always called in the same order and not depending on conditions or loop when rendering.

Calling hook while respecting react rules should be something like:

const SimpleSecondComponent = () => { 
  const [count, setCount] = useState(0) ✔
  const [name, setCount] = useState('') ✔
  useEffect(() => { ✔
    document.title = `You clicked ${count} times`;
  });
}

For the curious developers, who want to know why the order is so important and what is behind the scenes, & also linked list and data structure are your favorite topic😢, please check this wonderful explanation 👌

2 – Use it only inside react functional component

Yes, React function component and Javascript functions are not the same thing, calling hooks inside a js function will be impossible, functional react components accepts props as arguments and returns JSX, even if they have the same body and structure as a simple javascript function.🤷‍♀️

React functional component are not the same as regular Javascript components

import { useState } = "react";

const sayHello = (name) => {
  const [name, setName] = useState("John");
  return console.log(`Hello ${name}`);
}
document.getElementById("root").innerHTML = sayHello;

The useState will be useless here 🤷‍♂️ unless you create a functional react component.

3 – useYourCustomHooks()

Custom hooks is a new way that offers you the flexibility of sharing logic that wasn’t possible in React components before. You can write it to cover many use cases like data fetching handling, complex annimation, declarative subscriptions, timers… and more.

Custom Hooks means fewer code. and less repetitive blocks

Imagine that you’re using a component that uses a huge state, the same state is shared between other components, and we know as much as the state gets bigger, it becomes very hard to manage its logic complexity,

Using many setState in your functional component won’t make updating the state centralized and easier, this is where the idea of reducers come from😉, and creating a useReducer custom hook will solve this problem for many other components.

Let’s create a simple Hook that displays a title, our hook will be in a separated file and will look like:

const useTitle= (title) => {
  useEffect(() => {
    document.title = title;
  }, [title])
}

As we can see, a custom hook is a function that starts with use, and can use another hook inside, it so simple right? 😁 and of course, you can use this hook anywhere !! POWERFUL 🚀


 import React, { Component, useState } from 'react';
 import useTitle from './myHooks/usetitle'; // our custom hook 

 const Counter() => {
    const [count, setCount] = useState(0);
    const incrementCount = () => setCount(count + 1);
    useTitle (`You clicked ${count} times`);

    return (
      <div>
        <p>You clicked {count} times</p>
        <button onClick={incrementCount}>Click me</button>
      </div>
    )
  }

  export default Counter;

Think of creating your useLocalStorageHook to manage your local storage, useValidData to validate your form… and many more!!

I guarantee you a much cleaner & centralized code 😉.

4- Yes, Linters Are a Must!

Lint your code, to avoid annoying conflicts😣, I use an esLint plugin to make sure that all the rules above are applied, especially when working with a team.

create-react-app included the plugin, otherwise, you can install it by using:

npm install eslint-plugin-react-hooks --save-dev

And use the following configuration in you esLint config file to enforce these rules:

// Your ESLint configuration
{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
    "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies
  }
}

Conclusion:

In this article, I’ve tried in this article to list the most important rules to follow for developers who are willing to adopt React Hooks in there next project, put in mind that using hooks requires validating these steps :

  • Simplicity: in three words DRY ✔
  • Organization: Follow this order, computations first, instantiate the state, subscribe to your side-effects, set up your event handlers, and finally render(); ✔
  • Type-check your code, read more here
  • Use a style guide, it will make your life much easier and will give your code credibility✔

4 thoughts on “ How to Better Use React Hooks? ”

Leave a Reply

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