react hooks--概述

news2024/9/25 15:26:04

前言

Hook 是 React 16.8 的新增特性,它可以让我们在不编写class的情况下使用state以及其他的React特性(比如生命周期)。

我们先来思考一下class组件相对于函数式组件有什么优势?比较常见的是下面的优势:

◼ class组件可以定义自己的state,用来保存组件自己内部的状态;

 函数式组件不可以,因为函数每次调用都会产生新的临时变量;

◼ class组件有自己的生命周期,我们可以在对应的生命周期中完成自己的逻辑;

 比如在componentDidMount中发送网络请求,并且该生命周期函数只会执行一次;

 函数式组件在学习hooks之前,如果在函数中发送网络请求,意味着每次重新渲染都会重新发送一次网络请求;

◼ class组件可以在状态改变时只会重新执行render函数以及我们希望重新调用的生命周期函数componentDidUpdate等;

 函数式组件在重新渲染时,整个函数都会被执行,似乎没有什么地方可以只让它们调用一次;

所以,在Hook出现之前,对于上面这些情况我们通常都会编写class组件。

在react中组件分为类组件和函数组件

类组件:

  • 通过class类去定义组件
  • 类组件有内部state状态,可以通过setState控制组件自身更新渲染
  • 类组件拥有自己的生命周期

class App extends React.Componnet {
    constructor(props) {
        super(props);
    }
    
    click = () => {
        
    }
    
    render() {
        return (
        	<div onClick={this.click}>类组件</div>
        )
    }
}

Class组件存在的问题

复杂组件变得难以理解:

 我们在最初编写一个class组件时,往往逻辑比较简单,并不会非常复杂。但是随着业务的增多,我们的class组件会变得越来越复杂;

 比如componentDidMount中,可能就会包含大量的逻辑代码:包括网络请求、一些事件的监听(还需要在componentWillUnmount中移除);

 而对于这样的class实际上非常难以拆分:因为它们的逻辑往往混在一起,强行拆分反而会造成过度设计,增加代码的复杂度;

难以理解的class:

 很多人发现学习ES6的class是学习React的一个障碍。

 比如在class中,我们必须搞清楚this的指向到底是谁,所以需要花很多的精力去学习this;

 虽然我认为前端开发人员必须掌握this,但是依然处理起来非常麻烦;

组件复用状态很难

 在前面为了一些状态的复用我们需要通过高阶组件;

 像我们之前学习的redux中connect或者react-router中的withRouter,这些高阶组件设计的目的就是为了状态的复用;

 或者类似于Provider、Consumer来共享一些状态,但是多次使用Consumer时,我们的代码就会存在很多嵌套;

 这些代码让我们不管是编写和设计上来说,都变得非常困难;

函数组件

  • 使用函数编写组件
  • 函数组件没有内部state,无法控制自身更新渲染,只能接收外部props数据来更新渲染
  • 函数组件没有生命周期
  • 函数式组件的命名:第一个字母必须大写

function App() {
    
    function click() {
        
    }
    
    return (
        <div onClick={click}>函数组件</div>
    )
}

Hooks概述

随着react版本的更迭,在react16.8版本,新增了hook特性,可以通过hook函数去开发函数组件,使函数组件内部拥有了state内部状态,以及模拟生命周期

Hook只能在函数组件中使用,不能在类组件,或者函数组件之外的地方使用!!!

  • Hooks:钩子、钓钩、钩住
  • HooksReact v16.8 中的新增功能
  • 作用:为函数组件提供状态、生命周期等原本 class 组件中提供的 React 功能
    • 可以理解为通过 Hooks 为函数组件钩入 class 组件的特性
  • 注意:Hooks 只能在函数组件中使用,自此,函数组件成为 React 的新宠儿

React v16.8 版本前后,组件开发模式的对比:

  • React v16.8 以前: class 组件(提供状态) + 函数组件(展示内容)
  • React v16.8 及其以后:
    1. class 组件(提供状态) + 函数组件(展示内容)
    2. Hooks(提供状态) + 函数组件(展示内容)
    3. 混用以上两种方式:部分功能用 class 组件,部分功能用 Hooks+函数组件

