前端-react(class组件和Hooks)

news2024/11/24 9:50:32

文章主要以Hooks为主,部分涉及class组件方法进行对比

一.了解react

1.管理组件的方式

在React中,有两种主要的方式来管理组件的状态和生命周期:Class 组件和 Hooks。

Class 组件:
Class 组件是 React 最早引入的方式,它是基于 ES6 class 的语法来创建的。Class 组件包含了生命周期方法,可以用来处理组件的状态、副作用等。以下是一些 Class 组件的特点和生命周期方法:
Hooks:
Hooks 是 React 16.8 版本引入的一项功能,它的目的是为了让函数组件也能够拥有状态和生命周期控制的能力,同时减少代码的冗余和复杂性。

2.样式管理

在vue中我们可以利用style scoped控制样式仅在某个组件生效

在react当中万平米可以利用将css文件命名为组件名.module.css

classnames

因为classname必须接受一个字符串,比较繁琐,所有可以借助classnames帮助我们生成一个字符串.

二.JSX

1.概念:

JSX是JavaScript和XML(HTML)的缩写,表示在JS代码当中编写HTML模板结构,是React中编写UI模板的方式.

2.本质:

JSX并不是标准的JS语法,是JS的扩展语法,浏览器本身不能不能识别,需要通过解析工具(BABEL)做解析之后才能在浏览器中运行.

原理可以理解:

jsx是快速创建React-element对象的快速方法

3.JSX中使用JS表达式

在JSX中可以通过大括号语法{}识别JavaScript中的表达式进行.

三.渲染

1.列表渲染

将依赖 JavaScript 的特性,例如 for 循环 和 array 的 map() 函数 来渲染组件列表。

2.条件渲染

可以通过逻辑与运算符&&或者三元表达式(?:) 实现

四.事件绑定

类似原生 on+事件名(首字母大写)

    //阻止事件冒泡

    event.stopPropagation()

    //阻止默认行为

    event.preventDefault()

组件

概念:一个组件就是用户界面的一部分,可以有自己的逻辑和外观,组件之间可以互相嵌套,也可以多次复用.

五.响应式属性(class方法以及Hooks)

react没有像vue一样监听get和set

class方法:

这里的PureComponent其实是实现了利用生命周期方法阻止出现更新后的值和更新前的一致但是还渲染页面的情况.详细会在生命周期章节讲述.

import React from 'react'
//PureComponent修改了很多Component的性能问题
//这里提及一个区别,如果涉及数组和对象的更新
//PureComponent需要利用一下浅拷贝(...this.state.arr),而Component不需要
class App extends React.PureComponent {
  state = {
    a: 0
  }
  add = () => {
    this.setState({
      a: this.state.a+1
      //setState属于异步操作
      //console.log()属于同步操作先打印a:0才会执行修改更新
      //所有需要在第二个参数执行
    }, () => {
      console.log(this.state.a)
    })
  }
  render() {
    return <div className="App">
      <span>{this.state.a}</span>
      <button onClick={this.add}>数据+1</button>
    </div>
  }
}
export default App

Hooks:

useState 中获得两样东西:当前的 state(count),以及用于更新它的函数(setCount)。你可以给它们起任何名字,但按照惯例会像 [something, setSomething] 这样为它们命名。

在react中,状态被认为是只读的,我们始终应该替换它而不是修改他,直接修改状态不能引发视图更新

例如不能直接在绑定事件中count++

修改对象状态(回顾知识:变量是存于栈内,对象是存于堆内 修改对象数据需要浅拷贝)

小案例:

六.表单绑定

React不能像Vue一样使用v-model,还是要使用原生的操作去做.

例如原生表单获取表单输入值,我们可以通过监听input,change等事件,然后获取e.target.value

然后设置value属性.

七.react获取DOM

useRef 返回一个具有单个 current 属性 的 ref 对象,并初始化为你提供的 初始值。

