React useCallback钩子的作用方法demo

 更新时间:2022年12月13日 17:06:20   作者:Jovie  
这篇文章主要为大家介绍了React useCallback钩子的作用方法demo,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

简介

如果你还不熟悉钩子的概念,请务必查看本文章,因为它对钩子的概念提供了一个非常好的、深入的概述,以及一些钩子的例子。

useCallback 钩子是用来缓存一个记忆化的回调函数,以节省任何重新计算的开销。

这个钩子可以阻止一个组件重新渲染,除非它的道具发生了变化,这意味着我们现在可以隔离资源密集型的函数,这样它们就不会在每个组件渲染时自动运行。

最好是展示一个有利于使用该钩子的场景,这样我们就能更好地理解我们为达成一个问题所采取的步骤,然后再解释使用useCallback 钩子背后的思考过程。

项目概述

我们将从搭建一个全新的React项目的脚手架开始。首先,我们将创建一个新的项目目录,之后,我们将使用终端初始化一个新项目。

在这个过程中,你可以使用npmnpx或者yarn。你要运行的命令是:

  • npmnpm init react-app app-name
  • npx: npx create-react-app app-name
  • yarnyarn create react-app app-name

现在我们已经设置好了一切,让我们直接进入有趣的部分。

项目进展

由于这是一个小项目,我们将把所有的代码放在根src 目录下的App.js 文件内,它看起来会是这样的:

import { useState, memo } from "react";
import './App.css';
const Todos = ({ todos, addTodo }) => {
  console.log("child render");
  return (
    <div className="todos-container">
      <h2>My Todos</h2>
      <div className="todos">
        {todos.map((todo, index) => {
          return <p key={index}>{todo}</p>;
        })}
      </div>
      <button onClick={addTodo}>Add Todo</button>
    </div>
  );
};
const MemoizedTodos = memo(Todos);
const App = () => {
  const [count, setCount] = useState(0);
  const [todos, setTodos] = useState([]);
  const increment = () => {
    setCount((c) => c + 1);
  };
  const addTodo = () => {
    setTodos((t) => [...t, "New Todo"]);
  };
  return (
    <div className="App">
      <MemoizedTodos
        todos={todos}
        addTodo={addTodo}
      />
      <hr />
      <div className="counter-container">
        <p>Count: {count}</p>
        <button onClick={increment}>+</button>
      </div>
    </div>
  );
};
export default App;

这里有相当多的东西需要解压,所以让我们看看我们有什么。

首先,我们定义了一个Todos 组件,它的道具是一个todos列表,以及一个函数,一旦被调用,就会添加一个新的todo。这个组件的任务是将todos渲染到屏幕上,并在按下Add Todo 按钮时添加一个新的todo。

然后,我们有其余的App 组件,除了渲染和传递道具给MemoizedTodos 组件外,还在屏幕上显示一个可以递增的计数器。

而为了让一切看起来更好一点,我们还将在我们的App.css 文件中添加以下样式:

.App {
  text-align: left;
  width: 80vw;
  margin: 5vh auto 0 auto;
}

那么,问题出在哪里?

现在,你可能会问自己:"这个应用程序有什么问题?";的确,一切似乎都在正常工作。然而,问题是,每次我们点击+ 按钮来增加计数器时,Todos 组件就会被重新渲染。

我们可以通过检查控制台来检查,每次我们重新渲染Todos 组件时,都会打印到控制台。

意外的Todos 组件的重新渲染

问题的根本原因

你看,在App 组件中,我们定义了addTodo 函数,它将在每次App 组件重新渲染时被重新创建。当App 组件的状态发生变化时,它就会重新渲染,其中包括todos和计数器

我们正在使用[memo](https://reactjs.org/docs/react-api.html#reactmemo),所以Todos 组件不应该重新渲染,因为当计数增加时,todos 的状态和addTodo 的功能都没有改变。

因此,基本上,问题在于addTodo 是定义在App 组件内的,并且在该组件重新生成时被重新创建。

解决方法

实际上,我们有两种方法可以解决这个问题:

  • 通过在App 组件之外定义addTodo 函数。
  • 通过对addTodo 函数的记忆化

虽然第一种方法似乎是明确的解决方案,但我们不能总是依靠将一个函数排除在组件的范围之外,而使其成为一个纯函数。

对函数进行记忆

然后我们再来看看useCallback 钩子,它正是通过对函数进行备忘来解决我们现在面临的这个问题,以避免其重构。

我们所要做的就是从React中导入useCallback 钩子,并将调用钩子的结果与钩子的回调返回的状态更新分配给addTodo 函数,就这样:

const addTodo = useCallback(() => {
  setTodos((t) => [...t, "New Todo"]);
}, []);

而这个轻微的调整应该可以解决我们之前的问题。

现在,如果你想知道为什么我们没有把todos 数组添加到钩子的依赖数组中,那是因为React会拾取状态,因为我们使用的是以回调为参数的setTodos 函数,而不是一个数组值。

如果我们要改变这一点,我们应该看到一个警告。

setState的值而不是回调作为参数

useCallback依赖数组的警告

总结

我希望你喜欢读这篇文章,并希望你对useCallback 钩子是什么,它的作用,以及什么时候应该使用它有了更好的理解。

以上就是React useCallback钩子的作用方法demo的详细内容,更多关于React useCallback钩子的资料请关注脚本之家其它相关文章!

相关文章

  • 利用ES6语法重构React组件详解

    利用ES6语法重构React组件详解

    这篇文章主要介绍了利用ES6语法重构React组件的相关资料,文中通过示例代码介绍的很详细,对大家具有一定的参考借鉴价值,需要的朋友们下面来一起看看吧。
    2017-03-03
  • 详解vant2 自动检查表单验证 -validate

    详解vant2 自动检查表单验证 -validate

    这篇文章主要介绍了vant2 自动检查表单验证 -validate,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • React状态管理Redux原理与介绍

    React状态管理Redux原理与介绍

    redux是redux官方react绑定库,能够使react组件从redux store中读取数据,并且向store分发actions以此来更新数据,这篇文章主要介绍了react-redux的设置,需要的朋友可以参考下
    2022-08-08
  • 详解React中合并单元格的正确写法

    详解React中合并单元格的正确写法

    用表格进行页面布局,页面布局在各种浏览器的的兼容性, 本文主要介绍了详解React中合并单元格的正确写法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • React中setState使用原理解析

    React中setState使用原理解析

    这篇文章主要介绍了React中的setState使用细节和原理解析,主要包括使用setstate的原因及基本用法,本文通过实例代码给大家详细讲解,需要的朋友可以参考下
    2022-10-10
  • ahooks useInfiniteScroll源码解析

    ahooks useInfiniteScroll源码解析

    这篇文章主要为大家介绍了ahooks useInfiniteScroll源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • React调度系统Scheduler工作原理详解

    React调度系统Scheduler工作原理详解

    这篇文章主要为大家介绍了React调度系统Scheduler工作原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • React事件监听和State状态修改方式

    React事件监听和State状态修改方式

    这篇文章主要介绍了React事件监听和State状态修改方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • 详解React 代码共享最佳实践方式

    详解React 代码共享最佳实践方式

    这篇文章主要介绍了React 代码共享最佳实践方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • React hook实现简单的websocket封装方式

    React hook实现简单的websocket封装方式

    这篇文章主要介绍了React hook实现简单的websocket封装方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09

最新评论