Re-rendering React Components and the conditions that force components to re-render

Before delving into the topic, there are a few definitions we need to know in order to understand our topic.


React is a declarative JavaScript library used to create effective user interfaces from isolated, small chunks of code called components. React is created by Facebook and used to construct single page applications.


Components are isolated, reusable pieces of code. While working independently and returning HTML, they accomplish the same task as JavaScript functions. Class components and Function components are the two sorts of components.To instruct React on what we want to display on the screen, we utilize components. React will update and re-render components when data changes.


Render means updating the appropriate portion of the information on the user's screen when there are changes in state and props.


Re-rendering refers to a second or subsequent render that updates the state.


Let's take a deep dive into the topic.


Re-rendering React components


Any time the state or props of a React component change, the component automatically re-renders.React JS is a JavaScript library that is available as open source and is used to create user interfaces for single-page apps, as is well known. Additionally, it is renowned for offering a quick user experience by just updating the UI elements that have changed.


React calls the rendering of components as part of the React Component Lifecycle at various phases of the app, usually when the React Component is first constructed. Rendering components is not in the user's control.


All User Interface (UI) elements are automatically re-rendered when the state of the code is simply updated from anywhere.Re-rendering may occur for any of the following three reasons:


  1. Update in state

The state change for updating a variable may come through a prop or setState change. React updates the component's state after it receives it, reflecting the change on the app. When the state of a React component changes, React must call the render() method.


class App extends React.Component {

  componentDidMount() {

    this.setState({});

  }


  render() {

    console.log('render() method')

     return <h1>Hi!</h1>;

  }

}

When the component mounts, as in the aforementioned example, I update the state.

A component can also be re-rendered in response to an event, such a click event.


class App extends React.Component {

  state = {

    mssg: ""

  };


  handleClick = () => {

    this.setState({ mssg: "Hi there!" });

  };


  render() {

     console.log("render() method");

     return (

       <>

        <button onClick={this.handleClick}>Say something</button>

        <div>{this.state.mssg}</div>

       </>

     );

  }

}

Both outputs are:

  1. Update in prop

Changes to the prop cause state changes, which cause React to re-render the component.


class Child extends React.Component {

  render() {

     console.log('Child component: render()');

     return {this.props.message};

   }

}


class App extends React.Component {

   state = {

    mssg: ""

   };


   handleClick = () => {

     this.setState({ mssg: "Hi there!" });

   };


   render() {

     return (

      <>

         <button onClick={this.handleClick}>Say something</button>

         <Child message={this.state.mssg} />

       </>

     );

   }

}

In the aforementioned example, the <Child /> component does not have state, but it does have a custom prop called "message" that it will take.

The Child /> component will be updated and required to run the render() lifecycle once more when the button is clicked.

Output:


What if your component depends on a different factor other than just your state or property? Since React might not have recognised the change in that situation, you might need to force the component to be updated.


Let's look at how this forced update can be applied to a React component.


The forceUpdate() method

The forceUpdate() method is a built-in method of class components for re-rendering a component. This is used to make a component render again.shouldComponentUpdate() will not be called when calling forceUpdate(), which renders the component instead.


shouldComponentUpdate() is a lifecycle method in React. This makes the component to re-render only when there is a change in state or props of a component and the change will affect the output.If there is no need to apply a new render, your component can leave the update lifecycle using the shouldComponentUpdate() method.


Keep in mind: Relying on components being updated via the forceUpdate() method is not advised.When this function becomes necessary, you should first try to examine your code to see if there is another explanation for why React is failing to update the component.This may be the result of a bug, or you may be able to fix it by reorganizing your code so that React can correctly re-render the component on its own.


import React from 'react'


class App extends React.Component {

     constructor() {

         super();

         this.handleForceupdateMethod = this.handleForceupdateMethod.bind(this);

     };


     handleForceupdateMethod() {

         this.forceUpdate();

     };


