浅谈React

news2025/4/21 20:30:17

forwardRef和useImperativeHandle的联动使用

import React, { useImperativeHandle, useRef } from "react"
import { forwardRef } from "react"

const CustomInput = forwardRef((props, ref) => {
    const inputRef = useRef<HTMLInputElement>(null)

    useImperativeHandle(ref, () => ({
        focus: () => {
            inputRef.current?.focus()
        }
    }))
    return <div>
        <input ref={inputRef} />
    </div>
})

export default CustomInput

巧用children

  • 一般用法
父组件:

import React from "react"
import Child from './Child'

const CustomInput = () => {
    return <Child>
        <div>hello 靓仔</div>
    </Child>
}

export default CustomInput

子组件:

import React from "react"


const Child = ({
    children
}) => {
    return <div>{children}</div>
}

export default Child
  • 函数用法
父组件:

import React from "react"
import Child from './Child'

const CustomInput = () => {
    return <Child>
        {(arr)=><div>
            {arr.map((v,idx)=>{
                return <div key={idx}>{v}</div>
            })}
            </div>}
    </Child>
}

export default CustomInput

子组件:

import React from "react"


const Child = ({
    children
}) => {
    const arr = [1,2,4,5]
    return <div>{children(arr)}</div>
}

export default Child

useEffect

  • 没有依赖,类似于componentDidMount和componentDidUpdate
import React, { useEffect, useState } from "react"


const Detail = () => {
    const [count, setCount] = useState(1)
    const [num,setNum] = useState(2)
    useEffect(()=>{
        console.log(count,'count',num,'num')
    })
    return <div>
        <div onClick={() => setCount(count + 1)}>add count</div>
        <div onClick={() => setNum(num + 1)}>add num</div>
        <div>count: {count}</div>
        <div>num: {num}</div>
    </div>
}

export default Detail

  • 依赖是个空数组,相当于componentDidMount
import React, { useEffect, useState } from "react"


const Detail = () => {
    const [count, setCount] = useState(1)
    const [num,setNum] = useState(2)
    useEffect(()=>{
        console.log(count,'count',num,'num')
    },[])
    return <div>
        <div onClick={() => setCount(count + 1)}>add count</div>
        <div onClick={() => setNum(num + 1)}>add num</div>
        <div>count: {count}</div>
        <div>num: {num}</div>
    </div>
}

export default Detail

 

 

  • 有依赖,componentDidMount和对应依赖的componentDidUpdate
import React, { useEffect, useState } from "react"


const Detail = () => {
    const [count, setCount] = useState(1)
    const [num,setNum] = useState(2)
    useEffect(()=>{
        console.log(count,'count',num,'num')
    },[num])
    return <div>
        <div onClick={() => setCount(count + 1)}>add count</div>
        <div onClick={() => setNum(num + 1)}>add num</div>
        <div>count: {count}</div>
        <div>num: {num}</div>
    </div>
}

export default Detail

 

 

useEffect和useLayoutEffect

useEffect在渲染后执行,而useLayouEffect是在渲染之前执行

最典型的例子就是实现一个tooltip组件,在性能比较差的情况下,useEffect会先渲染初始状态再更新,而useLayoutEffect会阻塞UI的更新即不会出现组件闪烁的情况~

阻塞代码:

let now = performance.now();
while (performance.now() - now < 100) {
}

useEffect在性能差的情况下会出现以下效果

useContext

依赖注入

父级:
export const ThemeContext = createContext({});
const App = ()=>{

return  <ThemeContext.Provider value={{name:"real hot"}}>
        ......
    </ThemeContext.Provider>
}

 子级:
  const context = useContext(ThemeContext)
  console.log(context)

useState的变动

在react管辖下(react17.x.x)

  • 函数形式

状态能够更改多次,只渲染一次

const handleCount= ()=>{
  setCount(count=>count+1)
  setCount(count=>count+1)
}

  • 对象形式

多次更改状态会被合并成一次更改,即一次生效其他无效,只渲染一次

const handleCount= ()=>{
  setCount(count+1)
  setCount(count+1)
}

在异步任务/原生事件下(react17.x.x)

const handleCount= ()=>{
setTimeout(()=>{
  setCount(count=>count+1)
  setCount(count=>count+1)
})
}

 

