redux 为什么useSelector()带有条件EslintError

np8igboo  于 2022-11-24  发布在  其他
关注(0)|答案(2)|浏览(213)

为什么这会违反Hooks规则?
在我的例子中:

const getTopicId = useSelector((state) => state.topics.selectTopic.topicId) !== "" ? useSelector((state) => state.topics.selectTopic.topicId) : JSON.parse(localStorage.getItem("topic")).topicId;

我没有在useSelector中放置条件,我尝试说如果useSelector()有数据,就使用它,如果没有,就使用localStorage数据。
接受EsLint解决方案是:把useSelector放在一个变量里面,然后放在三进制里面......但是我不明白为什么。

const getTopicSelector = useSelector((state) => state.topics.selectTopic.topicId);

 const getTopicId = useSelector((state) => state.topics.selectTopic.topicId) !== "" ? getTopicSelector : JSON.parse(localStorage.getItem("topic")).topicId

谢谢你的解释。

8wtpewkr

8wtpewkr1#

您的代码有时调用useSelector一次,有时调用两次。
如果你把

const getTopicId = useSelector((state) => state.topics.selectTopic.topicId) !== "" ? useSelector((state) => state.topics.selectTopic.topicId) : JSON.parse(localStorage.getItem("topic")).topicId;

然后将三进制重写为if..else,您可以清楚地看到:

let getTopicId;
const conditionTopicId = useSelector((state) => state.topics.selectTopic.topicId)
if (conditionTopicId !== "") {
  getTopicId = useSelector((state) => state.topics.selectTopic.topicId)
} else {
  getTopicId = JSON.parse(localStorage.getItem("topic")).topicId
};

有时你调用一个钩子一次,有时两次。这违反了钩子的规则,从长远来看会使React崩溃。
在您的情况下,您可以将其改写为非常简单的内容:

let getTopicId = useSelector((state) => state.topics.selectTopic.topicId)
if (getTopicId == "") {
  getTopicId = JSON.parse(localStorage.getItem("topic")).topicId
}

突然间,你只叫了一次钩子--而且你没有条件地这样做。
您也可以使用三元,并将逻辑放在一个钩子调用中:

const getTopicId = useSelector(
  (state) => 
    state.topics.selectTopic.topicId !== "" ? 
      state.topics.selectTopic.topicId :  
      JSON.parse(localStorage.getItem("topic")).topicId
  )

所有这些替代方案都很好--唯一重要的是:不要在条件内调用useSelector(三元组只是编写if...else的一种简短方法)。
React不允许这样做,如果你这样做,它迟早会崩溃在你身上。

iszxjhcz

iszxjhcz2#

useSelector返回与从本地存储发送的任何值都不兼容的特定类型
处理这种情况的最佳方法是添加单独的useMemo变量

const {selectTopic} = useSelector((state) => state.topics)

const getTopicId  = useMemo(() => {
   return  selectTopic.topicId !== "" ? getTopicSelector : JSON.parse(localStorage.getItem("topic")).topic
}, [selectTopic])

相关问题