当前位置: 首页 > news >正文

浅谈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 servicelogErrorToMyService(error, errorInfo);}render() {if (this.state.hasError) {// You can render any custom fallback UIreturn <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;

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • SpringBoot项目架构实战之“网关zuul搭建“
  • 机器学习筑基篇,​Ubuntu 24.04 快速安装 PyCharm IDE 工具,无需激活!
  • 景联文科技打造高质量图文推理问答数据集,赋能大语言模型提升推理能力
  • Java内存划分详解:从基础到进阶
  • C++命名空间详细介绍
  • iOS多target时怎么对InfoPlist进行国际化
  • 流程图编辑框架LogicFlow-vue-ts和js
  • spark基于Spark的对招聘信息的分析与设计-计算机毕业设计源码50716
  • 好玩的珠玑妙算-加作弊带概率空间+日志存储240705mindMaster
  • C# IOC容器、依赖注入和控制反转
  • 统信UOS桌面操作系统上删除系统升级后GRUB中的回滚条目与备份
  • kotlin flow collect collectLatest 区别
  • gitee代码初次上传步骤
  • JavaScript(7)——数组
  • 界面控件DevExpress JS ASP.NET Core v24.1 - 全新的分割器组件
  • 《深入 React 技术栈》
  • 【EOS】Cleos基础
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • AHK 中 = 和 == 等比较运算符的用法
  • bearychat的java client
  • HTTP中GET与POST的区别 99%的错误认识
  • Java多线程(4):使用线程池执行定时任务
  • Python 反序列化安全问题(二)
  • Ruby 2.x 源代码分析:扩展 概述
  • sessionStorage和localStorage
  • springMvc学习笔记(2)
  • Vue ES6 Jade Scss Webpack Gulp
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 彻底搞懂浏览器Event-loop
  • 给Prometheus造假数据的方法
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 前端
  • 悄悄地说一个bug
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 使用API自动生成工具优化前端工作流
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 译有关态射的一切
  • 中文输入法与React文本输入框的问题与解决方案
  • 自制字幕遮挡器
  • scrapy中间件源码分析及常用中间件大全
  • # Apache SeaTunnel 究竟是什么?
  • (003)SlickEdit Unity的补全
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (void) (_x == _y)的作用
  • (二)Kafka离线安装 - Zookeeper下载及安装
  • (二十六)Java 数据结构
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (七)Java对象在Hibernate持久化层的状态
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (四) 虚拟摄像头vivi体验
  • (四)React组件、useState、组件样式
  • (五)c52学习之旅-静态数码管