我正在创建一个日历日期选择功能组件,以便在React应用程序中为日程安排分配日期,我希望能够使用现有数据预填充日历,以便用户可以对其进行修改。
这是我到目前为止所拥有的:
const initialOptions: { [key: string]: number[] } = {};
for (const option of Object.keys(props.options)) {
const dates = props.options[option].dates;
initialOptions[option] = dates ? dates : [];
}
const [selectedDates, setSelectedDates] = useState(initialOptions);
但是,当我尝试渲染页面时,我得到了:
React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks
通读了react rules of hooks之后,我没有看到任何指示React取决于参数的 value 的信息,以“将本地状态与[my useState()呼叫]”。它真正说的只是...
只要渲染之间的Hook调用顺序相同,React便可以将某些本地状态与每个渲染相关联。
那么,当我按自己的规则在任何条件语句或函数之外的顶级反应代码中调用useState()
时,为什么反应会向我抱怨?
答案 0 :(得分:1)
对this question的评论基本上说,对任何响应结构的调用都必须先于 ,即使它们是不相关的正确的方向。
尽管我需要处理selectedDates
的初始值,如果我提供了初始值并且在< / strong>我打电话给useState()
是为了将其作为参数传递。
尽管对此感到困惑,而且此解决方案有点荒谬(对于两个几乎不相关的代码,顺序应该无关紧要,正确?),我还是设法重构了自己的逻辑,都停止了对抱怨的回应 并且允许我仍然有条件地在我的响应日历组件中设置selectedDates
。
这就是我最终得到的:
const initialOptions: { [key: string]: number[] } = {};
Object.entries(props.options).forEach(value => {
const [id, options] = value;
if (options.dates) {
initialOptions[id] = options.dates;
}
});
const [selectedDates, setSelectedDates] = useState(initialOptions);
作为一个不熟悉react的内部知识的人,似乎是:
总的来说,我的结论是,通过调用for
来代替.forEach()
循环,ESLint
插件将我的循环视为 function 而不是控件结构/条件,并允许我的代码通过测试并可以正常运行。
现在,as a self-described "junior" react developer,我非常确定,诱使ESLint不要给出这样的错误不是一个好的长期解决方案。理想情况下,ESLint规则可能需要更新以更好地检查是否有条件使用了不正确的条件,和/或对React文档进行了示例更新,以了解如何以不违反react Hook规则的方式有条件地设置hook的默认值。
编辑:我为react文档创建了一个issue,以便找到解决该问题的长期解决方案,并获取文档和/或ESLint插件必要时更新