在使用Hooks的过程中,需要注意的两点是:
-
不要在循环,条件或嵌套函数中调用Hook,必须始终在React函数的顶层使用Hook。这是因为React需要利用调用顺序来正确更新相应的状态,以及调用相应的钩子函数。一旦在循环或条件分支语句中调用Hook,就容易导致调用顺序的不一致性,从而产生难以预料到的后果。
-
只能在React函数式组件或自定义Hook中使用Hook。
为了避免我们无意中破坏这些规则,你可以安装一个eslint插件:
npm install eslint-plugin-react-hooks --save-dev
并在配置文件中使用它:
{
"plugins": [
// ...
"react-hooks"
],
"rules": {
// ...
"react-hooks/rules-of-hooks": "error"
}
}
Hooks嵌套多个,代码的执行顺序:
其实我个人的理解是,因为hook本质上是函数,而函数在执行栈中的执行顺序是后进先出,也就是说要从最内层的hook开始执行,连同useEffect中的也都是最内层的先执行。
来看代码:
函数式组件ADemo中调用了useSetMyState这个hook,在useSetMyState又嵌套了useInnerState这个hook,具体的代码如下:
const ADemo = () => {
const [my, setMy] = useSetMyState();
console.log('***22', 22, my);
useEffect(() => {
console.log('**外层hook*', 33, my);
// setMy('Nice to meet you!')
// console.log('***44', 44, my);
}, [])
return (
<div>
ADemo.tsx
<Button>传递给B组件参数</Button>
</div>
);
};
export default ADemo;
Hook2:
export function useSetMyState() {
const [hello, setHello] = useState<string>();
useInnerState();
useEffect(() => {
console.log('***内层hook**', 0, hello);
}, [])
console.log('***11', 11, hello);
return [hello, setHello]
}
Hook3:
export function useInnerState() {
const [status, setStatus] = useState<string>();
console.log('***inner**00', status);
useEffect(() => {
console.log('***最内层hook**', status);
}, []);
return [status, setStatus]
}
来看一下最终在控制台中展现的结果:
都是最内层的hook先执行的。
以上就是本次分享啦,关注一下代码的执行顺序。