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
- 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
- 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> ... ) };
- 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.
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); }
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);
Result
That's it!
Side projects
There are some of my articles. Feel free to check if you like!
- My blog-posts for software developing
- My web resume
- Facebook page
- My website
- npm package - create-nrs-web
- npm package - use-react-monitor
- npm package - react-ui-gauge-component
Top comments (0)