     render() {

         return (

             <div>

                 <h1>Hello StackAbuse</h1>

                 <h3>Random Number: { Math.random() }</h3>

                 <button onClick={this.handleForceupdateMethod}>

                     Force re-render

                 </button>

             </div>

         );

     }

}


export default App


This method involves a lot more than it may seem. For instance, using forceUpdate() also activates the child components' lifecycle functions. Additionally, React will only update the DOM if the markup has truly changed, as is well known.


The useState() hook

There isn't a forceUpdate method for re-rendering in Functional Components. So you can use the useState() hook or create a custom hook to force a component for re-rendering in functional components.


// forceUpdate hook

function useForceUpdate() {

   const [value, setValue] = useState(0);

   return () => setValue((value) => value + 1);

}


// component

function App() {

   const forceUpdate = useForceUpdate();


  return (

     <div>

       <button onClick={forceUpdate}>

         Change Number

       </button>

       <h4>Random Number : { Math.random() }</h4>

     </div>

   );

}


Why the Component Isn't Updating: Troubleshooting

Let's examine some of the typical problems that cause React to stop updating your components and find fixes for them as well.

1. An inaccurate state update

Let's think about the following illustration:


const App = () =>  {

   const [user, setUser] = useState({ name: "", age: 0, });


   const updateUser = () => {

     user.name = "Tom";

     setUser(user)

   }


   return (

     <>

       <h2>Name: {user.name}</h2>

       <button onClick={updateUser}>

         Update User

       </button>

     </>

   );

}

Even if the Update User button is clicked, the App component won't render the user's name again.

React assesses state modifications by examining their shallow equality (also known as reference equality), which determines if the old and new values of state reference the same object. In our example, we changed a property of the user object, but since setUser was technically the same object reference, React didn't notice the change in the object's state.

State should be viewed as immutable, as stated in the React documentation.How then do we correct it? The changed values might be used to construct a new object:

  const updateUser = () => {

     setUser({

       ...user,

       name: "Tom",

    })

   }


2.Mistakenly Updated Props (without state change)

Bugs might also result from incorrectly updating props without a state change.Let's examine an illustration:

let time = new Date();

// setInterval(() => {

//   console.log(time)

// }, 1000);


const App = () =>  {

   useEffect(() => {

     const intervalId = setInterval(() => {

       time = new Date()

     }, 1000);

     return () => clearInterval(intervalId);

   }, []);


   return (

     <Clock time={time} />

   );

}

After the initial load, the clock in the sample doesn't update the time. Just un-comment the console.log to verify that the time is being changed correctly. The runtime will update the variable time every second, and our clock component will then display that information.

When the state changes, the parent component, App, is re-rendered, which causes the child component, Clock, to be re-rendered with the new time. As a result, re-rendering is actually caused by updating state, which is then propagated through the props. Therefore, updating the state is Vital!

So we might utilise the following to resolve the problem:

const App = () =>  {

   const [time, setTime] = useState(new Date());

   useEffect(() => {

     const intervalId = setInterval(() => {

       setTime(new Date());

     }, 1000);

     return () => clearInterval(intervalId)

   }, [])


   return (

     <Clock time={time} />

   );

}


Wrapping up

React components automatically re-render whenever their state or props change. Every time a state changes, React schedules a render (scheduling a render doesn't mean it happens right away; it could take some time and be done at the right time).

Always update a React component's state and properties if you need to re-render it. Never use forceUpdate() to force a re-render.If you find that this function is required, you should first try to look at your code to see if there is another reason why React is not updating the component. You might be able to remedy this by rearranging your code so that React can appropriately re-render the component on its own, or it might be the consequence of a bug.


Unnecessary re-renders reduce an app's performance and drain the user's battery, neither of which are things that any user would like.


There are a few specialised situations where forcing a re-render makes sense to retrieve the most recent data from the blockchain, such as when changing a blockchain (which only returns a transaction hash and no data).


Thank you for your time!




Comments

Popular posts from this blog

DataDog vs. AWS CloudWatch: Choosing the Best Observability Tool

Redis Tutorial: Exploring Data Types, Architecture, and Key Features