官方 Hook

userState

**const [todo, setTodo] = userState([])**

  • 函数组件具有维持状态的能力
  • 遵行一个原则:state 中永远不要保存可以通过计算得到的值(props,URL,本地缓存(cookie,localStorage))

    useEffect

    **useEffect(callback, deps)**

  • 用于执行一段副作用

  • useEffect 是每次组件 render 完之后判断依赖并执行

    useReducer

    Redux:是应用中统一管理状态的问题 但通过和 useReducer 的配合使用,可以实现类似 Redux 的作用。

  • useState 的替代方案。它接收一个形如 (state, action) => newStatereducer,并返回当前的 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 可以帮助我们跨越组件层级直接传递变量,实现共享。

  • 需要注意的是 useContextredux 的作用是不同的!!!
  • 解决的问题就是组件之间传递的问题

    useImperativeMethods

    useMutationEffect

    useLayoutEffect

  • 其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。

    自定义 Hook

Hook 规则

hook 的操作基本可以分为 mount 阶段(mountWorkInProgressHook)和 update 阶段(updateWorkInProgressHook)。 mount 阶段,初始化新到 hookupdate 阶段,将 current fiberhook 克隆到 work-in-progress fiber 中。

只在最顶层使用 Hook

不要在循环,条件或嵌套函数中调用 **Hook**, 确保总是在你的 **React** 函数的最顶层以及任何 **return** 之前调用他们。

官网解释:https://zh-hans.reactjs.org/docs/hooks-rules.html#explanation
从源码角度解释的话:

updateWorkInProgress的主要功能是获取当前保存在 fiberhooks 链表中对应的 hook 节点对象。

  • 挂载阶段,将会形成一个 Hooks 链表,其中包含 StateHook、EffectHook、MemoHook 等,每个 Hook 中存贮的 memoizedState 信息不一样。
  • 在更新阶段,通过 updateWorkInProgresscurrent memoizedStateHooks 链表中取出对应的 hook,如果 hook 放到了 if 条件语句中,会导致链表结构被破坏,导致更新操作发生异常。

    只在 React 函数中调用 Hook

小技巧

使用多了发现一个 tips

useCallback 与 useMemo

  • useCallback 的功能是可以用 useMemo 来实现的
  • 两者从本质上讲,做了相同的事情:建立绑定某个结果到依赖的数据关系,只有依赖变了,结果才需要从新计算。

题外话:在进行代码开发的时候发现,有如下两种常见:

  1. 习惯添加 memo
  2. 几乎不用 mem