官方 Hook
userState
**const [todo, setTodo] = userState([])**
- 函数组件具有维持状态的能力
- 遵行一个原则:state 中永远不要保存可以通过计算得到的值(props,URL,本地缓存(cookie,localStorage))
useEffect
**useEffect(callback, deps)**
- 用于执行一段副作用
useEffect
是每次组件render
完之后判断依赖并执行
模拟生命周期 componentDidMount - [] componentDidUpdate - 无依赖 componentWillUnMount - return fn
useReducer
Redux
:是应用中统一管理状态的问题 但通过和useReducer
的配合使用,可以实现类似Redux
的作用。
useState
的替代方案。它接收一个形如(state, action) => newState
的reducer
,并返回当前的state
以及与其配套的dispatch
方法。(如果你熟悉Redux
的话,就已经知道它如何工作了。)- 在某些场景下,
useReducer
会比useState
更适用,例如state
逻辑较复杂且包含多个子值,或者下一个state
依赖于之前的state
等。并且,使用useReducer
还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递dispatch
而不是回调函数 。
useCallback
**useCallback(fn, deps)**
缓存回调函数
- 返回一个
memoized
回调函数,我的理解即返回一个函数的句柄,等同于函数的变量,因此你可以使用memoizedCallback()
进行执行该函数或者传递给事件和子组件,这里可以推荐绝大多数事件或者子组件的方法使用useCallback
,避免组件更新重复渲染。 - 因此
useCallback
中的doSomething
并不会在定义时就执行,而是需要手动调用返回的memoizedCallback
才是真的执行。 - 简单理解为
useCallback
定义了一个函数,仅在deps
发生变化时重新定义该函数,否则该函数的变量不会变化,事件和子组件内容也就不用重新绑定或者渲染。
useMemo
**useMemo(fn, deps)**
原理与
**class**
组件的**PureComponent**
优化原理相同,对**props**
进行了浅比较
- 作为性能优化的手段(缓存数据,避免重复计算,避免子组件的重复渲染)
useRef
**const myRefContainer = useRef(initialValue)**
多次渲染之间共享数据
useRef
返回一个可变的ref
对象,其.current
属性被初始化为传入的参数(initialValue
)。返回的ref
对象在组件的整个生命周期内保持不变。常见访问子组件
useContext
**const value = usecontext(context)**
定义全局状态
useContext
可以帮助我们跨越组件层级直接传递变量,实现共享。- 需要注意的是
useContext
和redux
的作用是不同的!!! - 解决的问题就是组件之间传递的问题
useImperativeMethods
useMutationEffect
useLayoutEffect
- 其函数签名与
useEffect
相同,但它会在所有的DOM
变更之后同步调用effect
。可以使用它来读取DOM
布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect
内部的更新计划将被同步刷新。
自定义 Hook
Hook 规则
hook
的操作基本可以分为mount
阶段(mountWorkInProgressHook
)和update
阶段(updateWorkInProgressHook
)。mount
阶段,初始化新到hook
。update
阶段,将current fiber
的hook
克隆到work-in-progress fiber
中。
只在最顶层使用 Hook
不要在循环,条件或嵌套函数中调用
**Hook**
, 确保总是在你的**React**
函数的最顶层以及任何**return**
之前调用他们。
官网解释:https://zh-hans.reactjs.org/docs/hooks-rules.html#explanation 从源码角度解释的话:
updateWorkInProgress
的主要功能是获取当前保存在fiber
的hooks
链表中对应的hook
节点对象。
- 挂载阶段,将会形成一个
Hooks
链表,其中包含StateHook、EffectHook、MemoHook
等,每个Hook
中存贮的memoizedState
信息不一样。 - 在更新阶段,通过
updateWorkInProgress
从current memoizedState
的Hooks
链表中取出对应的hook
,如果hook
放到了if
条件语句中,会导致链表结构被破坏,导致更新操作发生异常。
只在 React 函数中调用 Hook
小技巧
使用多了发现一个
tips
useCallback 与 useMemo
useCallback
的功能是可以用useMemo
来实现的- 两者从本质上讲,做了相同的事情:建立绑定某个结果到依赖的数据关系,只有依赖变了,结果才需要从新计算。
副作用 side effect
记得以前在公司刚引进 hooks 时,发现同事在讨论如何避免副作用,我觉得有点匪夷所思。 觉得我们应该想要避免的是:错误的代码逻辑,错误的思维理念;而对于副作用,应该考虑的不是避免,应该是更如何合理的它。
题外话:在进行代码开发的时候发现,有如下两种常见:
- 习惯添加 memo
- 几乎不用 mem