在后续的渲染中,useRef 将返回相同的对象。你可以改变它的 current 属性来存储信息,并在之后读取它。这会让人联想到 state,但是有一个重要的区别。

改变 ref 不会触发重新渲染。这意味着 ref 是存储一些不影响组件视图输出信息的完美选择。所以 ref 不适合用于存储期望显示在屏幕上的信息

八.组件通信

1.父传子

Props 是你传递给 JSX 标签的信息。例如,classNamesrcaltwidthheight 都可以传递

子组件只能读取props中的数据,不能直接进行修改,父组件的数据只能父组件修改.

2.props.children

3.子传父

核心思路:在子组件中调用父组件中的函数并传递参数

4.兄弟组件之间通信

核心思路:子传父->state->父传子

import { useState, useRef } from 'react'
import React from 'react'
function Son({onGetMes }) {
  const sonmsg = 'sonmsg'
  return (
    <div>
      <span>this is Son</span>
      <button onClick={() => onGetMes(sonmsg)}>send to bro </button>
    </div>
  )
}
function Sonbro({sonmsg}){
return(
<div>
  <span>i am sonbro:{sonmsg}</span>
</div>
)
}
function App() {
  const [sonmsg,setSonmsg]=useState('')
  const getMes = (sonmsg) => {
    setSonmsg(sonmsg)}
  return (
    <div className="A">
      <Son onGetMes={getMes} />
      <Sonbro sonmsg={sonmsg}></Sonbro>
    </div>
  )
}
export default App

5.跨层级通信

实现步骤:

①使用createContext方法创建一个上下文对象

const MsgContext = createContext()

 ②在顶层组件中通过Provider提供数据

      <MsgContext.Provider value={msg}>

        this is APP

        <A />

      </MsgContext.Provider>

③在底层组件中通过useContent钩子函数获取消费数据

  const receivemsg=useContext(MsgContext)

九.生命周期(class方法)

三大周期:挂载,更新,卸载

 对于Vue来说是通过监听状态的改变实现更新,但是React不会,这时候我们就需要多利用生命周期来实现一下自定义的优化.

组件挂载时
当组件实例被创建并插入DOM时,其生命周期调用顺序如下:
constructor()
static getDerivedStateFromProps()
render()
componentDidMount()
组件更新时
当组件的props或state发生变化时会触发更新。组件更新的生命周期调用顺序如下:
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
组件卸载时
当组件从DOM中移除时会调用如下方法
componentWillUnmount()
错误处理
当渲染过程,生命周期或子组件的构造函数中抛出错误时,会调用如下方法:
static getDerivedStateFromProps()
componentDidCatch()

之前提及的purecomponent原理:

  shouldComponentUpdate(props,state){

    // console.log('shouldup')

    let change=false;

    for(let item in this.state){

      if(this.state[item] !==state[item]){

        change=true

      }

    }

    return change

  }

重要生命周期总结 

探索react更新的问题

十.函数组件

1.useEffect (副作用)

函数页面没有生命周期,所以需要利用一些方法

useEffect有两个参数:

不传第二个参数 功能=componentDidMount和componentDidUpdate

第二个参数传空数组 功能=componentDidMount

第二个参数数组里放某个数据=watch监听

vue的watch默认是不会开始就执行的,react的useEffect监听某个数据,开始就会执行一次(didamount)

2.useMemo 

让一段计算在开始执行一次,后续只有依赖的数据发生变化才重新运算(避免每次其他属性变化都要执行一次计算)

参数效果和useEffct相同

作用:

1.类似于vue的一个计算属性的效果

2.缓存一个数据,让其不会重新创建

注意:利用函数组件也要使用记得使用浅拷贝(解除引用)