版本的演变(React18)

react18之后在异步操作或者react事件中都是批量更新,即多个状态更新合成一次渲染,若需要多次渲染可使用flushsync

const handleCount= ()=>{
  flushSync(()=>{
    setCount(count=>count+1)
  })
  flushSync(()=>{
    setCount(count=>count+1)
  })

}

探索生命周期函数

父子组件生命周期执行顺序

挂载: 

更新: 

卸载: 

错误处理

生命周期方法:

getDerivedStateFromError
componentDidCatch

缺点(没办法捕获):

  • 异步操作
  • 事件处理函数报错
  • 错误边界自己报错 
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // Update state so the next render will show the fallback UI.
    return { hasError: true };
  }

  componentDidCatch(error, errorInfo) {
    // You can also log the error to an error reporting service
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // You can render any custom fallback UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

实现一个简单的Message

import ReactDOM from 'react-dom';
import { Modal } from 'antd';
const ToastFn = () => {
let parent = null;
return {
open: function ({ el, container = document.body }) {
// this.destroy();
parent = document.createElement('div');
document.body.appendChild(parent);
ReactDOM.render(<Modal open onCancel={this.destroy}>{el}</Modal>, parent)
},
destroy: function () {
ReactDOM.unmountComponentAtNode(parent);
},
};
};
const Toast = ToastFn();
export default Toast;

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

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

相关文章

【以史为镜、以史明志,知史爱党、知史爱国】中华上下五千年之-宋朝(北宋)

宋朝&#xff08;960年—1279年&#xff09;是中国历史上承五代十国下启元朝的朝代&#xff0c;分北宋和南宋两个阶段&#xff0c;共历十八帝&#xff0c;享国三百一十九年。 北宋 赵匡胤&#xff08;宋太祖&#xff09;-赵光义&#xff08;宋太宗&#xff09;-赵恒&#xff08…

【MyBatis】——入门基础知识必会内容

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

【初阶数据结构】树与二叉树:从零开始的奇幻之旅

初阶数据结构相关知识点可以通过点击以下链接进行学习一起加油&#xff01;时间与空间复杂度的深度剖析深入解析顺序表:探索底层逻辑深入解析单链表:探索底层逻辑深入解析带头双向循环链表:探索底层逻辑深入解析栈:探索底层逻辑深入解析队列:探索底层逻辑深入解析循环队列:探索…

文华财经盘立方博易大师boll布林带指标公式源码

TT:TIME>850&&TIME<1150; MID:MA(CLOSE,26);//求N个周期的收盘价均线&#xff0c;称为布林通道中轨 TMP2:STD(CLOSE,26);//求M个周期内的收盘价的标准差 TOP:MID2*TMP2;//布林通道上轨 BOTTOM:MID-2*TMP2;//布林通道下轨 A:EVERY(ISDOWN,2)&&TT&&…

SQL职场必备:掌握数据库技能提升职场竞争力

&#x1f482; 个人网站:【 摸鱼游戏】【网址导航】【神级代码资源网站】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

Centos7下zabbix安装与部署

Centos7下zabbix安装与部署 一、Zabbix介绍 1、zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案 2、zabbix能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各…

Android初学者书籍推荐

书单 1.《Android应用开发项目式教程》&#xff0c;机械工业出版社&#xff0c;2024年出版2.《第一行代码Android》第二版3.《第一行代码Android》第三版4.《疯狂Android讲义》第四版5.《Android移动应用基础教程&#xff08;Android Studio 第2版&#xff09;》 从学安卓到用安…

ICC2:no path与scenario status

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 有星球小伙伴提问为什么pt能报出来path而ICC2报告不出来&#xff0c;排除两边sdc约束不同的问题&#xff0c;那就是ICC2并没有设置好scenario status&#xff0c;最后发现是没有…

Java接口案例

一案例要求&#xff1a; 二代码&#xff1a;(换方案只需要将操作类第二行的new新对象修改就能更改项目) Ⅰ&#xff1a;&#xff08;主函数&#xff09; package d1;public class test {public static void main(String[] args) {operator anew operator();a.show();a.averag…

从0开始的STM32HAL库学习2

外部中断(HAL库GPIO讲解) 今天我们会详细地学习STM32CubeMX配置外部中断&#xff0c;并且讲解HAL库的GPIO的各种函数。 准备工作&#xff1a; 1、STM32开发板&#xff08;我的是STM32F103C8T6&#xff09; 2、STM32CubeMx软件、 IDE&#xff1a; Keil软件 3、STM32F1xx/ST…

南京邮电大学运筹学课程实验报告3 整数规划问题求解 指导

一、题目描述 实验三 整数规划问题求解    实验属性&#xff1a; 设计型    实验目的 1&#xff0e;理解图的整数规划问题概念&#xff1b; 2&#xff0e;掌握运筹学软件的使用方法&#xff1b; 3. 掌握整数规划问题求解原理和方法。 实…

转:in-context learning浅显易懂解释

in-context learning的learning和 machine learning、deep learning、supervise learning、unsupervise learning不一样&#xff0c;这些learning是用梯度更新模型参数的。 context就是上下文的意思&#xff0c;就是你输入的上下文。in-context就是从你输入的上下文里学习到了…

短视频矩阵系统全解析:让获客变得更简单

随着数字媒体的迅猛发展&#xff0c;短视频已成为人们生活中不可或缺的一部分。对于企业而言&#xff0c;如何有效利用短视频平台吸引目标用户&#xff0c;实现高效获客&#xff0c;成为了一个亟待解决的问题。本文将全面解析短视频矩阵系统&#xff0c;带您领略其独特魅力&…

CTF php RCE(三)

0x07 日志文件包含 判断类型 使用kali curl -I urlF12 打开F12开发者工具&#xff0c;选中之后F5刷新查看server类型即可 配置文件 直接包含或者访问如果有回显就是&#xff0c; NGINX&#xff1a;NGINX 的配置文件通常位于 /etc/nginx/ 目录下&#xff0c;具体的网站配…

ICC2:如何设置don‘t use

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 set_attribute -objects [get_lib_cells */xx] -name dont_use -value true set_dont_touch [get_lib_cells */xx] true是有dont use效果的&#xff0c;还有set_lib_cell_purpo…

Vue2/Vue3实现全局/局部添加防篡改水印的效果。删除元素无效!更改元素属性无效!支持图片、元素、视频等等。

水印目的 版权保护:水印可以在图片、文档或视频中嵌入作者、品牌或版权所有者的信息,以防止未经授权的复制、传播或使用。当其他人使用带有水印的内容时,可以追溯到原始作者或版权所有者,从而加强版权保护。 身份识别:水印可以用作作者或品牌的标识符,使观众能够轻松识…

14.爬虫---Selenium 经典动态渲染工具的使用

14.Selenium 经典动态渲染工具的使用 1.查看chrome浏览器版本2.ChromeDriver 安装3.Selenium 安装4.验证安装5.基本用法5.1启动浏览器5.2导航到页面5.3查找元素5.3.1单个元素 find_element5.3.2多个元素 find_elements 5.4 执行操作5.5 动作链ActionChains5.6 执行 JavaScript …

在linux中安装docker

文章目录 1、安装依赖2、安装docker的下载源3、安装docker4、设置Docker服务开机自启 1、安装依赖 sudo yum install -y yum-utils2、安装docker的下载源 sudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repohttps://download.do…

【Qt 基础】Qt Creator 的初步使用、创建项目的过程

文章目录 1. Qt SDK 中工具程序的介绍2. 创建第一个 Qt 项目的前置步骤 1. Qt SDK 中工具程序的介绍 下载之后会出现下面几个程序&#xff1a; Assistant 表示 Qt 自带的离线官方文档&#xff1b; Designer &#xff1a;Qt设计师&#xff0c;图形化的设计界面的工具&#xf…

“删错文件不再怕:双管齐下的数据恢复策略“

一、删错文件的常见困境与影响 在日常的计算机操作中&#xff0c;删错文件是一个令人头疼的问题。无论是因为疏忽大意、误操作&#xff0c;还是软件故障、系统崩溃&#xff0c;一旦重要文件被误删除&#xff0c;往往会带来连锁反应。这些文件可能包含工作文档、学习资料、家庭…