react-stable-ref 🤷♂️
Your stable reference utility library with everything you need to test, visualize and protect against the dreaded unintentional rerender 😱
Get started 🏗
Installation
npm install --save react-stable-ref
or yarn add react-stable-ref
Example
const UnstableButton: FC<ButtonProps> = onClick children // Unstable reference (unstableArray is reassigned on every render) const unstableArray = '1' '2' '3'; const stableValue = 'Im stable because im a string'; ; // Triggers re-renders every second ; /** * Will output the following to the console (or onChange if you pass it in) * * > [useWhichDepChanged]: { unstableArray: { from: [1, 2, 3]; to: [1, 2, 3]}} */ return <button ="button" => children </button> ;;
Motivation 🧠
It's not always obvious unstable references are passed into hooks such as useEffect
. This can cause unnecessary rerenders, which when left unchecked can decrease the performance of your app, cause jank and ultimately degrade your user's experience 😭.
Thankfully the React team have already thought about this and provided lint rules to help 🥰. But what if you're passing objects and arrays into dependency arrays which are not 'deeply' compared? How can you know for sure?
react-stable-ref
fills that gap and provides an assortment of utilities to help test, visualize and protect against the dreaded re-render 😱.
API 🤖
useStableRefTester()
A development only hook, which increments state over a predefined interval, triggering rerenders in your component.
Arguments:
- timeout:
Number
Timeout between rerenders
Returns:
count: Number
Example:
const UnstableButton = children const myArray = '1' '2' '3'; ; ; return <button>children</button>;;
useWhichDepChanged()
A development only hook which emits (via console) which prop triggered an update. Useful when you are unsure which property changed in a useEffect
dependency array.
Inspired by: useWhyDidYouUpdate
Arguments:
- dependencies:
Object
A dependency object which mirrors the dependency array of the hook you are trying to test - onChange(changedDeps):
(changedDeps: Obj) => void
A callback which is fired when a dependency is changed.
Returns:
void
Example:
const UnstableButton = children const myArray = '1' '2' '3'; ; return <button>children</button>;;
useRenderCount()
A hook which returns how many times it has been rendered.
Arguments:
- initialCount:
Number
Initial counter value
Returns:
- count:
Number
Current counter value
Example:
const RenderCounter = const count = ; return <button>count</button>;;
<RenderCount />
A visual component that keeps track of the number of renders that have occurred.
Props:
- initialCount:
Number
Initial counter value - count:
Number
Provide a count for a controlled API
useDeeplyComparedEffect()
Coming soon...
A react hook for deeply comparing objects and arrays passed into its dependency array.
useCustomComparedEffect()
Coming soon...
A react hook to allow you to provide custom methods used to comparing dependencies and trigger an effect.
Thanks 😍
Huge thank you to Pablo Stanley and contributors of Open Peeps for the logo.