react-stable-ref
Version:
An assortment of utilities for testing against unstable references in React
168 lines (105 loc) • 5.02 kB
Markdown
<p align="center">
<img width="300" src="./assets/logo.png" alt="Test stable references">
</p>
[](https://www.npmjs.com/package/react-stable-ref)
[](https://www.npmjs.com/package/react-stable-ref)
[](https://www.npmjs.com/package/react-stable-ref)
Your stable reference utility library with everything you need to test, visualize and protect against the dreaded unintentional rerender 😱
[](https://danieldelcore.github.io/react-stable-ref/)
**Installation**
`npm install --save react-stable-ref` or `yarn add react-stable-ref`
```jsx
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';
useStableRefTester(); // Triggers re-renders every second
useWhichDepChanged({ unstableArray, stableValue });
/**
* 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 type="button" onClick={onClick}>
{children}
</button>
);
};
```
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](https://www.npmjs.com/package/eslint-plugin-react-hooks) 🥰. 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 😱.
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:**
```jsx
const UnstableButton = ({ children }) => {
const myArray = ['1', '2', '3'];
useStableRefTester();
useEffect(() => {
console.warn('I should not be called on every render');
}, [myArray]);
return <button>{children}</button>;
};
```
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](https://usehooks.com/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:**
```jsx
const UnstableButton = ({ children }) => {
const myArray = ['1', '2', '3'];
useWhichDepChanged({ myArray, children }, onChange(changedDeps) => {
console.log('UnstableButton: ', changedDeps); // UnstableButton: myArray
});
return <button>{children}</button>;
};
```
A hook which returns how many times it has been rendered.
**Arguments:**
- initialCount: `Number` Initial counter value
**Returns:**
- count: `Number` Current counter value
**Example:**
```jsx
const RenderCounter = () => {
const count = useRenderCount();
return <button>{count}</button>;
};
```
A visual component that keeps track of the number of renders that have occurred.
<p align="left">
<img width="200" src="./assets/rendercount.png" alt="Render count component">
</p>
**Props:**
- initialCount: `Number` Initial counter value
- count: `Number` Provide a count for a controlled API
_Coming soon..._
A react hook for deeply comparing objects and arrays passed into its dependency array.
_Coming soon..._
A react hook to allow you to provide custom methods used to comparing dependencies and trigger an effect.
Huge thank you to [Pablo Stanley](https://twitter.com/pablostanley) and contributors of [Open Peeps](https://www.openpeeps.com/?ref=react-stable-ref) for the logo.
- [Introducing Hooks](https://reactjs.org/docs/hooks-intro.html)
- [Making Sense of React Hooks](https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889)
- [When to useMemo and useCallback](https://kentcdodds.com/blog/usememo-and-usecallback/)