Skip to content

使用 useShallow 防止重新渲染

¥Prevent rerenders with useShallow

当你需要从存储订阅计算状态时,推荐的方法是使用选择器。

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

如果输出根据 Object.is 发生变化,则计算选择器将导致重新渲染。

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

在这种情况下,如果计算值始终浅等于前一个值,你可能需要使用 useShallow 来避免重新渲染。

¥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.

js
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:

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

此更改导致 BearNames 重新渲染,即使 names 的实际输出没有根据浅相等而改变。

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

我们可以使用 useShallow 解决这个问题!

¥We can fix that using useShallow!

js
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>
}

现在他们都可以订购其他餐点,而不会导致我们的 BearNames 组件不必要的重新渲染。

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

Zustand v5.0 中文网 - 粤ICP备13048890号