React Hooks 使用详解

文章目录

    • 一、Hooks 简介
    • 二、Hooks 初体验
    • 三、常用的两个 Hooks
      • 1、useState
        • 语法
        • 与在类中使用 `setState` 的异同点:
        • 使用对比
        • 优化
      • 2、useEffect
        • 语法
        • 使用对比
        • 优化 useEffect
    • 四、其他 Hoos API
      • 1、useContext
        • 语法
        • 用法
        • 注意事项
      • 2、useReducer
        • 语法
        • 用法
        • 优化:延迟初始化
        • 与 useState 的区别
      • 3、useCallback
        • 语法
      • 4、useMemo
        • 语法
        • 用法
      • 5、useRef
        • 语法
        • 使用
      • 6、useLayoutEffect
        • 语法
      • 用法
    • 五、尝试编写自定义 Hooks
      • 1、编写自定义 useReducer
      • 2、使用自定义 useReducer
    • 五、Hooks 使用及编写规范
    • 六、使用 React 提供的 ESLint 插件
      • 安装 ESLint 插件
      • 在 .eslintrc 中使用插件
    • 七、参考文档

本文对 16.8 版本之后 React 发布的新特性 Hooks 进行了详细讲解,并对一些常用的 Hooks 进行代码演示,希望可以对需要的朋友提供点帮助。

一、Hooks 简介

HooksReact v16.7.0-alpha 中加入的新特性。它可以让你在 class 以外使用 state 和其他 React 特性。
本文就是演示各种 Hooks API 的使用方式,对于内部的原理这里就不做详细说明。


二、Hooks 初体验

Example.js

import React, {
    useState  } from 'react';

function Example() {
   
    // 声明一个名为“count”的新状态变量
    const [count, setCount] = useState(0);

    return (
        <div>
            <p>You clicked {
   count} times</p>
            <button onClick={
   () => setCount(count + 1)}>
                Click me
            </button>
        </div>
    );
}

export default Example;

useState 就是一个 Hook,可以在我们不使用 class 组件的情况下,拥有自身的 state,并且可以通过修改 state 来控制 UI 的展示。


三、常用的两个 Hooks

1、useState

语法

const [state, setState] = useState(initialState)

  • 传入唯一的参数: initialState,可以是数字,字符串等,也可以是对象或者数组。
  • 返回的是包含两个元素的数组:第一个元素,state 变量,setState 修改 state值的方法。
与在类中使用 setState 的异同点:
  • 相同点:也是异步的,例如在 onClick 事件中,调用两次 setState,数据只改变一次。
  • 不同点:类中的 setState 是合并,而函数组件中的 setState 是替换。
使用对比

之前想要使用组件内部的状态,必须使用 class 组件,例如:

Example.js

import React, {
    Component } from 'react';

export default class Example extends Component {
   
    constructor(props) {
   
        super(props);
        this.state = {
   
            count: 0
        };
    }

    render() {
   
        return (
            <div>
            <p>You clicked {
   this.state.count} times</p>
            <button onClick={
   () => this.setState({
    count: this.state.count + 1 })}>
                Click me
            </button>
            </div>
        );
    }
}

而现在,我们使用函数式组件也可以实现一样的功能了。也就意味着函数式组件内部也可以使用 state 了。

Example.js

import React, {
    useState } from 'react';

function Example() {
   
    // 声明一个名为“count”的新状态变量
    const [count, setCount] = useState(0);

    return (
        <div>
            <p>You clicked {
   count} times</p>
            <button onClick={
   () => setCount(count + 1)}>
                Click me
            </button>
        </div>
    );
}

export default Example;
优化

创建初始状态是比较昂贵的,所以我们可以在使用 useState API 时,传入一个函数,就可以避免重新创建忽略的初始状态。

普通的方式:

// 直接传入一个值,在每次 render 时都会执行 createRows 函数获取返回值
const [rows, setRows] = useState(createRows(props.count));

优化后的方式(推荐):

// createRows 只会被执行一次
const [rows, setRows] = useState(() => createRows(props.count));

2、useEffect

之前很多具有副作用的操作,例如网络请求,修改 UI 等,一般都是在 class 组件的 componentDidMount 或者 componentDidUpdate 等生命周期中进行操作。而在函数组件中是没有这些生命周期的概念的,只能 return 想要渲染的元素。
但是现在,在函数组件中也有执行副作用操作的地方了,就是使用 useEffect 函数。

语法

useEffect(() => { doSomething });

两个参数:

  • 第一个是一个函数,是在第一次渲染以及之后更新渲染之后会进行的副作用。

    • 这个函数可能会有返回值,倘若有返回值,返回值也必须是一个函数,会在组件被销毁时执行。
  • 第二个参数是可选的,是一个数组,数组中存放的是第一个函数中使用的某些副作用属性。用来优化 useEffect

    • 如果使用此优化,请确保该数组包含外部作用域中随时间变化且 effect 使用的任何值。 否则,您的代码将引用先前渲染中的旧值。
    • 如果要运行 effect 并仅将其清理一次(在装载和卸载时),则可以将空数组([])作为第二个参数传递。 这告诉React你的 effect 不依赖于来自 props 或 state 的任何值,所以它永远不需要重新运行。

虽然传递 [] 更接近熟悉的 componentDidMountcomponentWillUnmount 执行规则,但我们建议不要将它作为一种习惯,因为它经常会导致错误。

使用对比

假如此时我们有一个需求,让 document 的 title 与 Example 中的 count 次数保持一致。

使用 class 组件:

Example.js

import React, {
    Component } from 'react';

export default class Example extends Component {
   
    constructor(props) {
   
        super(props);
        this.state = {
   
            count: 0
        };
    }

    componentDidMount() {
   
        document.title = `You clicked ${
      this.state.count } times`;
    }

    componentDidUpdate() {
   
        document.title = `You clicked ${
      this.state.count } times`;
    }

    render() {
   
        return (
            <div>
            <p>You clicked {
   this.state.count} times</p>
            <button onClick={
   () => this.setState({
    count: this.state.count 

你可能感兴趣的:(前端开发,React,前端开发,React,Hooks)