reactjs 使用Zustand/React获取多个状态(简写语法)

jk9hmnmh  于 2023-02-12  发布在  React
关注(0)|答案(2)|浏览(388)

从***Zustand***存储中获取状态的两种方法在状态更改时的重新呈现方面是否相同?

文件中描述的方法:

const nuts = useStore(state => state.nuts)
const honey = useStore(state => state.honey)

速记:

const { nuts, honey } = useStore()
xtupzzrd

xtupzzrd1#

简短回答

不,这些方法并不相同。

长答案

如zustand自述文件中所述:
把所有东西都拿来
可以,但请记住,这将导致组件在每次状态更改时更新!
常量状态= useStore()
因此,当您使用选择器选择某些状态切片时,组件将仅在所选值更改时更新/重新呈现。
当您调用useStore()而不传递任何参数时,您实际上是在为组件订阅整个状态,作为一个比喻,您可以说"zustand将要求组件在任何状态更改时更新/重新呈现,状态树中的任何地方"。速记语法中的对象解构只是以更快的方式将变量分配给对象属性的语法糖。useStore()返回(并订阅组件)的值仍然是整个状态。
所以,如果你使用const { nuts, honey } = useStore(),你可能会遇到性能问题,这些问题是否会被注意到取决于应用程序,但我想说,使用选择器很容易,不必担心它。

进一步建议

如果您需要在一个useStore(...)调用中选择所有状态片,推荐的方法是使用合适的选择器。

import shallow from 'zustand/shallow'

// Object pick, re-renders the component when either state.nuts or state.honey change
const { nuts, honey } = useStore(state => ({ nuts: state.nuts, honey: state.honey }), shallow)

// Array pick, re-renders the component when either state.nuts or state.honey change
const [nuts, honey] = useStore(state => [state.nuts, state.honey], shallow)

// Mapped picks, re-renders the component when state.treats changes in order, count or keys
const treats = useStore(state => Object.keys(state.treats), shallow)
cedebl8k

cedebl8k2#

不,它们并不完全相同:第一个将仅在选定属性更改时重新呈现;而第二个将在存储的任何属性改变时重新呈现。
提出这个问题的动机似乎是为了避免使用Zustand获取多个状态的冗长过程(正如ICW也评论的那样,这可能是一个痛苦的过程)。
您可以通过几种不同的方式为多个zustand导入实现更简洁的语法。

选项1

让我们定义这个辅助函数:

function useMulti(useFunc, ...items) {
  return items.reduce((carry, item) => ({
    ...carry,
    [item]: useFunc(state => state[item]),
  }), {})
}

在定义了这个 Package 函数之后,不要编写以下代码:

const {nuts, honey} = useStore(state => ({
  nuts: state.nuts,
  honey: state.honey,
}), shallow)

你可以这样写:

const {nuts, honey} = useMulti(useStore, 'nuts', 'honey')

Package 器函数只是为选择多个状态提供一些语法上的帮助。

  • 注意,在内部,useMulti为每个请求的属性使用单独的useStore调用。因此,状态无效等效于使用zustand/shallow而不使用useMulti
  • 还要注意useMulti只适用于存储的顶级属性:例如,如果您想获取state.x.y.z,则需要更复杂的useMulti实现。

选项2

单独导入它们可能会更简洁。如果您选择许多不同的商店 prop ,尤其如此:考虑:

const {
  media_items,
  selected_media_ids,
  media_items_loading,
  media_items_load_error,
  get_media_items,
  upload_media_items,
  delete_media_items,
  select_media_item,
  toggle_select_media_item,
  set_selected_media_ids,
  select_all_media_items,
} = useDataStore(state => ({
  media_items: state.media_items,
  selected_media_ids: state.selected_media_ids,
  media_items_loading: state.media_items_loading,
  media_items_load_error: state.media_items_load_error,
  get_media_items: state.get_media_items,
  upload_media_items: state.upload_media_items,
  delete_media_items: state.delete_media_items,
  select_media_item: state.select_media_item,
  toggle_select_media_item: state.toggle_select_media_item,
  set_selected_media_ids: state.set_selected_media_ids,
  select_all_media_items: state.select_all_media_items,
}), shallow)

与以下内容(大致等同):

const media_items = useStore(state => state.media_items)
const selected_media_ids = useStore(state => state.selected_media_ids)
const media_items_loading = useStore(state => state.media_items_loading)
const media_items_load_error = useStore(state => state.media_items_load_error)
const get_media_items = useStore(state => state.get_media_items)
const upload_media_items = useStore(state => state.upload_media_items)
const delete_media_items = useStore(state => state.delete_media_items)
const select_media_item = useStore(state => state.select_media_item)
const toggle_select_media_item = useStore(state => state.toggle_select_media_item)
const set_selected_media_ids = useStore(state => state.set_selected_media_ids)
const select_all_media_items = useStore(state => state.select_all_media_items)

本地辅助函数可以很容易地进一步减少每次调用的字符数。

相关问题