import React, { useEffect, useMemo, useState } from 'react'
function App() {
  let [arr,setArr]=useState([1,2,3,4])
  //当数组变化(计算)时候,all跟着一起变化(计算结果)
  let all=useMemo(()=>{
    console.log('usememo执行')
    let _all=0;
    arr.forEach(item=>{
      _all+=item
    })
    return _all
  },[arr])
  const addelement=()=>{
    let _arr=[...arr];_arr.push(arr[arr.length-1]+1);setArr(_arr)
  }
  return (
    <div >
      <span>数组:{arr}</span><br/>
      <span>总和:{all}</span>
      <button onClick={addelement}>修改arr</button>
    </div>
  )
}
export default App

3.useCallback

用于方法

十一.高阶组件

案例:

TetsHoc.jsx:

import React, { useEffect, useState } from "react";
export default function TestHoc(userCom) {
    return function () {
        let [point, setPoint] = useState({ x: 0, y: 0 })
        useEffect(() => {
            window.addEventListener('mousemove', (e) => {
                setPoint({
                    x: e.clientX,
                    y: e.clientY
                }
                )
                // console.log(point)
            })
        }, [point.x, point.y])
        return( <>
        {/* 给组件传递ponit参数 */}
           {userCom({ point })}
        </>
        )
    }
}

App.jsx

import React, { useEffect, useMemo, useState } from 'react'
import Test from './Test'
import TestHoc from './TetsHoc'
//组件作为参数传参
let HocSon=TestHoc(Test)
console.log(HocSon)
function App() {
  return (
    <div >
     <HocSon></HocSon>
    </div>
  )
}
export default App

Test.jsx

import './Test.css'
function Test(props) {
    return (
      <div >
       <span>x:{props.point.x} y:{props.point.y}</span>
      </div>
    )
  }
  export default Test

 十二.React性能问题和优化

React最大的性能问题就是React的某个组件的更新会连带着他的子组件一起更新

两个解决方式:

①源码层面上尽量弥补这个问题

②让子组件只做合理的更新

React的时间切片

Vue有依赖收集,做到了最小的更新范围,而React没有做这个事情,所以React要更新,就会有很大的differ算法比对和计算工作

这大的更新量,虚拟dom比对和计算会话很大时间,这样可能会阻塞浏览器的工作,导致页面长时间白屏

React为了解决这个问题选择另一种策略-时间切片,也就是先计算一部分更新,然后让渡给渲染进程渲染,然后再进行下一步更新。以此往复。这样我们从使用者的角度,就不会出现长时间白屏了。

保障在执行更新操作时计算时不能超过16ms(​人眼刷新频率一般​是60hz,60hz是16.6ms一帧),如果超过16ms,就需要先暂停,让给浏览器进行渲染。

fiber

避免父组件数据更改导致子组件更新

父组件更改导致子组件更新是最大的问题

class方法:PureComponent  函数hooks:React.memo 

我们利用React.memo :

但是引入对象和方法之后又出现子组件更新

原因:num更新后会导致app组件更新,重新执行App方法,这样会重新定义obj和f1,这样会导致他们的内存地址发生变化,导致之前传给组件的props不再是之前传递的props,这样就会认为props改变了。利用PureComponent或者React.memo 只能保证props或者state改变子组件才会更新,但是现在已经不满足这样的情况了,我们需要使用useCallback和useMemo解决。

避免state同样的值产生更新

避免state修改同样的值,而产生无意义更新(class方法Purecomponent可以解决,函数组件(hooks)本身就会判断)

十三.React-Router(最新6.28.0)

 npm install react-router-dom@6

1.路由配置(createRouter)

 基本配置示例:

这里做一下解释:

官网建议我们尽早选择新发布的未来标志,以便于最终迁移到 v7。 不然终端会做出提示

所以添加以下内容:

{

        future: {

            v7_fetcherPersist: true,

            v7_normalizeFormMethod: true,

            v7_partialHydration: true,

            v7_relativeSplatPath: true,

            v7_skipActionErrorRevalidation: true,

            v7_startTransition: true,

            }

    }

404路由配置

2.路由跳转 (Link or useNavigate)

配置如下(这个配置和vue配置类似哈)

两种方法:

3.路由传参(useSearchParams 和useParams)

①useSearchParams:

②useParams 

