天天看点

React Hook详解+案例尝试Hook解决的问题先决认知:function组件与class组件的区别已有Hook(典型)Hook使用关于自定义Hook官方Hook🔗

目录

  • Hook解决的问题
  • 先决认知:function组件与class组件的区别
  • 已有Hook(典型)
    • 1、useState
    • 2、useEffect(两种模式)
      • (1) Effects Without Cleanup
      • (2) Effects With Cleanup
  • Hook使用
  • 关于自定义Hook
  • 官方Hook🔗

Hook解决的问题

需要为function组件添加state,但不想重写function组件为class组件时使用Hook真香~

先决认知:function组件与class组件的区别

组件预编译

class方案可能带来的问题:

1、不能很好压缩;

2、热重载不稳定;

3、不易于优化。

已有Hook(典型)

1、useState

  • 推荐使用时机:为函数组件增加state,避免重写函数组件为类组件
  • state更新特点:与setState不同的是,hook更新state是 r e p l a c e \color{red}{replace} replace而非merge

2、useEffect(两种模式)

(1) Effects Without Cleanup

  • scene:需要在react更新DOM之后运行一些额外的code。
  • class components:render方法不应该造成side effects,时间过早。通常我们期望在react更新DOM后执行effects。所以class components中我们将side effects放在componentDidMount和componentDidUpdate。
  • 需求: 每 次 r e n d e r 触 发 \color{red}{每次render触发} 每次render触发。
  • 现状:class components无相应功能方法。提取方法后仍需要在componentDidMount 和 componentDidUpdate调用两次。
  • 现有解决方案:useEffect(将组件内相关的副作用组织在一起,避免拆分到不同的生命周期)。
  • 其他可应用场景:data fetching, and so on。
  • 我care的问题点:

    a: Why is useEffect called inside a component?

    —— 及时获取changes(无需单独的API);

    —— hooks包含js闭包,避免在js已经提供解决方法的地方引入特殊的react API;

    b: Does useEffect run after every render?

    ——YES!

(2) Effects With Cleanup

  • scene: 某些情况下我们需要对外部的数据进行subscription,此类情况为避免memory leak,cleanup尤为重要。
  • class components: componentDidMount里订阅,componentWillUnmount里卸载, Hook一次搞定。
  • 使 用 注 意 \color{red}{使用注意} 使用注意:需要return.

Hook使用

  • 禁 用 地 方 \color{red}{禁用地方} 禁用地方:loop、conditions、nested functions.
  • 集中更新逻辑仍然建议使用redux reducer,但可将reducer也封装成Hook(官方useReducer)。

关于自定义Hook

自定义hook使用一种重用有状态逻辑机制( a m e c h a n i s m t o r e u s e s t a t e f u l l o g i c \color{red}{a mechanism to reuse stateful logic} amechanismtoreusestatefullogic),所有state、effects都是孤立的(isolated)。

官方Hook🔗

  • Basic Hooks
    • useState
    • useEffect
    • useContext
  • Additional Hooks
    • useReducer
    • useCallback
    • useMemo
    • useRef
    • useImperativeHandle
    • useLayoutEffect
    • useDebugValue