React Hooks常见用法
背景
React在v16中推出了一项重大更新: Hooks. 以往在React组件开发中, 往往要区分函数式组件和类组件的定义和使用, 函数式组件纯展示无副作用, 类组件里面可以保存状态
但在Hooks推出后, 函数式组件除了在某些特殊场景下无法使用(ErrorBoundary/getSnapshotBeforeUpdate), 其他情况下都可以完美替代Class组件了, 今天来看看它是如何替换的
生命周期
先来看看React 16的最新生命周期, 和之前版本相比有些小的调整, 旧版的可以参考这一份文章, 主要是去掉了部分方法和和并了一些获取props更新的方法
去掉的方法
componentWillMountcomponentWillUpdatecomponentWillReceiveProps
这些方法的功能都被统一集中到了getDerivedStateFromProps中, 同时还新增了getSnapshotBeforeUpdate来解决异步渲染时的dom操作问题, 总体大的生命周期还是一致的

Hooks
先根据React官方文档简单介绍一下各Hooks函数的作用
Basic Hooks
useState: 保存状态, 状态变化时会触发重新渲染useEffect: 监听值变化useContext: 跨组件传值, 状态变化时会触发重新渲染
Additional Hooks
useReducer:useState的高级版, 更适合管理复杂状态useCallback: 局部缓存, 往往用于缓存函数useMemo: 局部缓存, 往往用于缓存值useRef: 获取一个脱离于生命周期的指针, 可以设置为任何值, 修改不会触发重新渲染useImperativeHandle: 用于包装函数式组件的父组件获取到的引用值(父组件调用子组件方法), 需要配合forwardRef一起使用useLayoutEffect:useEffect的升级版, 在React实际渲染之前触发, 会阻塞渲染, 用于特殊情况下减少页面闪烁useDebugValue: 与React开发者工具配合调试时使用, 可以用来显示状态等
模拟生命周期
constructor
一般在constructor里都是初始化state或者从props里读取某些值, 在函数式组件里可以直接使用, 不需要特殊处理, 初始化state可以使用setState
1 | const [nameState, setNameState] = useState(props.name); |
componentDidMount
1 | useEffect(() => { |
componentWillReceiveProps
1 | useMemo(() => { |
shouldComponentUpdate
1 | useCallback(() => { |
componentWillUnmount
1 | useEffect(() => { |
componentDidUpdate
这是实现起来比较复杂的一个方法, 需要结合多个Hooks才能满足条件
1 | const mounted = useRef(); |
其他场景
和上一次值对比
1 | import { useEffect, useRef, DependencyList } from 'react'; |
提供方法给父组件调用
1 | const C = forwardRef((props, ref) => { |
获取内部节点
1 | const divRef = useRef < HTMLDivElement > null; |
错误处理
错误处理只有类组件才能实现, 在项目中往往在最外层和各容器层包裹一个通用错误处理组件即可
1 | class ErrorBoundary extends Component<{}, { hasError: boolean }> { |
React Hooks常见用法

