reactjs - 避免警告的方法:React 检测到 Hooks 的顺序发生了变化
问题描述
我有一个组件,当应用程序中其他地方的状态发生变化时,它会调度一些操作。但这以某种方式给了我可怕的change in the order of Hooks
错误。
在阅读钩子规则时,它说基本上在条件句中包装钩子是禁止的......我目前没有这样做。
但是,随着服务器加载数据,我正在呈现项目列表并且这些列表的值发生变化。使用选择器和 redux-sagas 使得所有这些都无法实际调试,那么我还能如何追踪问题的根源呢?
我有一个组件:
const PhraseList = props => {
const trainingPhrases = useSelector(selectFilteredPhrases());
return (
<div className={styles.Wrapper}>
<ul className={opStyles.listReset}>
{
trainingPhrases.map((phrase, idx) => {
return PhraseItem({ phrase, idx });
})
}
</ul>
</div>
);
它调用PhraseItem
组件,该组件引发错误。
const PhraseItem = ({ phrase, idx }) => {
// this line chokes
const [checked, setChecked] = useState(false);
return (
<li key={"tr-" + idx}>
<div className={styles.container}>
<div className={styles.phraseText}>{phrase.text}</div>
</div>
</li>
);
};
我正在调试选择器(选择器工厂)中的更改,这似乎是触发应用程序崩溃的原因。
export const selectFilteredPhrases = () =>
createSelector(trainingPhrases, phraseFilter, (trainingPhrases, phraseFilter) => {
console.log('trainingPhrases', trainingPhrases)
return trainingPhrases
});
但是如果数据没有改变,那么很难构建一个应用程序:O
我看到了一个我认为不相关的关于使用 JSX 的答案。在这个问题上没有太多其他内容。
redux, sagas, hooks, selectors...react DSL 层数越来越多,很难在框架中深入调试。
更新。我认为这可能是因为我一个接一个地调用两个 saga,这会导致 UI 中出现某种竞争条件?
const pickIntent = () => {
dispatch(pickIntentAction(intentId));
dispatch(getIntentPhrasesAction(intentId));
解决方案
我认为这个答案是相关的,因为它已经在这个链接中提到,如果你调用 jsx 组件作为一个函数 react 认为,在这个 jsx 函数中声明的钩子是应用程序组件的一部分,所以如果你的数组trainingPhrases
有更少第一次渲染的元素比第二次渲染的元素会导致这个警告(渲染的 jsx 组件会更少,这意味着钩子会更少)。解决方案很简单,像这样调用 jsx 组件<PhraseItem phrase={phrase} idx={idx} />
推荐阅读
- c++ - 使用 Cygwin 的 C++ 中未定义的引用错误,为什么我的文件没有链接?
- java - 打印结果时如何使for循环转到下一行
- r - 使用 R 软件在 shapefile 中重叠(或转换)栅格
- javascript - 如何制作将channelID存储在数据库中的命令?
- file - 我可以在 Ansible vars_files 中创建动态列表吗?
- node.js - Express:在 bcrypt.compare 之前使用 await 会出错
- spring-boot - Spring Boot Kafka 消费者滞后并读错
- c++ - 如何获取指向类(不是对象)的引用/指针?
- python - 在 Visual Studio 中不显示 plotly.graphs_objs
- css - Angular 7 SCSS 不保留 CSS 自定义属性