Creating Own useMemo hook in React | useMemo Hook Polyfill
Sandeep Singh
Elite Freelancer | Top Computer Science Voice@Linkedin | I build Scalable Web Apps & SaaS Solutions for your business | 3+ years of experience | Typescript | AWS | React | Nextjs | Node.js Full Stack Developer
Introduction to useMemo Hook
In React, optimization plays a crucial role in ensuring the smooth and efficient performance of applications.
One of the optimization techniques provided by React is the useMemo hook.
This hook is used to memoize expensive calculations, preventing unnecessary re-renders of components.
When dealing with complex computations or heavy data processing, useMemo can significantly enhance performance by caching the results and only recomputing them when the dependencies change.
How useMemo Works
The useMemo hook takes two arguments: a callback function and an array of dependencies.
It calculates the memoized value based on the provided callback function and the dependencies array.
If any of the dependencies change between renders, useMemo will recompute the value; otherwise, it returns the cached value from the previous render.
Creating a Custom useMemo Hook Polyfill
To understand how useMemo works internally and create a custom polyfill for it, let's examine the code snippet provided:
//----------------------- useCustomMemo() --------------------------
import { useRef, useEffect } from "react"
const checkChanges = (prevDeps, deps) => {
if(prevDeps === null) return false
if (prevDeps?.length !== deps.length) return false;
for (let i = 0; i < deps.length; i++) {
if (prevDeps[i] !== deps[i]) return false;
}
return true;
}
export const useCustomMemo = (callback, deps) => {
//variable or state -> for storing cached Values
const memoizedRef = useRef(null) // useRef because it will persist the value throughout lifecycle of the component
//changes in deps
if (!memoizedRef.current || !checkChanges(memoizedRef?.current?.deps, deps)) {
memoizedRef.current = {
value: callback(), // will run and return the value and get stored
deps: deps
}
}
//cleanup logic
useEffect(()=>{
return ()=>{
memoizedRef.current = null
}
},[])
//return the result
return memoizedRef.current.value;
}
In the provided code snippet, useCustomMemo is a custom hook designed to replicate the functionality of useMemo.
领英推荐
It utilizes useRef to persist the memoized value throughout the component's lifecycle. The check changes function compares the previous dependencies with the current ones to determine if recalculation is necessary.
Explanation of Code
Implementing the Custom useMemo Hook Polyfill
Now, let's see how to use the custom useCustomMemo hook in a React component:
//----------------------- App.jsx -------------------------------
import { useCallback, useMemo, useState } from "react"
import { useCustomMemo } from "../pollyfills/useCustomMemo";
export const Memoize = () =>{
const [counter, setCounter] = useState(0);
const [counter2, setCounter2] = useState(100);
const heavyCalcs = () =>{
console.log("heavy Calcs... ", counter2)
return counter*counter;
}
// const havyCalcs2 = useCallback(heavyCalcs,[counter])
const havyCalcs2 = useCustomMemo(heavyCalcs, [counter] )
return(
<div>
<p>This is counter value: {havyCalcs2}</p>
<button onClick={()=>{
setCounter(state => state+1)}}>Increment</button>
<p>This is counter2 value: {counter2}</p>
<button onClick={()=>{setCounter2(state => state-1)}}>Decrement</button>
</div>
)
}
In the Memoize component, useCustomMemo is utilized to memoize the heavyCalcs function based on the counter dependency. This ensures that the heavy computations are only performed when necessary, optimizing the performance of the component.
Conclusion
Creating a custom useMemo hook polyfill allows developers to gain a deeper understanding of how memoization works in React. By replicating the functionality of built-in hooks like useMemo, developers can customize optimization techniques to suit specific project requirements, enhancing performance and user experience.
FAQs