DEV Community

Cover image for Day 56 of #100DaysOfCode: Avoid useless re-rendering with React.memo for the customized hooks
Jen-Hsuan Hsieh
Jen-Hsuan Hsieh

Posted on • Edited on

Day 56 of #100DaysOfCode: Avoid useless re-rendering with React.memo for the customized hooks

1. Introduction

I create a React hook recently which is called use-react-monitor. It can help us to monitor endpoints for the specified interval and reset the interval when it changes.

  • We have to install the package in the first step
npm install use-react-monitor -S
Enter fullscreen mode Exit fullscreen mode
  • We can use the hook for endpoints that we want to monitor to
import React from 'react';
import useMonitor from 'use-react-monitor';

const Tester = () => {
    const interval = 3000;
    const {results, status, lastTimes} = useMonitor(
        { urls:['http://rem-rest-api.herokuapp.com/api/users',
                'http://rem-rest-api.herokuapp.com/api/users'],
          freshRate: interval});

    return (
        <>
            {<Results results = {results} status = {status}/>}
        </>
    )
}

const Results = ({ results, status}) => {
    const refCount = React.useRef(0);
    refCount.current++;
    return (
        <div>
        <p>
       {`render time: ${refCount.current}`}
        </p>
        {results && results.map((result, i) =>{
            return (
                <>
                    <div key={`status-${i}`}>Status: {status && status[i]}</div>
                    <ul key={i}>
                        {result.data.map((r, index) => {
                            return (<li key={index}>{r.id} {r.firstName} {r.lastName}</li>)
                        })}
                    </ul>
                </>)
        })}
     </div>
    );
};

export default Tester
Enter fullscreen mode Exit fullscreen mode
  • Then it can polling to fetch the resources from endpoints. Now we add useRef to check if the child was re-rendered even though the fetched result was unchanged.
const Results = ({ results, status}) => {
    const refCount = React.useRef(0);
    refCount.current++;
    return (
        <div>
        <p>
       {`render time: ${refCount.current}`}
        </p>
        ...
    )
};
Enter fullscreen mode Exit fullscreen mode
  • We found that the child component was re-rendered whenever use-react-monitor return the value. However, what we expect is that the child component was re-rendered only when use-react-monitor return new values.

Alt Text

2. Avoid useless re-rendering with React.memo

React.memo is a HOC. We can pass our child component with the compare function and React.memo will perform shallow comparing.
The wrapped child component will only be re-rendered when use-react-monitor return new values.

Compare function

function monitoredPropsAreEqual(prevResults, nextResults){
    return JSON.stringify(prevResults) === JSON.stringify(nextResults);
}
Enter fullscreen mode Exit fullscreen mode

Wrap the child component with React.memo

import React, {memo} from 'react';
const Tester = () => {
    const interval = 3000;
    const {results, status, lastTimes} = useMonitor(
        { urls:['http://rem-rest-api.herokuapp.com/api/users',
                'http://rem-rest-api.herokuapp.com/api/users'],
          freshRate: interval});

    return (
        <>
            {<MemorizedResults results = {results} status = {status}/>}
        </>
    )
}
const MemorizedResults = memo(Results, monitoredPropsAreEqual);
Enter fullscreen mode Exit fullscreen mode

Result

Alt Text

That's it!

Side projects

There are some of my articles. Feel free to check if you like!

References

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay