前言
面试官:看你简历写的熟悉React,那你跟我说说为什么 hooks 不能放在条件语句和循环语句里面?
🤖 有图有真相(代码 + 图)
function App() {
useEffect(() => {
console.log("你好,我是 useEffect")
})
const ref = useRef("许泽川")
useLayoutEffect(() => {
console.log("你好,我是 useLayoutEffect")
})
const [state, setState] = useState(true);
function handleClick() {
setState(false)
}
return <div onClick={handleClick}></div>
}
🤖 面试的时候应该怎么回答?
- 每一个组件对应一个
fiber
,他的fiber.memoizedState
存储了一条hook
链表。
- 当组件(
<App />
)对应的fiber
第一次创建出来后,react
会调用对应的组件函数(App()
)拿到jsx
来创建子fiber
。当组件函数执行的时候,运行到useEffect()
或者useState()
这些hook
,会在组件(<App />
)的fiber.memoizedState
按照hooks
的执行先后顺序,创建一个个的hook
对象串成一条链表,每一个hook
对象里面存储了一些初始化信息(比如useState
的hook
对象存了他的值,useEffect
的hook
对象存了要执行的副作用,useRef
的hook
对象存了ref
)。
- 之后通过
setState
触发重渲染,函数组件重新执行,运行到useEffect()
或者useState()
这些hook
,又会从这条链表按顺序从头到尾取对应的hook
对象出来使用(useEffect
取完对应的hook
,链表前进一步,useState
取对应的hook
。。。。。。)
- 如果我们使用了
if
或者while
语句,你猜一下会发生什么?可能会导致拿到错误的hook
对象,比如useEffect
拿到了useState
的hook
对象,那肯定不行了。因为不同的hook
对象是为对应的hook
准备的,他里面存储的数据都不同,怎么能随便拿来用呢?
版权归许泽川所有
如需转载,请提前询问本人的许可