注意1:虽然有了 Hooks,但 React 官方并没有计划从 React 库中移除 class。

注意2:有了 Hooks 以后,不能再把函数组件称为无状态组件了,因为 Hooks 为函数组件提供了状态。

为什么要有 Hooks

两个角度:1 组件的状态逻辑复用  2 class 组件自身的问题

  1. 组件的状态逻辑复用:
    • 在 Hooks 之前,组件的状态逻辑复用经历了:mixins(混入)、HOCs(高阶组件)、render-props 等模式。
    • (早已废弃)mixins 的问题:1 数据来源不清晰 2 命名冲突。
    • HOCs、render-props 的问题:重构组件结构,导致组件形成 JSX 嵌套地狱问题。
  1. class 组件自身的问题:
    • 选择:函数组件和 class 组件之间的区别以及使用哪种组件更合适
    • 需要理解 class 中的 this 是如何工作的
    • 相互关联且需要对照修改的代码被拆分到不同生命周期函数中
      • componentDidMount ->  window.addEventListener('resize', this.fn)
      • componentWillUnmount -> window.addEventListener('resize', this.fn)
  • 相比于函数组件来说,不利于代码压缩和优化,也不利于 TS 的类型推导
  • 语法上来说,函数组件学习成本会低一点,函数组件少了this指向和继承
  • 从组件的开发难易程度来说,函数组件相对于类组件来说难度低一点,函数组件少了this指向和继承
  • 类组件的开发基于面向对象方式开发,类与类之间通过继承来达到了一种依赖关系,这种继承的开发方式并不是最好的解决方案

正是由于 React 原来存在的这些问题,才有了 Hooks 来解决这些问题

hooks的优势

由于原来 React 中存在的问题,促使 React 需要一个更好的自带机制来实现组件状态逻辑复用。

  1. Hooks 只能在函数组件中使用,避免了 class 组件的问题
  2. 复用组件状态逻辑,而无需更改组件层次结构
  3. 根据功能而不是基于生命周期方法强制进行代码分割
  4. 抛开 React 赋予的概念来说,Hooks 就是一些普通的函数
  5. 具有更好的 TS  类型推导
  6. tree- - shaking  友 好,打包时去掉未引用的代码
  7. 更好的压缩

项目开发中,Hooks 的采用策略:

  • 不推荐直接使用 Hooks 大规模重构现有组件
  • 推荐:新功能用 Hooks,复杂功能实现不了的,也可以继续用 class
  • 找一个功能简单、非核心功能的组件开始使用 hooks

class 组件相关的 API 不用了,比如:

  • class Hello extends Component
  • componentDidMountcomponentDidUpdatecomponentWillUnmount
  • this 相关的用法

原来学习的内容还是要用的,比如:

  • JSX:{}onClick={handleClick}、条件渲染、列表渲染、样式处理等
  • 组件:函数组件、组件通讯
  • 路由
  • React 开发理念:单向数据流状态提升
  • 解决问题的思路、技巧、常见错误的分析等上

hook函数使用规则
  • 只在 React 函数中调用 Hook,不要在普通的 JavaScript 函数中调用 Hook
  • 只能在最顶层使用 Hook
  • 不要在循环,条件或嵌套函数中调用 Hook,确保总是在你的 React 函数的最顶层调用他们
  • 遵守这条规则,你就能确保 Hook 在每一次渲染中都按照同样的顺序被调用
  • 这让 React 能够在多次的 useStateuseEffect 调用之间保持 hook 状态的正确
  • 不要在class类组件中使用hook函数

hooks 的缺陷

计数器示例

类组件实现
import React, { PureComponent } from 'react'

export default class demoClassComponent extends PureComponent {
  constructor(props) {
    super(props)

    this.state = {
      counter: 0,
    }
  }

  increment() {
    this.setState({
      counter: this.state.counter + 1,
    })
  }

  decrement() {
    this.setState({
      counter: this.state.counter - 1,
    })
  }

