React Hooks 学习 - 01 React Hooks 介绍

目录

  • React Hooks 介绍
  • React Hooks 钩子函数的介绍和使用
  • 模拟 React Hooks 钩子函数的实现原理

React Hooks

Reat Hooks 介绍

React Hooks 是 React 16.8 版本新添加的特性,实际上是一堆钩子函数。

React Hooks 主要是增强函数型组件的功能,让函数型组件可以实现类组件相同的功能,例如:

  • 使用和存储 state(状态)
  • 拥有处理副作用的能力

从 React 16.8 版本开始,React 官方推荐开发者使用函数去创建组件。

没有计划从 React 中移除 class,类组件依然可用。

副作用

在一个组件中,只要不是把数据转换成视图的代码,就属于“副作用”,或简称“作用”。例如:

  • 获取 DOM 元素,为 DOM 元素添加事件
  • 设置定时器
  • 发送 ajax 请求

在类组件中,通常使用生命周期函数来处理这些副作用。

在函数型组件中,就要使用 Hooks 来处理副作用。

类组件的不足(Hooks 要解决的问题)

Hook 简介 - 动机

1. 缺少逻辑复用机制

通常情况下,开发者可能会使用 Render Props 或 高阶函数来实现逻辑复用。

这样实现的代码本身是非常复杂的。

通常是在原有组件的外面又包裹了一层组件,这一层组件又没有实际的渲染效果,增加了组件层次,显得十分臃肿。

组件嵌套层级的增加,增加了调试的难度,以及降低了运行效率。

2. 业务逻辑经常会变得很复杂且难以维护

这体现在类组件的生命周期函数中。

  • 将一组相关的业务逻辑拆分到多个生命周期函数中。
  • 在一个生命周期函数中存在多个不相干的业务逻辑。

例如:

  • 在组件挂载时设置事件监听,又要在组件被卸载前清除事件监听
  • 在组件挂载时,获取数据,同时进行其它初始化设置
  • 在组件更新时,对比组件状态中的某个数据

3. 类成员方法不能保证 this 指向的正确性

当给一个元素绑定事件,在事件处理函数中更改状态的时候,通常要更正这个函数中的 this 指向,否则就会指向全局(window),严格模式下则会指向 undefined。

import React from 'react'
class Demo extends React.Component {
  handleClick() {
    console.log(this);
    // 非严格模式 window
    // 严格模式 this
  }
  render() {
    return <button onClick={this.handleClick}>Click</button>
  }
}
export default Demo

这需要开发者理解 JavaScript 中 this 的工作原理。

简单来说,函数中的 this 指向函数的调用者。

当前 click 事件直接绑定了类成员 handleClick 这个函数的引用,在触发时,它的调用者就是全局对象 window,在严格模式下就是 undefined。

开发者通常会使用以下3种方式去更改 this 指向:

  1. 使用箭头函数定义类成员

如果使用箭头函数定义这个成员,那函数内部的 this 就是定义时 this 的指向,即组件实例对象:

handleClick = () => {
  console.log(this);
  // this 指向组件实例对象
}
  1. 使用 bind 更改 this 指向
constructor() {
  this.handleClick = this.handleClick.bind(this)
}

或者

render() {
  return <button onClick={this.handleClick.bind(this)}>Click</button>
}
  1. 箭头函数嵌套(原理同方式1)
render() {
  return <button onClick={() => this.handleClick()}>Click</button>
}

这些方式都使代码变得复杂难以理解和维护。

React Hooks 使用

Hook 意为钩子,React Hooks 就是一堆钩子函数,意思是“钩入” React 特性。

React 通过这些钩子函数对函数型组件进行增强,不同的钩子函数提供了不同的功能:

  • 基础 Hook
    • useState:用于为函数组件引入状态
    • useEffect:让函数型组件拥有处理副作用的能力,类似生命周期函数
    • useContext:在使用 createContext 跨组件层级传递数据时,简化获取数据的代码
  • 额外的 Hook
    • useReducer:另一种让函数组件引入状态的方式
    • useCallback:性能优化 - 缓存函数,使组件重新渲染时得到相同的函数实例
    • useMemo:性能优化 - 监测某个数据的变化,根据变化值计算新值,类似 Vue 中的计算属性
    • useRef:获取 DOM 元素对象、保存跨组件周期的数据
    • useImperativeHandle
    • useLayoutEffect
    • useDebugValue

钩子函数以 use 开头,自定义 Hook 也约定以 use 开头的命名规则,以方便 linter 插件校验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值