Getting Started With The React Hooks API


 

QUICK SUMMARY In this blog, you are going to learn and understand what React hooks are, the basic React Hooks that are available and also examples of how to write them for your React applications. 

When React 16.8 was released officially in early February 2019, it shipped with an additional API that lets you use state and other features in React without writing a class. This additional API is called Hooks and they’re becoming popular in the React ecosystem, from open-sourced projects to being used in production applications.

React Hooks are completely opt-in which means that rewriting existing code is unecessary, they do not contain any breaking changes, and they’re available for use with the release of React 16.8.

What Are React Hooks? 

React Hooks are in-built functions that allow React developers to use state and lifecycle methods inside functional components, they also work together with existing code, so they can easily be adopted into a codebase. The way Hooks were pitched to the public was that they allow developers to use state in functional components but under the hood, Hooks are much more powerful than that. They allow React Developers to enjoy the following benefits:

  • Improved code reuse;
  • Better code composition;
  • Better defaults;
  • Sharing non-visual logic with the use of custom hooks;
  • Flexibility in moving up and down the components tree.

With React Hooks, developers get the power to use functional components for almost everything they need to do from just rendering UI to also handling state and also logic — which is pretty neat.

Motivation Behind The Release Of React Hooks 

According to the ReactJS official documentation, the following are the motivation behind the release of React Hooks:

  • Reusing stateful logic between components is difficult.
    With Hooks, you can reuse logic between your components without changing their architecture or structure.
  • Complex components can be difficult to understand.
    When components become larger and carry out many operations, it becomes difficult to understand in the long run. Hooks solve this by allowing you separate a particular single component into various smaller functions based upon what pieces of this separated component are related (such as setting up a subscription or fetching data), rather than having to force a split based on lifecycle methods.
  • Classes are quite confusing.
    Classes are a hindrance to learning React properly; you would need to understand how  this  in JavaScript works which differs from other languages. React Hooks solves this problem by allowing developers to use the best of React features without having to use classes.

Basic React Hooks 

There are 10 in-built hooks that was shipped with React 16.8 but the basic (commonly used) hooks include:

These are the 4 basic hooks that are commonly used by React developers that have adopted React Hooks into their codebases.

useState()

The useState() hook allows React developers to update, handle and manipulate state inside functional components without needing to convert it to a class component. Let’s use the code snippet below is a simple Age counter component and we will use it to explain the power and syntax of the useState() hook.

function App() {
  const [age, setAge] = useState(21);
  const handleClick = () => setAge(age + 1)

  return 
      <div> 
          I am {age} Years Old 
        <div> 
        <button onClick={handleClick}>Increase my age! </button>
      </div>
   </div>
}

If you’ve noticed, our component looks pretty simple, concise and it’s now a functional component and also does not have the level of complexity that a class component would have.

The useState() hook receives an initial state as an argument and then returns, by making use of array destructuring in JavaScript, the two variables in the array can be named what. The first variable is the actual state, while the second variable is a function that is meant for updating the state by providing a new state.


This is how our component should look when it is rendered in our React application. By clicking on the “Increase my Age” button, the state of the age will change and the component would work just like a class component with state.

useEffect() 

The useEffect() hook accepts a function that would contain effectual code. In functional components, effects like mutations, subscriptions, timers, logging, and other effects are not allowed to be placed inside a functional component because doing so would lead to a lot of inconsistencies when the UI is rendered and also confusing bugs.

In using the useEffect() hook, the effectual function passed into it will execute right after the render has been displayed on the screen. Effects are basically peeked into the imperative way of building UIs that is quite different from React’s functional way.

By default, effects are executed mainly after the render has been completed, but you have the option to also fire them when certain values change.

The useEffect() hook mostly into play for side-effects that are usually used for interactions with the Browser/DOM API or external API-like data fetching or subscriptions. Also, if you are already familiar with how React lifecycle methods work, you can also think of useEffect() hook as component mountingupdating and unmounting — all combined in one function. It lets us replicate the lifecycle methods in functional components.

We will use the code snippets below to explain the most basic way that we can by using the useEffect() hook.

Step 1: Define The State Of Your Application

import React, {useState} from 'react';
function App() {
    //Define State
    const [name, setName] = useState({firstName'name'surname'surname'});
    const [title, setTitle] = useState('USER');
    
    return(
        <div>
            <h1>Title: {title}</h1>
            <h3>Name: {name.firstName}</h3>
            <h3>Surname: {name.surname}</h3>
        </div>
    );
};
export default App

Just like we discussed in the previous section on how to use the useState() hook to handle state inside functional components, we used it in our code snippet to set the state for our app that renders my full name.

Step 2: Call The useEffect Hook

import React, { useState, useEffect } from "react";
function App() {
  //Define State
  const [name, setName] = useState({ firstName"name"surname"surname" });
  const [title, setTitle] = useState("USER");

  //Call the use effect hook
  useEffect(() => {
    setName({ firstName"Nushky"surname"Ansar" });
  }, []); //pass in an empty array as a second argument

  return (
    <div>
      <h1>Title: {title}</h1>
      <h3>Name: {name.firstName}</h3>
      <h3>Surname: {name.surname}</h3>
    </div>
  );
}
export default App;

