【发布时间】:2019-08-24 20:49:03
【问题描述】:
Rules of Hooks 要求在每次渲染时都以相同的顺序调用相同的钩子。如果您违反此规则,则会出现错误的解释。例如这段代码:
function App() {
console.log('render');
const [flag, setFlag] = useState(true);
const [first] = useState('first');
console.log('first is', first);
if (flag) {
const [second] = useState('second');
console.log('second is', second);
}
const [third] = useState('third');
console.log('third is', third);
useEffect(() => setFlag(false), []);
return null;
}
输出到控制台
render
first is first
second is second
third is third
render
first is first
third is second
并导致警告或错误。
但是在元素生命周期内不改变的条件呢?
const DEBUG = true;
function TestConst() {
if (DEBUG) {
useEffect(() => console.log('rendered'));
}
return <span>test</span>;
}
这段代码并没有真正违反规则,而且似乎工作正常。但它仍然会触发 eslint 警告。
此外,基于props编写类似的代码似乎是可能的:
function TestState({id, debug}) {
const [isDebug] = useState(debug);
if (isDebug) {
useEffect(() => console.log('rendered', id));
}
return <span>{id}</span>;
}
function App() {
const [counter, setCounter] = useState(0);
useEffect(() => setCounter(1), []);
return (
<div>
<TestState id="1" debug={false}/>
<TestState id="2" debug={true}/>
</div>
);
}
此代码按预期工作。
那么当我确定它不会改变时,在条件中调用钩子是否安全?是否可以修改 eslint 规则来识别这种情况?
问题更多是关于真正的需求,而不是实现类似行为的方式。据我了解,这很重要
确保每次组件都以相同的顺序调用 Hook 呈现。这就是允许 React 正确保存 多个 useState 和 useEffect 调用之间的挂钩
这条规则有一个例外:“不要在循环、条件或嵌套函数中调用 Hooks”。
【问题讨论】:
标签: javascript reactjs eslint react-hooks