react笔记-05react扩展篇

react笔记-扩展篇

包括新用法和hooks

1. setState

setState更新状态的两种写法:

1. setState({}, [() => {}])
2. setState(() => {// 返回一个状态修改对象return {}
}, [() => {}])

1. 对象写法:

⚠️注意:react更新状态是异步的

import React, { Component } from 'react'export default class Demo extends Component {state = {count: 0}add = () => {// 更新状态:react更新状态是异步的this.setState({count: this.state.count + 1}, () => {// 该回调的可以获取到state更新后的结果,可选参数console.log(this.state.count); // 1 更改后})console.log(this.state.count); // 0 更改前}render() {return (<div><p>{this.state.count}</p><button onClick={this.add}>+1</button></div>)}
}

2. 函数写法:

回调参数可以收到stateprops

this.setState((state, props) => {return {count: state.count + 1}
})

总结:

对象式的setState是函数式的setState方式的简写方式(语法糖)

2. lazyLoad

路由组件的lazyLoad:懒加载

import React, { Component, lazy, Suspense } from 'react'
import { Route } from 'react-router-dom'const Home = lazy(() => import('./Home'))export default class Demo extends Component {render() {return (<div>{/* Suspense 包裹路由组件, 需要给定fallback */}<Suspense fallback={<div>loading...</div>}><Route path='/home' component={Home} /></Suspense></div>)}
}

3. Hooks

3.1 Hooks是什么

hooks是react16.8.0新增的新特性,可以在函数式组件中使用state以及其他react新特性。

3.2 三个常用的hook

  • State Hook:React.useState()
  • Effect Hook:React.useEffect()
  • Ref Hook:React.useRef()

3.3 useState

State Hook让函数组件也可以拥有state状态,并进行状态数据的读写操作。

import React from 'react'function Demo() {const [count, setCount] = React.useState(0)function change() {// 第一种写法:参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值setCount(count + 1)// 第二种写法:参数为函数,接收原来的状态值,返回新的状态值,内部用其覆盖原来的状态值setCount((num) => {return num + 1})}return <><div>{count}</div><button onClick={change}>+1</button></>
}export default Demo

通过import { useState } from 'react'也可以

3.4 useEffect

import { useState, useEffect } from 'react'function Demo() {const [count, setCount] = useState(0)// 	情况1:只给第一个参数:每当数据更改一次,调用一次回调useEffect(() => {// 可以执行任何副作用操作// 例如:网络请求,定时器console.log('数据更改了');})// 情况2:如果第一个参数返回一个函数,返回的函数可以做一些收尾工作,例如:清除定时器useEffect(() => {console.log('数据更改了');return () => {console.log('组件销毁了');}})// 情况3:监听count的改变,count改变了,就会调用回调useEffect(() => {console.log('数据更改了');}, [count, ...])// 情况4:参数2为空数组,谁都不监听,回调只有第一次render才会被调用useEffect(() => {console.log('数据更改了');}, [])return <><div>{count}</div><button onClick={() => { setCount(count + 1) }}>+1</button></>
}export default Demo

可以把useEffect看作三个函数的组合:

  • componentDidMount()
  • componentDidUpdate()
  • componentWillUnmount()

3.5 useRef

import { useRef } from 'react'function Demo() {let myRef = useRef()function getRef() {console.log(myRef.current.value)}return <><input type="text" ref={myRef} /><button onClick={getRef}>ref</button></>
}export default Demo

4. Fragment

类似于vue的template,不会解析到页面上

<Fragment></Fragment>
<></>
import { Fragment } from 'react'function Demo() {// Fragment可以绑定key,循环的时候可以传递key,空标签不允许传任何属性return <Fragment key={id}>hello</Fragment>
}export default Demo

5. Context

Context:一种组件间的通信方式。常用于【祖组件】与【后代组件】间的通信。

使用:

  1. 创建Context容器对象:
const MyContext = createContext()
  1. 渲染子组件时,外层包裹XxxContext.Provider,通过value属性给后代组件传递数据
export default class A extends Component {render() {return (<div>A<MyContext.Provider value={{ name: 'xiaotian', age: 18 }}><B /></MyContext.Provider></div>)}
}

也可以解构Provider:

const { Provider } = MyContext;<Provider></Provider>
  1. 后代组件读取数据(两种方式):

    1. 第一种方式:仅适用于类式组件
    class C extends Component {// 声明接收context,通过this.context读取value的数据static contextType = MyContextrender() {return (<div>C{this.context.name}</div>)}
    }
    
    1. 第二种方式:函数式和类式组件都行
    <XxxContext.Consumer>{(value) => {// value就是context中value的数据return (需要返回的内容)}}
    </XxxContext.Consumer>
    

    例子:

    // C组件
    function C() {return (<MyContext.Consumer>{(value) => {return (<div>C{value.name}</div>)}}</MyContext.Consumer>)
    }
    

    6. 组件优化

    6.1 import {Component} from 'react'的Component的两个问题:

    1. 只要执行setState(),即使不改变状态,组件也会重新render()
    2. 当前组件重新render,就会自动重新render子组件(即使子组件没有用到父组件的任何数据),效率低

    6.2 效率高的做法:

    只有当组件的stateprops发生改变的时候才重新render

    6.3 原因:

    Component中的shouldComponentUpdate()总是返回true

    6.4 解决方法:

    类式组件

    1. 方法1:重写shouldComponentUpdate()方法,比较新旧stateprops数据,只有发生变化才返回true,否则返回false

    2. 方法2:使用PureComponentPureComponent重写了shouldComponentUpdate(),只有当stateprops发生变化时才返回true。

      import { PureComponent } from 'react'
      

      ⚠️注意:只是进行stateprops数据的浅比较,如果只是数据对象内部数据变了,返回的是false。

      不要直接修改state,而是要产生新数据

    函数式组件:可以通过使用React.memo来实现类似PureComponent的优化效果。下面是关于React.memo的基本使用方法:

    1. 基本用途React.memo是一个高阶函数,它接收一个函数组件作为参数,并返回一个新的经过优化的组件,该组件在props没有变化时避免不必要的渲染。
    2. 用法示例
    import React, { memo } from 'react'const MyFunctionalComponent = (props) => {// 组件逻辑...return <div>{props.text}</div>
    }export default memo(MyFunctionalComponent)
    

    在这个例子中,MyFunctionalComponentmemo包裹,这意味着React会跳过重新渲染该组件,除非它的props发生了变化。

    1. 深入理解:与PureComponent相似,React.memo执行浅比较来检查props是否变化。如果props是复杂对象且需要深层比较,你可以传递第二个参数,即一个自定义的比较函数来进行更精细的控制。
    2. 注意事项React.memo只对props的变化做出反应,组件内部的state或context变化依然会导致重渲染。此外,如果组件有副作用(如数据获取、订阅等),应该在组件内部使用适当的生命周期方法或Hooks来管理这些副作用。

    通过这种方式,React.memo帮助提高了函数式组件的性能,减少了不必要的渲染,特别是在大型应用程序中,这种优化可以带来显著的性能提升。

7. renderProps(插槽技术)

类似于vue中的插槽

import React, { Component } from 'react'export default class Demo extends Component {render() {return (<div>{/* <BComponent name={name} /> 可以渲染任何组件 */}<AComponent render={(name) => <BComponent name={name} />} /></div>)}
}// 父组件
class AComponent extends Component {render() {return (<div><div>A组件</div>{/* 预留的位置,类似于vue中的插槽 */}{ this.props.render('xiaotian') }</div>)}
}// 子组件
class BComponent extends Component {render() {return (<div>B组件---A组件的name为:{this.props.name}</div>)}
}

8. 错误边界

8.1 理解:

错误边界(Errorboundary):用来捕获后代组件的错误,渲染出备用页面。

8.2 特点:

只能捕获后代组件生命周期产生的错误,不能捕获自己组件产生的错误和其他合成事件、定时器中产生的错误。

8.3 使用:

// 当子组件报错时,会触发getDerivedStateFromError,并携带错误信息
static getDerivedStateFromError(error) {console.log(error);return { hasError: true }
}// 当渲染组件时出错会调用该钩子,用于统计错误信息,反馈给服务器
componentDidCatch(error, errorInfo) {console.log(error, errorInfo);
}
import React, { Component } from 'react'export default class Parent extends Component {state = {hasError: '' // 用于标识子组件是否产生错误}// 当子组件报错时,会触发getDerivedStateFromError,并携带错误信息static getDerivedStateFromError(error) {console.log(error);return { hasError: error }}// 当渲染组件时出错会调用该钩子,用于统计错误信息,反馈给服务器componentDidCatch(error, errorInfo) {console.log(error, errorInfo);}render() {return (<div>{ this.state.hasError ? '当前网络不稳定' : <Child /> }</div>)}
}class Child extends Component {state = {// list: [1, 2, 3, 4, 5] 正常情况list: 'abc' // 错误情况}render() {return (<ul>{this.state.list.map((item, index) => {return <li key={index}>{item}</li>})}</ul>)}
}

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

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

相关文章

探究布局模型:从LayoutLM到LayoutLMv2与LayoutXLM

LAYOUT LM 联合建模文档的layout信息和text信息&#xff0c; 预训练 文档理解模型。 模型架构 使用BERT作为backbone&#xff0c; 加入2-D绝对位置信息&#xff0c;图像信息 &#xff0c;分别捕获token在文档中的相对位置以及字体、文字方向、颜色等视觉信息。 2D位置嵌入 …

Linux 查看进程 ps -ef | grep

说明 在 Unix 和 Linux 系统中&#xff0c;ps -ef 命令用于显示所有正在运行的进程的详细信息。而 grep 是一个强大的文本搜索工具&#xff0c;它允许你在输入流&#xff08;比如来自文件或另一个命令的输出&#xff09;中搜索特定的模式。 当你将 ps -ef 的输出通过管道 | 传…

装备制造行业数据分析指标体系

数字化飞速发展的时代&#xff0c;多品种、定制化的产品需求、越来越短的产品生命周期、完善的售后服务、极佳的客户体验和快速的交货速度等&#xff0c;使得装备制造行业的经营环境越来越复杂&#xff0c;企业竞争从拼产品、拼价格迈向拼服务&#xff0c;装备制造企业正处于数…

阿里云 debian10.3 sudo apt-get updat 报错的解决方案

阿里云全新的debian10.3(buster)镜像&#xff0c;却无法正常执行 sudo apt-get update。主要报错信息如下&#xff1a; Err:6 http://mirrors.cloud.aliyuncs.com/debian buster-backports Release404 Not Found [IP: 100.100.2.148 80] Err:3 http://mirrors.cloud.aliyuncs…

无引擎游戏开发(1):EasyX图形库引入 + 跟随鼠标移动的小球

来自bilibili up主的Voidmatrix的视频教程&#xff1a;【从零开始的C游戏开发】 一、图形库引入 EasyX在国内文档最多&#xff0c;而且功能函数齐全&#xff0c;最适合入门。 环境配置&#xff1a;vs2022 &#xff08;官网下载免费版&#xff09; 百度搜EasyX官方&#xff0…

后方穿行预警系统技术规范(简化版)

后方穿行预警系统技术规范(简化版) 1 系统概述2 预警区域3 预警目标4 预警条件5 指标需求1 系统概述 RCTA后方穿行预警系统工作在驾驶员有倒车意向的时候。在倒车过程中当驾驶员视线因周围障碍物被遮挡而产生碰撞风险时,系统通过光学信号对驾驶员进行提醒。 2 预警区域 RCT…

前端入门篇(五十二)练习6:transition过渡小动画

所以应该先找到第n个li&#xff0c;找到li再找img&#xff0c;li没有找错&#xff0c;底下又各自只有一个img&#xff0c;解决 ul li:nth-child(1) img { } 描述文字从下往上&#xff1a; 一开始描述也在框框下面&#xff0c;当hover时&#xff0c;translateY(0)&#xff0…

js处理数组的方法总结

本文总结了JavaScript操作数组的所有方法方式。包含了ES6新增的方法。会在操作方法上解释出现的版本。 内容较多&#xff0c;建议收藏查看。 push(): 在数组末尾添加一个或多个元素&#xff0c;并返回新的长度。 let arr [1, 2, 3]; let newLength arr.push(4, 5); console.…

【JS重点18】原型链(面试重点)

一&#xff1a;原型链底层原理 以下面一段代码为例&#xff0c;基于原型对象&#xff08;Star构造函数的原型对象&#xff09;的继承使得不同构造函数的原型对象关联在一起&#xff08;此处是最大的构造函数Object原型对象&#xff09;&#xff0c;并且这种关联的关系是一种链…

CleanShot X for Mac v4.7 屏幕滚动长截图录像工具(保姆级教程,小白轻松上手,简单易学)

Mac分享吧 文章目录 一、下载软件二、部分特有功能效果1、截图软件的普遍常用功能&#xff08;画框、箭头、加文字等&#xff09;都具备&#xff0c;不再详细介绍2、ABCD、1234等信息标注&#xff08;每按一下鼠标&#xff0c;即各是A、B、C、D...等&#xff09;3、截图更换背…

SQL注入-下篇

HTTP注入 一、Referer注入 概述 当你访问一个网站的时候&#xff0c;你的浏览器需要告诉服务器你是从哪个地方访问服务器的。如直接在浏览器器的URL栏输入网址访问网站是没有referer的&#xff0c;需要在一个打开的网站中&#xff0c;点击链接跳转到另一个页面。 Less-19 判…

Oracle中先进先出数据结构的例子

在Oracle中&#xff0c;实现先进先出&#xff08;FIFO&#xff09;数据结构的一个典型例子可以通过设计和查询特定的表来完成。以下是一个简化的例子来说明这个概念&#xff1a; 1. 设计表结构 首先&#xff0c;我们需要一个包含“入队”时间戳的表来模拟队列的行为。以下是一…

Python部分库函数

目录 一、常规函数 元组相关函数 1.元组的创建 2.元组多变量赋值 列表相关函数 1.列表的创建 &#xff08;1&#xff09;将至于中括号中的、用逗号分隔开的一组数据赋值给一个变量&#xff0c;数据可以是多个也可以是一个 &#xff08;2&#xff09;使用list函数 &…

第29讲:Ceph集群使用RBD块存储设备与K8S的PV集成

文章目录 1.Ceph集群使用RBD块存储与K8S集成简介2.Ceph集群RBD块存储与K8S PV存储卷集成2.1.创建K8S集群PV使用的块存储2.2.创建K8S集群访问RBD块存储设备的认证用户2.3.将认证用户的Key存储在K8S Secret资源中2.4.在K8S集群的所有节点中安装Ceph命令2.5.创建PV及PVC资源使用RB…

C#开发-集合使用和技巧(八)集合中的排序Sort、OrderBy、OrderByDescending

C#开发-集合使用和技巧&#xff08;八&#xff09;集合中的排序Sort、OrderBy、OrderByDescending List<T>.Sort()IEnumerable<T>.OrderBy()Enumerable<T>.OrderByDescending() 在C#中&#xff0c;List<T> 类提供了多种方法来进行排序&#xff0c;最常…

浔川法务部通知——浔川法务部

原文链接&#xff1a;如何用python做一个用户登录界面——浔川python社-CSDN博客 抄袭链接&#xff1a;用python做的一个登录界面——浔川python社-易微帮 浔川python社原创文章被抄袭&#xff0c;请抄袭网站删除文章。 我方于昨夜联系了CSDN举报中心。如不删除&#xff0c;我…

jax.nn.initializers.glorot_normal()

import jax import jax.numpy as jnp from jax import random import jax.nn.initializers as init# 设置随机数种子 key random.PRNGKey(42)# 定义权重的形状 shape (in_dim, out_dim)# 获取 Glorot 正态初始化函数 glorot_normal_init init.glorot_normal()# 初始化权重 w…

QT基础 - QMainWindow主窗口

目录 零. 简介 一. 菜单栏 二. 工具栏 三. 状态栏 四. 可停靠区域 五. 总结 零. 简介 QMainWindow 是 Qt 中用于构建主窗口的类。 它通常包含以下几个主要部分&#xff1a; 菜单栏&#xff1a;用于提供各种操作选项。工具栏&#xff1a;放置常用的操作按钮。中心区域&…

搭建Vue的环境

目录 # 开篇 步骤一&#xff0c;准备Vue 的环境 步骤二&#xff0c;下载Vue.js的包 步骤三&#xff0c;创建并打开写前端代码的文件夹 步骤四&#xff0c;在VSCode中引入Vue.js的包 步骤五&#xff0c;创建第一个vue.html Vue其他知识 Vue.config命令 # 开篇 介绍&…

详细分析Element Plus的el-pagination基本知识(附Demo)

目录 前言1. 基本知识2. Demo3. 实战 前言 需求&#xff1a;从无到有做一个分页并且附带分页的导入导出增删改查等功能 前提一定是要先有分页&#xff0c;作为全栈玩家&#xff0c;先在前端部署一个分页的列表 相关后续的功能&#xff0c;是Java&#xff0c;推荐阅读&#x…