Understand Unnecessary Rerenders In React

unnecessary re-rendering
An image uploaded to Strapi

Mohd Aatif

Technology

React is an open-source and powerful library for building user interfaces and the thing which enhances the performance of React is state manipulation. We all like React because of its performance and ease of state manipulation.

But when we develop large applications which contain more than a few components, it becomes hard to manipulate states, especially the handling of Re-Rendering in an application. Sometimes unnecessary rerendering causes performance issues in applications.

Let’s dive into these things and understand what is re-rendering in React and why it is at times necessary and how it works.

Later in this post, we will find out some solutions to prevent unnecessary re-renders, and how the performance of the application will increase by preventing these unnecessary renders.

Table of contents

  1. When does React rerenders?
  2. Optimize useEffects.
  3. Use useReducer hook.
  4. Use useMemo hook.
  5. Call function without refrencing it.
  6. Using React fragments.

When does React re-renders?

React always detects the state changes; whenever the state changes, React renders the whole component again. The reason for this re-rendering is to update the component with a fresh state based on the actions or data values.

If the components have child components then React will re-render those child components as well. React uses an in-memory data structure for capturing the changes in state, which is called virtual DOM. Virtual DOM is a very powerful concept, whenever the state change the changes of state will firstly reflect in virtual DOM then the virtual DOM compares those changes with the actual DOM and if there is any difference between those two DOMs , virtual DOM updates only that part of real DOM which has been impacted by the change/difference, e.g. , if the attribute of an element changes, React will only update the attribute of an Html element by calling a function document.setAttribute .

Let’s discuss hooks specifically useEffect as it plays a major role in rendering.

Hooks

Hooks are a new feature that is introduced in React 16.8, Hooks let us use state and other features without writing a class, hooks can only be used in the functional component. useEffect hook plays a very important role in terms of re-rendering, we can track any state changes in useEffect hook.

useEffect

useEffect is a hook in React that allows us to perform side effects on functional components.

This hook tells component that something has changed and the component needs to do something, useEffect hook runs after the first render and after every update in component but this updation depends on passed parameters specifically those which are passed as a second parameter as an array, we can declare useEffect in the following manner;

useEffect.PNG

When we pass some object in useEffect as a dependency array, the useEffect function will run every time on change of that object’s property, e.g.

useEffectObj.PNG

Let’s optimize this thing with a better way to do this, we just only pass that property of the object on which we want to trigger render of our component, e.g.

useEffectObj1.PNG

useReducer hook

Let’s take a look at another hook. If you are familiar with Redux then useReducer hook is very easy to understand but if you are not still don’t worry it is actually easy to grasp.

Let’s learn about this hook.

When you have a complex state and your state has many subproperties, then useReducer hook is always preferable instead of useState hook.

useReducer hook also supports deep updates because of a dispatch callback function, which triggers the updates using actions, which we will discuss later.

The useReducer hook accepts two arguments the reducer function and the initial state object and it returns an array of two items which are state and a dispatch function.

reducer1.PNG

A) state (First item in useReducer returned array)

This state object always has an updated state, we use this state in our component, another thing is we can’t update the state by using this state item, for updating the state we need to dispatch an action first.

B) dispatch function (Second item in useReducer returned array)

The dispatch is an function that dispatch an action. By using the dispatch function we can update the state. The dispatch function takes an action object that tells the reducer function which property of the state will be affected.

dispatchWithActionObj.PNG

C) reducer function

The reducer is a javascript function that takes two parameters the current state and the action object, this reducer function depends on the action object by using the action object the reducer function update the state, and the reducer function always makes a copy of the state object and update only the requested property in an immutable manner.

Reducer.PNG

D) initial state

The initial state is the value the state is initialized with, or we can say the initial state has the default value of the state

InitailState.PNG

Once we apply all the above points the component will look like this.

WholeComponent.PNG

useMemo hook

The useMemo is a hook that returns a memoized value.

The useMemo hook always holds a memory for preventing a recomputation.

The useMemo hook takes two parameters: the memoized function that will compute some operation and in the second parameter it takes a dependent array that contains parameters for memoization. The compute function will only run in the condition of change dependent array value if the dependent array values remain same so the useMemo hook returns the last value the one useMemo had before, useMemo hook contains this value as cached value; e.g.

UseMemo.PNG

In the above example the expensiveFunction will only run in the condition of propA or propB change.

Call function without refrencing it

When you call a function in an event, so it will behave like an infinite loop operation and the result will look like this

callingFunctionError.png

This condition usually happens when you call a function in a event without referencing it e.g

CallFunctionWithoutreference.PNG

Change this syntax in the following manner;

CorrectSyntax.PNG

In the above syntax onClick event only initializes the reference of the onClick handler function this way we can prevent recursive component rendering.

Using React fragments

If you have worked with React before, you will know that React requires wrapping the components with a single parent element. Though it’s not directly about rendering, have you known that it affects the overall component rendering time?

As a solution, you can use React Fragments to wrap the components, and it will reduce the load on the DOM overall, resulting in faster rendering times and decreased memory usage.

ReactFragment.PNG

Wait Wait, I hope you guys learn these techniques to prevent unnecessary re-renderings, Now I have two questions for you all, give me the answers in the comments below;

1) Can you initialize the state from a function? Provide an example

2) Why we update state using setState or useState second parameter, why can’t we update state directly?

Conclusion

In this article, I have discussed six ways for preventing unnecessary rendering in React components.

In addition, these ways will improve your application performance and prevent user frustration with waits or hangs.

Thanks for reading, I hope you have found this useful.

An image uploaded to Strapi
Mohd Aatif

Senior Software Developer