前端-react(class组件和Hooks)

文章主要以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.mzph.cn/bicheng/61771.shtml

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

相关文章

Ollama vs VLLM:大模型推理性能全面测评!

最近在用本地大模型跑实验&#xff0c;一开始选择了ollama,分别部署了Qwen2.5-14B和Qwen2.5-32B&#xff0c;发现最后跑出来的实验效果很差&#xff0c;一开始一直以为prompt的问题&#xff0c;尝试了不同的prompt&#xff0c;最后效果还是一直不好。随后尝试了vllm部署Qwen2.5…

基于深度学习CNN算法的花卉分类识别系统01--带数据集-pyqt5UI界面-全套源码

文章目录 基于深度学习算法的花卉分类识别系统一、项目摘要二、项目运行效果三、项目文件介绍四、项目环境配置1、项目环境库2、环境配置视频教程 五、项目系统架构六、项目构建流程1、数据集2、算法网络Mobilenet3、网络模型训练4、训练好的模型预测5、UI界面设计-pyqt56、项目…

【PCIE常见面试问题-1】

PCIE常见面试问题-1 1 PCIE概述1.1 PCI为何发展开PCIE&#xff1f;1.2 什么是Root Complex(RC)1.3 什么是EP&#xff1f;1.4 什么是Swith1.5 PCIE协议如何组织通信的&#xff1f;1.6 简要介绍一下PCIE的分层结构&#xff0c;为什么需要分层&#xff1f;1.7 PCIE的事务类型有哪些…

解决 Docker Desktop 启动报错:Docker Desktop is unable to detect a Hypervisor

在使用 Docker Desktop 时&#xff0c;有时会遇到启动报错&#xff1a;“Docker Desktop is unable to detect a Hypervisor.” 这是由于系统的虚拟化功能未正确启用或配置导致的。本文将分步骤指导如何解决该问题。 一、检查虚拟化是否已启用 打开任务管理器 按下 Ctrl Shift…

订单日记为“惠采科技”提供全方位的进销存管理支持

感谢温州惠采科技有限责任公司选择使用订单日记&#xff01; 温州惠采科技有限责任公司&#xff0c;成立于2024年&#xff0c;位于浙江省温州市&#xff0c;是一家以从事销售电气辅材为主的企业。 在业务不断壮大的过程中&#xff0c;想使用一种既能提升运营效率又能节省成本…

rust中解决DPI-1047: Cannot locate a 64-bit Oracle Client library问题

我们在使用rust-oracle crate连接oracle进行测试的过程中&#xff0c;会发现无法连接oracle&#xff0c;测试运行过程中抛出“DPI-1047: Cannot locate a 64-bit Oracle Client library”错误。该问题是由于rust-oracle需要用到oracle的动态连接库&#xff0c;我们通过安装orac…

东方通重置管理员密码

百度给出的回答 注意&#xff0c;箭头所指的密码是举例&#xff0c;不是自己的默认密码 自己的默认密码存储在下图位置 原文地址

spark 写入mysql 中文数据 显示?? 或者 乱码

目录 前言 Spark报错&#xff1a; 解决办法&#xff1a; 总结一下&#xff1a; 报错&#xff1a; 解决&#xff1a; 前言 用spark写入mysql中&#xff0c;查看中文数据 显示?? 或者 乱码 Spark报错&#xff1a; Sat Nov 23 19:15:59 CST 2024 WARN: Establishing SSL…

电子应用设计方案-20:智能电冰箱系统方案设计

智能电冰箱系统方案设计 一、系统概述 本智能电冰箱系统旨在提供更便捷、高效、智能化的食品存储和管理解决方案&#xff0c;通过集成多种传感器、智能控制技术和联网功能&#xff0c;实现对冰箱内部环境的精确监测和控制&#xff0c;以及与用户的互动和远程管理。 二、系统组成…

实验四:构建园区网(OSPF 动态路由)

目录 一、实验简介 二、实验目的 三、实验需求 四、实验拓扑 五、实验步骤 1、在 eNSP 中部署网络 2、设计全网 IP 地址 3、配置二层交换机 4、配置路由交换机并测试通信 5、配置路由接口地址 6、配置 OSPF 动态路由&#xff0c;实现全网互通 一、实验简介 使用路由…

