美文网首页React
React Hooks:usePrevious

React Hooks:usePrevious

作者: CondorHero | 来源:发表于2021-07-28 17:36 被阅读0次
React Hooks:usePrevious

今日内容要点

  1. 认识类的组件的 componentDidUpdate
  2. 实现 usePrevious hook
  3. 结合 TypeScript 封装 usePrevious
  4. 总结

前言

在项目中某些情况下,我们必须知道组件的先前状态,通过对比状态去做一些事情。

在类组件编程中,我们可以通过 componentDidUpdate 这个生命周期钩子来做到实现,但函数组件却没有这个功能,所以我们需要自己编写自定义的逻辑来实现这个功能。

我们暂且把这个组件叫做 usePrevious(),顺便说一下,它甚至可能最终出现在下一个 React 版本中,请看 官方 React 文档中所述

认识类的组件的 componentDidUpdate

componentDidUpdate 的经典模版语法长成下面这样:

componentDidUpdate(prevProps, prevState, snapshot) {
    // 典型用法 一定要出现 if 条件语句,否则容易死循环:
}

componentDidUpdate() 会在更新后会被立即调用,首次渲染不会执行此方法。当组件更新后,可以在此处对 DOM 进行操作。

一般我们会在此对更新前后的 props 进行了比较,选择在此处进行网络请求。(例如,当 props 未发生变化时,则不会执行网络请求)。

componentDidUpdate(prevProps) {
    // 典型用法(不要忘记比较 props):
    if (this.props.userID !== prevProps.userID) {
        this.fetchData(this.props.userID);
    }
}

有时,我们还会在 componentDidUpdate 中直接调用 setState(),但一定一定要注意它必须被包裹在一个条件语句里不然会导致死循环或导致额外的重新渲染,虽然用户不可见,但会影响组件性能

componentDidUpdate 生命周期钩子,它按以下顺序接受以下参数:

  • prevProps 一个包含 props 先前值的对象
  • prevState 包含先前状态值的对象
  • snapshot 接收 getSnapshotBeforeUpdate 生命周期方法返回的值,如果没有返回值则是未定义 undefined。

实现 usePrevious hook

在函数式组建中,没有任何自带的钩子可以让我们获得之前的状态,但是我们可以使用 useRef() 这个 API 实现类似的功能。

创建一个名为 usePrevious.jsx 的新文件,内容如下:

import { useRef, useEffect } from "react";

const usePrevious = value => {
    const ref = useRef();
    // useEffect 是副作用,所以会先执行 return ,然后在执行 useEffect,ref.current 的值正好完了一步。
    useEffect(() => {
        ref.current = value;
    });

    return ref.current;
};

export default usePrevious;

使用案例:

const Counter = () => {
    const [value, setValue] = React.useState(0);
    const lastValue = usePrevious(value);

    return (
        <div>
            <p>
                Current: {value} - Previous: {lastValue}
            </p>
            <button onClick={() => setValue(value + 1)}>Increment</button>
        </div>
    );
};

在这我们能明显的感觉到 usePrevious 相对于 componentDidUpdate 的简单易维护。

结合 TypeScript 封装 usePrevious

如果项目支持 TypeScript,我们还需要向自定义钩子添加一些类型:


import { useRef, useEffect } from "react";

const usePrevious = <T>(value: T): T | undefined => {
    const ref = useRef<T>();
    
    useEffect(() => {
        ref.current = value;
    });
  
    return ref.current;
};

export default usePrevious;

简单的添加了函数泛型和联合类型。

总结

在本文中,我们学习了如何在 React 中获取功能组件的先前状态,对于类组件可通过 componentDidUpdate 来实现,在函数组件中需要基于内置的 useRef 创建了自定义 usePrevious hook,如果是 React 的项目,我们还为 usePrevious 添加了类型校验。

2021-07-28 17:35

相关文章

  • React Hooks:usePrevious

    今日内容要点 认识类的组件的 componentDidUpdate 实现 usePrevious hook 结合 ...

  • React Hooks

    React Hooks Hooks其实就是有状态的函数式组件。 React Hooks让React的成本降低了很多...

  • react-hooks

    前置 学习面试视频 总结react hooks react-hooks react-hooks为函数组件提供了一些...

  • React Hooks

    前言 React Conf 2018 上 React 提出了关于 React Hooks 的提案,Hooks 作为...

  • 5分钟简单了解React-Hooks

    首先附上官网正文?:React Hooks Hooks are a new addition in React 1...

  • react-hooks

    react-hooks react-hooks 是react16.8以后,react新增的钩子API,目的是增加代...

  • React-hooks API介绍

    react-hooks HOOKS hooks概念在React Conf 2018被提出来,并将在未来的版本中被...

  • React Hooks 入门

    React Hooks 是 React v16.8 版本引入了全新的 API。 React Hooks 基本概念 ...

  • react hooks 源码分析 --- useState

    1. react hooks简介 react hooks 是react 16.8.0 的新增特性,它可以让你在不编...

  • React Hooks的入门简介

    什么是React Hooks? 首先React Hooks是React生态圈里的新特性,它改变了传统react的开...

网友评论

    本文标题:React Hooks:usePrevious

    本文链接:https://www.haomeiwen.com/subject/dyizmltx.html