首页 > 解决方案 > 关于 useSelector 相等性检查

问题描述

我有一个关于 redux useSelector 相等性检查的问题。

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

useSelector 将对返回值和前一个值做参考比较,如果结果不同,则强制重新渲染

我有一个像这样的默认博客商店状态

searcherParam: {
  keyword: '',
  categories: [],
  tags: [],
},

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

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

如果我调度一个动作来更新具有相同值的 searcherParam,组件将重新渲染,因为返回值是对象(浅比较)

所以我通过多次调用 useSelector 来检索值

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 的值进行调度,所以它是相同的参考...

这是codesandbox,对不起愚蠢的问题Q_Q

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

标签: reactjsreduxreact-reduxreact-hooks

解决方案


所以当你这样做时:

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

这仅仅意味着,您希望获得它们中的每一个的最新值。

它不会转化为:

searcherParam: {
  keyword: newKeyword,
  categories: newCategories,
  tags: newTags,
},

因为searcherParam在调度操作时将始终是一个新的引用。

如果您只想重新渲染,如果 3 个属性中的任何一个发生更改,那么您可以简单地获取state.searcherParam和调度并实现重新渲染。

当您只想在keyword更改时重新渲染时,获取单个属性会有所帮助。您不想在其中一个cateogoriestags已更改时重新渲染。

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

这就是文档所提到的。


在评论中讨论后。

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

编辑 redux-useSelector-useDispatch-Sample


推荐阅读