浅谈React

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;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java并发编程概述

java并发编程概述 一. 进程和线程的概念 进程是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分配的基本单位。进程是程序运行的实例&#xff0c;每当操作系统在运行一个程序时&#xff0c;会为其创建一个进程。每个进程都拥有自己的一整套变量。…

同享人力资源管理系统-TXEHR V15 DownloadTemplate 文件读取漏洞复现

0x01 产品简介 同享人力资源管理系统(TXEHR V15)是一款专为现代企业设计的人力资源管理软件解决方案,旨在通过先进的信息化手段提升企业人力资源管理的效率与水平。该系统集成了组织人事、考勤管理、薪资核算、招聘配置、培训发展、绩效管理等核心模块,并提供了灵活的配置…

TikTok短视频矩阵管理系统源码

在数字化浪潮汹涌的今天&#xff0c;短视频已成为人们生活中不可或缺的一部分。TikTok作为短视频领域的佼佼者&#xff0c;其用户基数庞大&#xff0c;影响力深远。然而&#xff0c;对于众多内容创作者和营销人员来说&#xff0c;如何高效管理多个TikTok账号&#xff0c;实现批…

解决QT creator中文乱码问题

1.首先设置文本编辑器为UTF-8 先在工具-选项-文本编辑器-behavior部分选择文件编码为UTF-8&#xff0c;紧接着是选择“如果编码是UTF-8则添加”&#xff0c;如下图 2.设置ext code for tools 为system 具体解决办法是 工具-选项-环境-interfaces这一栏有一个“Text code for to…

网安防御保护-小实验

1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问 2、生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 3、办公区设备10.0.2.10不允许访问DMZ区的FTP服务器和HTTP服务器&#xff0c;仅能ping通…

前端如何取消接口调用

&#x1f9d1;‍&#x1f4bb; 写在开头 点赞 收藏 学会&#x1f923;&#x1f923;&#x1f923; 1. xmlHttpRequest是如何取消请求的&#xff1f; 实例化的XMLHttpRequest对象上也有abort方法 const xhr new XMLHttpRequest(); xhr.addEventListener(load, function(e)…

昇思25天学习打卡营第17天|应用实践之SSD目标检测

基本介绍 今天要学习的内容是计算机视觉领域中的目标检测任务。与图像分类相比&#xff0c;目标检测更难&#xff0c;因为目标检测不仅要检测出图片中的物体的类别&#xff0c;还要检测出该物体的位置。现主流的目标检测算法大致可分为两种&#xff0c;一种是基于CNN的&#xf…

MQTT是什么,物联网

写文思路&#xff1a; 以下从几个方面介绍MQTT&#xff0c;包括&#xff1a;MQTT是什么&#xff0c;MQTT和webSocket的结合&#xff0c;以及使用场景&#xff0c; 一、MQTT是什么 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅消息…

Java技术栈总结:JVM虚拟机篇

一、Java的四种引用类型 1、强引用 最常见的引用&#xff0c;类似Object obj new Object()、String str “hello”。 如果一个对象具有强引用&#xff0c;垃圾回收器绝对不会回收它。即使抛出“OutOfMemoryError”错误&#xff0c;程序终止&#xff0c;也不会随意回收具有强…

市场趋势的智能预测:Kompas.ai如何洞察未来市场动向

在商业领域&#xff0c;市场趋势预测是企业制定战略规划和做出明智决策的关键。准确把握市场动向能够帮助企业及时调整战略&#xff0c;抓住机遇&#xff0c;规避风险。Kompas.ai&#xff0c;一款先进的人工智能市场分析工具&#xff0c;正通过其深度学习和数据分析能力&#x…

重塑肌肤DNA!华贝甄选解锁生命活力密码

在探索生命奥秘与健康的征途中&#xff0c;华贝甄选携手前沿干细胞科技&#xff0c;为您开启一场前所未有的健康革命。我们深知&#xff0c;生命的活力源自细胞的不懈更新与修复&#xff0c;而干细胞&#xff0c;正是这场生命奇迹的钥匙。 【重塑内分泌平衡&#xff0c;焕发自…

Sentieon Arm版本:进一步降低基因组计算成本

前不久&#xff0c;Arm在其社区的HPC blog上发布了一篇Sentieon在低通量全基因组&#xff08;LP-WGS&#xff09;的应用案例。 图1 伴随着大规模基因组学的需求持续增长&#xff0c;基因测序成本的降低使得研究和分析更加广泛。而在基因组学的每一个应用背后,都有一系列计算密…

入驻长沙!全球数据资产理事会长江中游中心挂牌成立

在全球数据资产化浪潮的推动下&#xff0c;长江中游地区迎来了其在数字经济领域的重要里程碑。 近日&#xff0c;《数据资产长江中游生态论坛暨数据资产入表和价值转化研讨会》于长沙圆满落幕&#xff0c;会上各产业专家、企业高管&#xff0c;围绕数据产品开发、数据资产融资…

ICC2:如何检查input floating

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 input floating分为两种情况&#xff1a; input没接net的情况: get_flat_pins -f "direction &#xff1d;&#xff1d;in && undefined(net)" input接net…

数据结构:链表相关题目

链表反转 LeetCode地址&#xff1a;LCR 024. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 头插法&#xff1a; class Solution {public ListNode reverseList(ListNode head) {ListNode h1 new ListNode(-1);while(head!null){ListNode index new ListNode(head.val…

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

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

顺序结构 ( 五 ) —— 数据输入输出 【互三互三】

文章目录 &#x1f341;序 &#x1f341;一、字符输入函数getchar &#x1f341;二、字符输出函数putchar &#x1f341;三、通过cout流输出数据 &#x1f341;四、通过cin流读入数据 &#x1f341;五、格式化输入函数scanf &#x1f341;六、格式化输出函数printf &…

【每日一练】python面对对象的基本概念和用法(附实例)

面向对象编程&#xff08;OOP&#xff09;是一种程序设计方法&#xff0c;其基本概念包括对象、类、继承和封装。 对象&#xff1a;对象是系统中的基本单位&#xff0c;用于描述客观事物。每个对象包含一组属性和对这些属性进行操作的方法。对象是类的一个实例&#xff0c;具有…

高通开发系列 - LCD屏调试过程中的一些技巧

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 返回:专栏总目录 目录 打开开发者模式wifi adb shellmodetest测试使用异显CPU和GPU加速开性能模式进程绑定大核CPU设置和查询进程状态视频…

Java 中的阻塞 IO 和非阻塞 IO

Java 中的阻塞 IO 和非阻塞 IO 1、阻塞 IO&#xff08;Blocking IO&#xff09;2、非阻塞 IO&#xff08;Non-blocking IO&#xff09;3、区别与应用场景4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; IO&#xff08;输入输出&…