Fundamentals of React Hooks

Manish Johar
Geek Culture
Published in
7 min readJun 20, 2021

Hooks have been really gaining a lot of popularity from the first day of its release by the Facebook React team. If you have any experience with class components then you can really understand how hooks make a React developer’s life easier. Lots of libraries like Vue, Svelte are adopting hooks to extends their features.

But on the other side, there is a lack of clarity about its uses. So, with the help of this article, I will try to make things easier to understand for you.

What are Hooks?

Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.

Contents

  1. Basic Hooks

2. Additional Hooks

3. Custom Hooks

Let’s go through all these hooks one by one.

Basic Hooks

useState

It is the most common hook in react which creates the state variable in a functional component.

const [state, setState] = useState(initialState);

To use it you can pass any value or function as an initial state and it returns an array of two entities, the first element is the initial state and the second one is a function (dispatcher) which is used to update the state.

Note: If you pass a function as the initial value then react call it internally as you can see in code.

Now let’s see how to update the values

As you can see in the code we updated the value in two ways. The first one is pretty much clear but the second one we have used whenever we have some dependency on the old value.

useEffect

useEffect is the second most used hook in React. It just called the passed function just after the render is committed to the screen.

Let’s see what I mean by this line.

Output:

So you can see on the console ‘Component update’ print just after the “Render End” — (“just after the render is committed to the screen”).

When and how to use it?

When

It has lots of use cases but let me mention the most common one.

  1. use it as the initial first render of the component (ComponentDidMount).
  2. use it when a component goes out of scope (ComponentWillUnMount)
  3. to call or handle any piece of code for a particular state change.

You can learn about the React life-cycle.

How

Please give your attention to the console.log and comments I mention in the code.

useContext

What is context API?

Context API is a new feature added in 16.3 which allows us to pass the state directly to any children component.

As you can clearly see in the diagram, that without context API if you want to pass the data(props) to any children component then you have to pass that data to each children component that contains the target component. This process is called props drilling.

But with context API you can directly pass data (props) to any children component.

Let’s have some code

Ok, so you can see in the code we directly pass the Object ({hello: ‘Hello World’}) to my ChildThree component with the help of useContext hook cool right 😎.

Additional Hooks

useReducer

It is an alternative to useState. Accepts a reducer of type, (state, action) => newState and returns the current state paired with a dispatch method. (If you’re familiar with Redux, you already know how this works.)

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

useReducer is usually preferable to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one.

Ok, let’s understand with code what I am trying to say.

So as you can see in the code, first, we create the reducer then put our logic as we do in our redux. Then we pass that reducer to the useReducer as the first parameter and pass ‘0’ as the initial value.

And now we can update the count value using countDispatcher pretty simple 😊. So you can create more complex states using the useReducer.

useCallBack

We use useCallback to memorized the version of the callback that only changes if one of the dependencies has changed.

const memorizedFunction = useCallback(fn, [deps]);

Suppose we have a function to the child component, used in the map, so whenever the map data get updated child will re-render and a new reference of that function will also generate, so to prevent this we can use useCallback.

Let’s have some code

So as you can see in the “memorizedFun” will not create a new reference on every render.

useMemo

We use useMemo to memorized the value that only changes if one of the dependencies has changed.

const memorizedValue = useCallback(value, [deps]);

Suppose we have to store the value which we get after the heavy calculation and we don’t want to recompute that value on every render, in that case, we can use useMemo.

Let’s have some code.

So as you can see in the code memorizedValue memorized during the first render then it just used the stored value which helps us to improve performance also.

useRef

useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue).

A common use case is to access dom/ child component properties.

Let’s have some code.

output

As you can see in the code and output useRef just store the value or property of the DOM/ React Component which you can also change.

useImperativeHandle

useImperativeHandle customizes the instance value that is exposed to parent components when using ref. As always, imperative code using refs should be avoided in most cases. useImperativeHandle should be used with forwardRef.

Let’s see what do we mean by this.

How to use in Child Component

How to in Parent component

So as you can see in the code, now we can easily change the child component state using the instance in the parent, because of this hack we don’t need to change the parent’s state and that’s how we save the rendering.

useLayoutEffect

The signature is identical to, useEffect but it fires synchronously after all DOM mutations. Use this to read the layout from the DOM and synchronously re-render. Updates scheduled inside useLayoutEffect will be flushed synchronously before the browser has a chance to paint.

Output

As you can see on the console “Layout Effect updated” just call before the “Component Updated”. This is what we mean by the definition.

Custom Hooks

There might be a situation where you have been using the same repetitive and redundant stateful logic inside multiple components. So mentioned that logic in every component, we can separate that code in a file and use it wherever we want.

Let’s see some real-life example

Suppose you want a state by which you can figure out either the screen is in mobile view or desktop view.

How to create a separate file for the required custom hook.

Note: you have to use ‘use’ as a prefix for the service name as you can see in the code.

How to use it

Ok, so whenever you adjust your browser width it will automatically update the state.

Conclusion

At this point, we have a complete basic understanding that when, where, and how to use different hooks in React. With the use of the best match hook as per the requirement we can make our application modular, less complex, and improve the performance by preventing the unrequired rendering.

Thanks for reading this article. I hope you enjoyed it.

--

--