关于reactjs:关于useSelector相等性检查

About useSelector equality check

我对redux useSelector相等性检查有疑问。

请参阅React Redux Hook文档(https://react-redux.js.org/api/hooks#equality-comparisons-and-updates)

useSelector将与返回值和前一个值进行参考比较,如果结果看起来不同,则强制重新呈现

我具有这样的默认博客存储状态

1
2
3
4
5
searcherParam: {
  keyword: '',
  categories: [],
  tags: [],
},

在组件中,我使用useSelector检索值

1
const searchParam = useSelector(state => state.Blog.searcherParam)

如果我分派一个动作来更新具有相同值的searcherParam,则该组件将重新呈现,因为返回值是对象(浅比较)

因此我通过多次调用useSelector来检索值

1
2
3
const keyword = useSelector(state => state.Blog.searchrParam.keyword)
const categories = useSelector(state => state.Blog.searchrParam.categories)
const tags = useSelector(state => state.Blog.searchrParam.tags)

然后我调度一个动作再次用相同的值更新searcherParam

该组件将不会重新渲染

我不明白的是为什么组件不重新渲染?

如果useSelector进行引用比较,则分派后的类别值(数组)和标签也不应是同一引用

我有什么误会吗?谢谢

不重新渲染的原因是因为我通过useState保存了类别(来自redux存储)。

并使用useState的值进行分派,因此它是相同的引用...

这是codeandbox,对于愚蠢的问题Q_Q

,我们深表歉意。

https://codesandbox.io/s/useselector-test-u6pvg


因此,当您执行此操作时:

1
2
3
const newKeyword = useSelector(state => state.Blog.searchrParam.keyword)
const newCategories = useSelector(state => state.Blog.searchrParam.categories)
const newTags = useSelector(state => state.Blog.searchrParam.tags)

这只是意味着,您将希望具有每个值的最新值。

它不翻译成这样:

1
2
3
4
5
searcherParam: {
  keyword: newKeyword,
  categories: newCategories,
  tags: newTags,
},

因为searcherParam将始终是分派操作时的新引用。

如果您只想重新渲染,则3个属性中的任何一个都发生了更改,那么您可以简单地获取state.searcherParam并进行分派并实现重新渲染。

如果只想在keyword更改时重新呈现,

获取单个属性会有所帮助。 cateogoriestags中的任何一个更改后,您都不想重新渲染。

在这种情况下,请注意,如果您仅获取searcherParam,则它不会关心3个属性中的哪个已更改,因为它是一个新引用,您将获得重新渲染。

这就是文档中提到的内容。

在评论中讨论之后。

实现了一个简单的实现。检查以下

Edit


可以通过解构searchrParam对象来获得所有这些属性,而不是单独选择上述属性:

1
2
3
const { newKeyword, newCategories, newTags } = useSelector(
     state => state.Blog.searchrParam
)