We have now imported the useEffect hook and also made use of the useEffect() function to set the state of our the name and surname property which is pretty neat and concise.

You may have noticed the useEffect hook in the second argument which is an empty array; this is because it contains a call to the setFullName which does not have a list of dependencies. Passing the second argument will prevent an infinite chain of updates (componentDidUpdate()) and it’ll also allow our useEffect() hook to act as a componentDidMount lifecycle method and render once without re-rendering on every change in the tree.

Our React app should now look like this:

We can also use change the title property of our application inside the useEffect() function by calling the setTitle() function, like so:
import React, {useState, useEffect} from 'react';
function App() {
    //Define State
    const [name, setName] = useState({firstName'name'surname'surname'});
    const [title, setTitle] = useState('BIO');
   
    //Call the use effect hook
    useEffect(() => {
      setName({firstName'Nushky'surname'Ansar'})
      setTitle({'My Full Name'}) //Set Title
    }, [])// pass in an empty array as a second argument
    
    return(
        <div>
            <h1>Title: {title}</h1>
            <h3>Name: {name.firstName}</h3>
            <h3>Surname: {name.surname}</h3>
        </div>
    );
};
export default App

Now after our application has rerendered, it now shows the new title.



useContext()

The useContext() hook accepts a context object, i.e the value that is returned from React.createContext, and then it returns the current context value for that context.

This hook gives functional components easy access to your React app context. Before the useContext hook was introduced you would need to set up a contextType or a <Consumer> to access your global state passed down from some provider in a class component.

Basically, the useContext hook works with the React Context API which is a way to share data deeply throughout your app without the need to manually pass your app props down through various levels. Now, the useContext() makes using Context a little easier.

The code snippets below will show how the Context API works and how the useContext Hook makes it better.

The Normal Way To Use The Context API 

import React from "react";
import ReactDOM from "react-dom";

const NumberContext = React.createContext();
function App() {
  return (
    <NumberContext.Provider value={45}>
      <div>
        <Display />
      </div>
    </NumberContext.Provider>
  );
}
function Display() {
  return (
    <NumberContext.Consumer>
      {value => <div>The answer to the question is {value}.</div>}
    </NumberContext.Consumer>
  );
}
ReactDOM.render(<App />, document.querySelector("#root"));



Let’s now break down the code snippet and explain each concept.

Below, we are creating a context called NumberContext. It is meant to return an object with two values: { Provider, Consumer}.

const NumberContext = React.createContext();

Then we use the Provider value that was returned from the NumberContext we created to make a particular value available to all the children. 

function App() {
  return (
    <NumberContext.Provider value={45}>
      <div>
        <Display />
      </div>
    </NumberContext.Provider>
  );
}

With that, we can use the Consumer value that was returned from the NumberContext we created to get the value we made available to all children. If you have noticed, this component did not get any props.

function Display() {
  return (
    <NumberContext.Consumer>
      {value => <div>The answer to the question is {value}.</div>}
    </NumberContext.Consumer>
  );
}
ReactDOM.render(<App />, document.querySelector("#root"));

How we were able to get the value from the App component into the Display component by wrapping our content in a NumberContext.Consumer and using the render props method to retrieve the value and render it.

Everything works well and the render props method we used is a really good pattern for handling dynamic data, but in the long run, it does introduce some unnecessary nesting and confusion if you’re not used to it.

Using The useContext Method 

To explain the useContext method we will rewrite the Display component using the useContext hook.

// import useContext (or we could write React.useContext)
import React, { useContext } from 'react';

// old code goes here

function Display() {
  const value = useContext(NumberContext);
  return <div>The answer is {value}.</div>;
}


That’s all we need to do in order to display our value. Pretty neat, right?
 You call the useContext() hook and pass in the context object we created and we grab the value from it.

Don’t forget that the argument that is passed to the useContext hook must be the context object itself and any component calling the useContext will always re-render when the context value changes.

useReducer() 

The useReducer hook is used for handling complex states and transitions in state. It takes in a reducer function and also an initial state input; then, it returns the current state and also a dispatch function as output by the means of array destructuring.

The code below is the proper syntax for using the useReducer hook.

const [state, dispatch] = useReducer(reducer, initialArg, init);


It is sort of an alternative to the useState hook; it is usually preferable to useState when you have complex state logic that has to do with multiple sub-values or when the next state is
 dependent on the previous one.

Other React Hooks Available 

useCallback

This hook returns a callback function that is memorized and that only changes if one dependency in the dependency tree changes.

useMemo

This hook returns a memoized value, you can pass in a “create” function and also an array of dependencies. The value it returns will only use the memorized value again if one of the dependencies in the dependency tree changes.


useRef

This hook returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will be available for the full lifetime of the component.


I hope you enjoyed working through this Blog.Thankyou



Comments

Popular posts from this blog

What is ReactJS: Introduction To React and Its Features