4.路由嵌套

使用<Outlet>组件配置二级路由渲染位置

 默认二级路由:

再二级路由的位置去掉path,设置index属性为true

十四.全局状态管理工具

这里使用的是:Zustand 

使用方法和pinia大差不差

参考:b站 三十的前端课;react官网;react router官网

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

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

相关文章

Ngrok实现内网穿透(Windows)

Ngrok实现内网穿透&#xff08;Windows&#xff09; 什么是内网穿透&#xff0c;内网穿透有什么用 内网穿透&#xff08;NAT traversal&#xff09;是一种技术手段&#xff0c;使得位于内网或防火墙后面的设备能够通过外网访问。例如&#xff0c;如果你的计算机、服务器等设备…

如何使用Jest测试你的React组件

在本文中&#xff0c;我们将了解如何使用Jest&#xff08;Facebook 维护的一个测试框架&#xff09;来测试我们的React组件。我们将首先了解如何在纯 JavaScript 函数上使用 Jest&#xff0c;然后再了解它提供的一些开箱即用的功能&#xff0c;这些功能专门用于使测试 React 应…

力扣 三数之和-15

三数之和-15 class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {int temp 0;//定义一个二维vector数组vector<vector<int>> ans;int n nums.size();//对nums数组进行排序sort(nums.begin(), nums.end());//固定…

深度学习每周学习总结J6(ResNeXt-50 算法实战与解析 - 猴痘识别)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 0. 总结ResNeXt基本介绍 1. 设置GPU2. 导入数据及处理部分3. 划分数据集4. 模型构建部分5. 设置超参数&#xff1a;定义损失函数&…

Transformer架构笔记

Attention is All You Need. 3.Model Architecture 3.1 整体架构如图 3.2 Encoder与Decoder Encoder&#xff1a;由 N 6 N6 N6个相同的Block/Layer堆叠而成。每个Block有两个子层sub-layer&#xff1a;多头注意力和MLP&#xff08;FFN&#xff0c;前馈神经网络&#xff09;&…

【大数据学习 | Spark-Core】spark-shell开发

spark的代码分为两种 本地代码在driver端直接解析执行没有后续 集群代码&#xff0c;会在driver端进行解析&#xff0c;然后让多个机器进行集群形式的执行计算 spark-shell --master spark://nn1:7077 --executor-cores 2 --executor-memory 2G sc.textFile("/home/ha…

增量预训练(Pretrain)样本拼接篇

增量预训练&#xff08;Pretrain&#xff09;样本拼接篇 一、Pretrain阶段&#xff0c;为什么需要拼接拼接&#xff1f; 为了提高pretrain效率、拓展LLM最大长度&#xff0c;随机将若干条短文本进行拼接是pretrain阶段常见手段。 二、有哪些拼接方式&#xff1f; 拼接方式一…

【AI最前线】DP双像素sensor相关的AI算法全集:深度估计、图像去模糊去雨去雾恢复、图像重建、自动对焦

Dual Pixel 简介 双像素是成像系统的感光元器件中单帧同时生成的图像&#xff1a;通过双像素可以实现&#xff1a;深度估计、图像去模糊去雨去雾恢复、图像重建 成像原理来源如上&#xff0c;也有遮罩等方式的pd生成&#xff0c;如图双像素视图可以看到光圈的不同一半&#x…

从零开始-VitePress 构建个人博客上传GitHub自动构建访问

从零开始-VitePress 构建个人博客上传GitHub自动构建访问 序言 VitePress 官网&#xff1a;VitePress 中文版 1. 什么是 VitePress VitePress 是一个静态站点生成器 (SSG)&#xff0c;专为构建快速、以内容为中心的站点而设计。简而言之&#xff0c;VitePress 获取用 Markdown…

使用uniapp编写APP的文件上传

使用uniapp插件文件选择、文件上传组件&#xff08;图片&#xff0c;视频&#xff0c;文件等&#xff09; - DCloud 插件市场 实用效果&#xff1a; 缺陷是只能一个一个单独上传

【51单片机】红外遥控

学习使用的开发板&#xff1a;STC89C52RC/LE52RC 编程软件&#xff1a;Keil5 烧录软件&#xff1a;stc-isp 开发板实图&#xff1a; 文章目录 红外遥控硬件电路 NEC协议编码编程实例LCD1602显示Data红外遥控控制扇叶转速 红外遥控 红外遥控是利用红外光进行通信的设备&#…

【解决】Unity TMPro字体中文显示错误/不全问题

问题描述&#xff1a;字体变成方块 原因&#xff1a;字体资源所承载的长度有限 1.找一个中文字体放入Assets中 2.选中字体创建为TMPro 字体资源 3.选中创建好的字体资源&#xff08;蓝色的大F&#xff09; 在右边的属性中找到Atlas Width h和 Atlas Heigth,修改的大一点&…

深度学习:GPT-1的MindSpore实践

GPT-1简介 GPT-1&#xff08;Generative Pre-trained Transformer&#xff09;是2018年由Open AI提出的一个结合预训练和微调的用于解决文本理解和文本生成任务的模型。它的基础是Transformer架构&#xff0c;具有如下创新点&#xff1a; NLP领域的迁移学习&#xff1a;通过最…

CKA认证 | Day2 K8s内部监控与日志

第三章 Kubernetes监控与日志 1、查看集群资源状态 在 Kubernetes 集群中&#xff0c;查看集群资源状态和组件状态是非常重要的操作。以下是一些常用的命令和解释&#xff0c;帮助你更好地管理和监控 Kubernetes 集群。 1.1 查看master组件状态 Kubernetes 的 Master 组件包…

概念解读|K8s/容器云/裸金属/云原生...这些都有什么区别?

随着容器技术的日渐成熟&#xff0c;不少企业用户都对应用系统开展了容器化改造。而在容器基础架构层面&#xff0c;很多运维人员都更熟悉虚拟化环境&#xff0c;对“容器圈”的各种概念容易混淆&#xff1a;容器就是 Kubernetes 吗&#xff1f;容器云又是什么&#xff1f;容器…

JDBC编程---Java

目录 一、数据库编程的前置 二、Java的数据库编程----JDBC 1.概念 2.JDBC编程的优点 三.导入MySQL驱动包 四、JDBC编程的实战 1.创造数据源&#xff0c;并设置数据库所在的位置&#xff0c;三条固定写法 2.建立和数据库服务器之间的连接&#xff0c;连接好了后&#xff…

移动充储机器人“小奥”的多场景应用(上)

在当前现代化城市交通体系中&#xff0c;移动充储机器人“小奥”发挥着至关重要的作用。该机器人不仅是一个简单的设备&#xff0c;而是一个集成了高科技的移动充电站&#xff0c;为新能源汽车提供了一种前所未有的便捷充电解决方案。该机器人配备了先进的电池管理系统&#xf…

element dialog会隐藏body scroll 导致tab抖动 解决方案如下

element dialog会隐藏body scroll 导致tab抖动 解决方案如下 在dialog标签添加 :lockScroll"false"搞定

Android 功耗分析(底层篇)

最近在网上发现关于功耗分析系列的文章很少&#xff0c;介绍详细的更少&#xff0c;于是便想记录总结一下功耗分析的相关知识&#xff0c;有不对的地方希望大家多指出&#xff0c;互相学习。本系列分为底层篇和上层篇。 大概从基础知识&#xff0c;测试手法&#xff0c;以及案例…

Bugku CTF_Web——my-first-sqli

Bugku CTF_Web——my-first-sqli 进入靶场 随便输一个看看 点login没有任何回显 方法一&#xff1a; 上bp抓包 放到repeter测试 试试万能密码&#xff08;靶机过期了重新开了个靶机&#xff09; admin or 11--shellmates{SQLi_goeS_BrrRrRR}方法二&#xff1a; 拿包直接梭…