  render() {
    const { counter } = this.state

    return (
      <div>
        <p>当前计数:{counter}</p>
        <button onClick={(e) => this.increment()}>+1</button>
        <button onClick={(e) => this.decrement()}>-1</button>
      </div>
    )
  }
}

函数组件实现
import { memo, useState } from 'react'

function DemoFuncClassComponent() {
  const [counter, setCounter] = useState(0)

  return (
    <div>
      <p>当前计数:{counter}</p>
      <button onClick={(e) => setCounter(counter + 1)}>+1</button>
      <button onClick={(e) => setCounter(counter - 1)}>-1</button>
    </div>
  )
}

export default memo(DemoFuncClassComponent)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2138070.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试学习笔记丨Docker 安装、管理、搭建服务

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/32192 容器&#xff08;Docker&#xff09;技术的价值 保证环境一致性&#xff0c;只要使用相同镜像部署就可以保证一致性。轻量级虚拟化访问&#xff0c;运行更快&#xff0c;资源更小。同时…

通用与专用LabVIEW软件版本对比

在LabVIEW开发过程中&#xff0c;通常会根据项目需求设计出通用版本和专用版本两类软件。通用版本适合广泛的测试场合&#xff0c;具有较强的扩展性和适用性&#xff0c;而专用版本则针对特定设备或功能进行定制&#xff0c;提供更高的精确度和效率。两者各有优势&#xff0c;开…

《SpringBoot+Vue》Chapter01_SpringBoot介绍

SpringBoot的介绍 简单来说&#xff0c;SpringBoot就是Spring提供的用于Web开发的脚手架框架。配置简单、上手快速 SpringBoot的特性 自带tomcat、Jetty服务器可以部署war包自动配置Spring框架和第三方框架能够提供应用的健康监控和配置的监控没有代码生成&#xff0c;并且尽可…

新能源汽车充电基础设施大爆发

新能源汽车充电基础设施迈入新阶段&#xff1a;全国总量破千万&#xff0c;未来五年将翻番增长 截至2024年7月底&#xff0c;全国充电设施总量已达到1060万台&#xff0c;为超过2500万辆新能源汽车提供了充电服务。目前&#xff0c;95%的高速公路服务区已具备充电功能&#xf…

OPENAIGC开发者大赛企业组钻石奖 | FilmAction — AI电影创作平台

在第二届拯救者杯OPENAIGC开发者大赛中&#xff0c;涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到&#xff0c;我们特意开设了优秀作品报道专栏&#xff0c;旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者&#xff0c;希望能带给您…

算法练习题27——疫情下的电影院(模拟)

其实思路还好 就是输入有点难搞 Java import java.util.ArrayList; import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);String input scanner.nextLine();// 去掉输入字符串的方括号if (input.…

从大脑图谱/ROI中提取BOLD信号

动机 在功能连接&#xff08;Functional Connectivity&#xff0c;FC&#xff09;构建过程中&#xff0c;由于FC中元素数目是节点数目的平方关系&#xff0c;所以在计算FC之前进行数据降维是一个常见的选择。 一般会将体素级/顶点级BOLD信号&#xff08;在2mm的图像分辨率下大脑…

Python实现一个轮盘抽奖功能(完整代码)

运行后代码图片 python的gui模块 python常用的图形库tkinter、wxpython、pyqt。 tkinter是python自带的图形库&#xff0c;Tkinter 可以在大多数的 Unix 平台下使用&#xff0c;同样可以应用在 Windows 和 Macintosh 系统里。 wxPython 是一款开源软件&#xff0c;是 Python…

C++进阶:多态

✨✨所属专栏&#xff1a;C✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 多态的概念 多态(polymorphism)的概念&#xff1a;通俗来说&#xff0c;就是多种形态。多态分为编译时多态(静态多态)和运⾏时多态(动态多态)&#xff0c;这⾥我们重点讲运⾏时多态。 编译时多态(静态多态)主…

一口气学完docker【入门到精通】