【大数据学习 | Spark-Core】yarn-client与yarn-cluster的区别

1. yarn的提交命令 # yarn的提交命令参数 --master yarn #执行集群 --deploy-mode # 部署模式 --class #指定运行的类 --executor-memory #指定executor的内存 --executor-cores # 指定核数 --num-executors # 直接指定executor的数量 --queue # 指定队列 2. yarn-client模式…

WEB攻防-通用漏洞文件上传二次渲染.htaccess变异免杀

知识点&#xff1a; 1、文件上传-二次渲染 2、文件上传-简单免杀变异 3、文件上传-.htaccess妙用 4、文件上传-PHP语言特性 1、上传后门时&#xff0c;文件内容带.就不行 这时可以上传一个转换后的ip地址&#xff0c;ip地址对应网站包含后门代码 转换后的int会在访问的时候…

【汽车制动】汽车制动相关控制系统

目录 1.ABS (Anti-lock Brake System&#xff0c;防抱死制动系统) 2.EBD&#xff08;Electronic Brake-force Distribution&#xff0c;电子制动力分配系统&#xff09; 3.TCS&#xff08;Traction Control System&#xff0c;牵引力控制系统&#xff09; 4.VDC&#xff08…

Tri Mode Ethernet MAC IP核详解

本文对 Vivado 的三速 MAC IP 核&#xff08;Tri Mode Ethernet MAC&#xff0c;TEMAC&#xff09;进行介绍。 在自行实现三速以太网 MAC 控制器时&#xff0c;GMII/RGMII 接口可以通过 IDDR、ODDR 原语实现&#xff0c;然而实际使用中自己实现的模块性能不是很稳定&#xff08…

项目实战:基于Vue3实现一个小相册

相册的示例效果图 注意看注释... CSS部分&#xff1a; <style>/* 伪元素选择器&#xff0c;用于在具有clear_ele类的元素内部的末尾添加一个新的元素 */.clear_ele::after{ content: ""; /* 这个伪元素的内容属性必须有 *//* 块级元素&#xff0c;便于占据一…

HTMLCSS:比赛记分卡

效果演示 这段 HTML 和 CSS 代码创建了一个卡片式的体育比赛信息展示组件&#xff0c;用于显示篮球比赛的两个队伍名称、比赛时间、比分以及一些装饰性的视觉元素。 HTML <div class"card"><div data-status"inprogress" class"teams"…

Paper -- 3D建筑模型生成 -- GABLE: 基于高分辨率卫星影像的全国尺度精细3D建筑模型

基本信息 论文题目: GABLE: A first fine-grained 3D building model of China on a national scale from very high resolution satellite imagery 中文题目: GABLE: 基于高分辨率卫星影像的全国尺度精细3D建筑模型 作者及单位: – 多数作者来自中国科学院空间信息研究所&…

蓝桥杯嵌入式再学习(2)基础框架的构建

1&#xff1a;打开工程以后我们需要进行一些配置如图&#xff1a; 第一步&#xff1a;将core里面的对勾取消掉 勾选Microlib 优化等级选择level 0 将我们自己的文件夹添加到路径里面去 这个样子我们就基本将框架搭建好了我们然后需要编写各个底层的驱动了

矩阵/矩阵乘法/特征征/特征向量的讲解

线性代数里有很多的概念&#xff0c;很多概念是有几何意义的&#xff0c;了解了几何意义可能会更好的理解各种概念及其相互之间的关系。 矩阵&#xff1a; 矩阵是一个变换&#xff0c;一个坐标系到另一个坐标第的变换。矩阵里的各个参数&#xff0c;代表了如何进行变换。 矩阵…

Easyexcel(5-自定义列宽)

相关文章链接 Easyexcel&#xff08;1-注解使用&#xff09;Easyexcel&#xff08;2-文件读取&#xff09;Easyexcel&#xff08;3-文件导出&#xff09;Easyexcel&#xff08;4-模板文件&#xff09;Easyexcel&#xff08;5-自定义列宽&#xff09; 注解 ColumnWidth Data…