Introduction
Like as always, we will be asked the question on whether we have heard of React hooks or not. And just like the title suggested, today I am going to be discussing as well as covering React hooks and what they are. Now, hooks were introduced in React 16.8 and they are nothing but the addition of new features that have been released as part of 16.8. But before 16.8, state for components was only available in class components and to use states, we had to convert our functional components to class components.
The reason they used to love functional components earlier was because of their simplicity. But according to the new way of using state in functional components, this enables us to create functional components that have states, so we can do data-related tasks using state in our functional components without any calls to the class components at all.
Well then...This will be the first of many articles that will help us understand hooks better in React. There are many articles as well as documentation provided by React, helping us get the hang of hooks. I have tried my best to do the same but through this article, just to make your lives easier as well. I won't lie its still not yet the easiest route for me but I have also tried compiling all the code snippets that will help you figure out hooks from the beginning as well as try to get a small understanding of what hooks are and how to use them.
Overview of state management hooks
The useState hook is part of a set of hooks that are shipped with React, which allow us to add local state management to functional components. The values that are returned from hooks such as useState and useReducer are referred to as hook states.
Using the useState hook, we can add state to functional components of React. This hook returns a pair of values which represent the current state of the application, and a method to update the value of the state. The method to update the state can take a parameter which is the new value to be assigned to the state. The useState hook accepts a parameter which is the initial value of the state when the component is rendered for the very first time. Its function signature is as follows:
const [state, setState] = useState(initialState).
The following hooks I will try to explore in this article:
- useState
- useReducer
- useContext
- useMemo
- useCallback
- useRef
In this article, I will explore various hooks which belong to the category of state management hooks in React. There are many hooks such as useState, useReducer, useContext, etc. which provide us with the capability to declaratively manage state in functional components of React.
Using State Management Hooks
Here, you define a function component named Counter that returns a div element, with a paragraph element that displays the current state's counter value, and a button element for incrementing the counter's value when clicked. In line 5, the useState hook is called to initialize a state variable named counter with an initial value of 0. You destructure the array returned by the useState hook, and use the first element of the array as the state variable that represents the current counter state. This state is displayed in the paragraph element in line 7, within the caption element that is rendered as the children of the paragraph element.
To keep track of component state within a function component, you can use the useState hook. This hook takes in a single argument, which is the initial state value, and returns an array with two elements: a state variable that keeps track of the current state's value, and a setState function that is used to update the current state, which triggers a re-render of the component.
export const Counter = () => {
const [counter, setCounter] = useState(0);
const incrementCounter = () => setCounter(counter + 1);
return (
<div>
<p>{counter}</p>
<button onClick={incrementCounter}>Increment</button>
</div>
);
};
import React, { useState } from 'react';
I hope it’s starting to become a little bit easier to understand what hooks are doing right now and how these overall functions and features of React hooks will continue to make our lives much easier from here on. Well let's continue then yeah?
Understanding the useContext Hook using code snippets
These are known to creates a state that is accessible from all the components.
At first glance, the function UserProfilePage in the code snippet above might look like some TypeScript code. However, it is simple JSX. The following useContext call returns the current UserContext context value with its corresponding Provider's value. Although it might seem like a beauty overkill for getting access to the context value, useContext gives you a bit more elegance in the code and functions well in a functional component.
function UserProfilePage() {
const user = useContext(UserContext);
return <UserProfile user={user} />;
}
As you saw in the examples above, direct usage of contextType is not possible without middleware libraries.
Introduction to useReducer Hook using code snippets
This one works exactly like the useState but the only difference is that unlike the useState having a single value, it contains an object.
like for instance useState can store only one value eg. 1
useReducer on the other hand stores the object that being multiple values.Meaning that it should be used when one has an object like for instances when wanting to name, age, contact detail....
Like the instance below where there is one useReducer, compared to 3 useState's for each user values:
function reducer(state, action) {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
const App = () => {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<h1>{state.count}</h1>
<button onClick={() => dispatch({ type: "increment" })}>Increase</button>
<button onClick={() => dispatch({ type: "decrement" })}>Decrease</button>
</div>
);
};
useCallback Hook
The useCallback() hook makes the function to be used within a child component so that a parent component pass to it will not re-render if its inputs are not changing. It can also be useful in that sense when wanting to pass props into the function
Like for instance:
// Returns the value 100
const apiResults = useMemo(() => {
return 100
}, [apiURL]);
// Returns a function, which then can be called
const getApiResults = useCallback((value) => {
return 100 + value
}, [apiURL]);
The useMemo Hook
The useMemo Hook in React is similar to the useCallback Hook. Keep in mind that useMemo is not memoization and should only be used when you have a performance optimization in your React application. useMemo can be imported from the React module by adding the following snippet in your JavaScript file: import { useMemo } from 'react'.
Defining your useMemo will look something similar to either of the following snippets. The main difference between the two is that the first piece of code directly defines the function, does not have function scope, and exists in the same scope as other hooks. The following script is an example of a direct useMemo: const cacheValue = useMemo(() => yourFunction(arg),);
When writing React applications, using hooks is a great way to maintain variables, functions, and state in your application. useMemo is a useful hook that allows you to cache the value of a function call based on a specific dependency. You can think of useMemo as a caching behavior that React provides as a hook so that you can avoid re-calling a function or expensive calculation unless the specific dependency of a function changes.
import { useState, useMemo } from "react";
const App = () => {
const [apiURL, setApiURL] = useState("https://callAPI/");
const apiResults = useMemo(() => {
callAPI();
}, [apiURL]);
return (
<div>
<button onClick={() => setApiURL("https://dummyAPI")}>Change API Url</button>
</div>
);
};
const callAPI = () => {
console.log("Call API");
};
The useRef Hook:
One of the most frequently used hooks for certain types of side effects in React is the useEffect
hook. However, there's also a useRef
hook in React as well which is very useful to access a DOM element or some other value that persists across renders. useRef
returns a mutable ref object which can be initialized with the initialValue.
The returned object will persist for the full lifetime of the component. The primary purpose of the useRef
hook is to store mutable data or values that would be lost on each re-render. Those values can be of type number, string, array, function, object, or any other typethat you could store as instance variable or class properties. Below is the type that shows on how the useRef can be used when wanting to create an input field and needing to access the value
import { useRef } from "react";
const App = () => {
const inputRef = useRef();
return (
<input
ref={inputRef}
onChange={() => {
console.log(inputRef.current.value);
}}
/>
);
};
I hope this makes your lives easier especially for beginners in React like myself, and also feel free to leave your opinions about the article. Thanks.