一、容器 1、什么是容器 容器是一种轻量级的虚拟化技术&#xff0c;它为应用程序提供了一种隔离的运行环境。在操作系统级别上实现&#xff0c;容器将应用程序及其所有依赖项&#xff08;包括库、配置文件等&#xff09;封装在一起&#xff0c;形成一个独立的标准单元。 每个…

[数据结构]二叉搜索树

今天我们来学习一下新的数据结构&#xff0c;二叉搜索树&#xff0c;这个结构比较简单&#xff0c;是一个铺垫式的结构&#xff0c;为之后的平衡二叉树&#xff0c;AVL树以及红黑树做一个知识基础&#xff0c;我们将从概念到实现具体的介绍二叉搜索树。 目录 Ⅰ.二叉搜索树的…

比亚迪电动汽车的市场占比太惊人

比亚迪&#xff08;BYD&#xff09;在中国电动汽车市场的崛起无疑是近年来最显著的现象之一。凭借其强大的技术整合、丰富的产品线以及价格优势&#xff0c;比亚迪已经迅速成为中国乃至全球电动汽车领域的领导者。在2024年&#xff0c;比亚迪的市场份额在中国汽车市场达到了惊人…

什么是上拉,下拉?

上拉就是将引脚通过一个电阻连接到电源&#xff0c;作用&#xff1a;1.使IO口的不确定电平稳定在高点平&#xff0c;2、为了增加IO口拉电流的能力。 下拉就是将引脚通过一个电阻与GND相连&#xff0c;作用&#xff1a;1.从器件输出电流 2.当IO口为输入状态时&#xff0c;引脚的…

Redhat 8,9系(复刻系列) 一键部署Oracle23ai rpm

Oracle23ai前言 Oracle Database 23ai Free 让您可以充分体验 Oracle Database 的能力,世界各地的企业都依赖它来处理关键任务工作负载。 Oracle Database Free 的资源限制为 2 个 CPU(前台进程)、2 GB 的 RAM 和 12 GB 的磁盘用户数据。该软件包不仅易于使用,还可轻松下载…

适合学生党开学买的蓝牙耳机?分享开放式耳机排行榜前十名

学生党开学想买耳机的话&#xff0c;我觉得比较适合入手开放式耳机&#xff0c;因为这类耳机佩戴舒适度高&#xff0c;长时间使用也不会感到不适或疲劳&#xff0c;同时保持耳道干爽透气&#xff0c;更加健康卫生&#xff0c;还能提供自然、开阔的音场&#xff0c;音质表现优秀…

详解c++多态---上

virtual关键字 1.可以修饰原函数&#xff0c;为了完成虚函数的重写&#xff0c;满足多态的条件之一。 class Person { public:virtual void BuyTicket() { cout << "买票-全价" << endl; } };class Student : public Person { public:virtual void Buy…

NarratoAI利用AI大模型,一键解说并剪辑视频

测试视频: 字幕/配乐后期添加的,视频由NarratoAI自动生成的 雪迷宫-NarratoAI利用AI大模型剪辑解说视频测试 WIN整合包 下载链接&#xff1a;https://pan.quark.cn/s/8f54ef99e3fb 使用前先更新&#xff0c;运行update.bat Gemini API Key 访问 https://aistudio.google.c…

性能测试-jmeter的控制器(十六)

一、if控制器 需求&#xff1a;使用“用户自定义变量”定义name变量&#xff0c;值可以是“baidu”或“itcast”,使用变量值&#xff0c;控制是否访问对应网站。 1、步骤&#xff1a; 在测试计划中添加用户定义的变量name,取值可为baidu或itcast添加两个http请求&#xff1a…

Docker突然宣布:涨价80%

从11月15日起&#xff0c;Docker的付费订阅中Pro和Team的价格都将大幅上调&#xff1a;Pro从原来的5美元每月激增到9美元每月&#xff0c;直接涨了80%&#xff1b;而Team也从之前的9美元每月来到15美元每月&#xff0c;涨价66.7%。只有Business保持此前的24美元每月不变。 同时…