In this article series, we embark on a journey through the realm of custom React hooks, discovering their immense potential for elevating your development projects. Our focus today is on the "useDeepCompareEffect" hook, one of the many carefully crafted hooks available in the collection of React custom hooks.
Github: https://github.com/sergeyleschev/react-custom-hooks
import { useEffect, useRef } from "react"
import isEqual from "lodash/fp/isEqual"
export default function useDeepCompareEffect(callback, dependencies) {
const currentDependenciesRef = useRef()
if (!isEqual(currentDependenciesRef.current, dependencies)) {
currentDependenciesRef.current = dependencies
}
useEffect(callback, [currentDependenciesRef.current])
}
Managing dependencies in React can be a challenge, especially when dealing with complex data structures or nested objects. That's where the useDeepCompareEffect custom hook comes in handy. Created to tackle the limitations of the default useEffect hook, useDeepCompareEffect ensures that the effect callback is only triggered when the dependencies have deeply changed, using lodash's isEqual function for accurate comparison.
One of the key advantages of useDeepCompareEffect is its ability to prevent unnecessary re-renders. By performing a deep comparison between the current and previous dependencies, the hook intelligently determines if the effect should be triggered, leading to optimized performance in scenarios where shallow comparisons fall short.
This custom hook can be especially useful when dealing with complex state objects, such as when you have deeply nested data structures or multiple interconnected states that need to be tracked. It enables you to define dependencies that accurately reflect the specific changes you want to track, ensuring that the effect is executed only when it is absolutely necessary.
import { useEffect, useState, useRef } from "react"
import useDeepCompareEffect from "./useDeepCompareEffect"
export default function DeepCompareEffectComponent() {
const [age, setAge] = useState(0)
const [otherCount, setOtherCount] = useState(0)
const useEffectCountRef = useRef()
const useDeepCompareEffectCountRef = useRef()
const person = { age: age, name: "Sergey" }
useEffect(() => {
useEffectCountRef.current.textContent =
parseInt(useEffectCountRef.current.textContent) + 1
}, [person])
useDeepCompareEffect(() => {
useDeepCompareEffectCountRef.current.textContent =
parseInt(useDeepCompareEffectCountRef.current.textContent) + 1
}, [person])
return (
<div>
<div>
useEffect: <span ref={useEffectCountRef}>0</span>
</div>
<div>
useDeepCompareEffect: <span ref={useDeepCompareEffectCountRef}>0</span>
</div>
<div>Other Count: {otherCount}</div>
<div>{JSON.stringify(person)}</div>
<button onClick={() => setAge(currentAge => currentAge + 1)}>
Increment Age
</button>
<button onClick={() => setOtherCount(count => count + 1)}>
Increment Other Count
</button>
</div>
)
}
You can easily incorporate useDeepCompareEffect into your React components by importing it and utilizing it in place of the traditional useEffect hook. By passing the effect callback and an array of dependencies, you can ensure that your effect runs efficiently and effectively.
Full Version | React Custom Hooks:
https://dev.to/sergeyleschev/supercharge-your-react-projects-with-custom-hooks-pl4
Top comments (0)