zustand/docs/guides/prevent-rerenders-with-use-shallow.md
Danilo Britto e414f7ccf4
fix(shallow): Extract shallow vanilla and react (#2097)
* Update readmes

* Splitting shallow in two modules

* Update tests

* Minor changes

* Minor changes

* Rename shadow.tests.tsx to shallow.test.tsx

* Add new entrypoint for shallow/react

* Update structure

* Update shallow to export from vanilla and react

* Add vanilla/shallow and react/shallow entrypoints

* Update tests

* Update readmes

* Update src/shallow.ts

Co-authored-by: Daishi Kato <dai-shi@users.noreply.github.com>

* Minor changes

* Update readmes

* Update readmes

* Update tests

* Minor changes

---------

Co-authored-by: Daishi Kato <dai-shi@users.noreply.github.com>
2023-10-05 23:04:56 +09:00

1.7 KiB

title nav
Prevent rerenders with useShallow 16

When you need to subscribe to a computed state from a store, the recommended way is to use a selector.

The computed selector will cause a rererender if the output has changed according to Object.is.

In this case you might want to use useShallow to avoid a rerender if the computed value is always shallow equal the previous one.

Example

We have a store that associates to each bear a meal and we want to render their names.

import { create } from 'zustand'

const useMeals = create(() => ({
  papaBear: 'large porridge-pot',
  mamaBear: 'middle-size porridge pot',
  littleBear: 'A little, small, wee pot',
}))

export const BearNames = () => {
  const names = useMeals((state) => Object.keys(state))

  return <div>{names.join(', ')}</div>
}

Now papa bear wants a pizza instead:

useMeals.setState({
  papaBear: 'a large pizza',
})

This change causes BearNames rerenders even tho the actual output of names has not changed according to shallow equal.

We can fix that using useShallow!

import { create } from 'zustand'
import { useShallow } from 'zustand/react/shallow'

const useMeals = create(() => ({
  papaBear: 'large porridge-pot',
  mamaBear: 'middle-size porridge pot',
  littleBear: 'A little, small, wee pot',
}))

export const BearNames = () => {
  const names = useMeals(useShallow((state) => Object.keys(state)))

  return <div>{names.join(', ')}</div>
}

Now they can all order other meals without causing unnecessary rerenders of our BearNames component.