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

React19学习-初体验

升级react19版本

  1. 安装
npm install react@beta react-dom@beta

如果使用ts则需要在package.json中添加。等正式版发布直接可以使用@types/react

  "overrides": {"@types/react": "npm:types-react@beta","@types/react-dom": "npm:types-react-dom@beta"}

官方文档

初始化项目

  1. npm create vite 选vanilla 和 ts
  2. 配置vite.config.ts
import {defineConfig} from "vite";
import react from '@vitejs/plugin-react';
/** @type {import('vite').UserConfig} */
export default {plugins:[react()]
}
  1. 安装依赖,如下package.json文件
{"name": "react19_exp","private": true,"version": "0.0.0","type": "module","scripts": {"dev": "vite","build": "tsc && vite build","preview": "vite preview"},"devDependencies": {"@types/node": "^20.12.10","@vitejs/plugin-react": "^4.2.1","typescript": "^5.2.2","vite": "^5.2.0"},"dependencies": {"@types/react": "npm:types-react@beta","@types/react-dom": "npm:types-react-dom@beta","react": "^19.0.0-beta-b498834eab-20240506","react-dom": "^19.0.0-beta-b498834eab-20240506"},"overrides": {"@types/react": "npm:types-react@beta","@types/react-dom": "npm:types-react-dom@beta"}
}
  1. 配置tsconfig.json
{"compilerOptions": {"target": "ES2020","useDefineForClassFields": true,"module": "ESNext","lib": ["ES2020", "DOM", "DOM.Iterable"],"skipLibCheck": true,/* Bundler mode */"moduleResolution": "bundler","allowImportingTsExtensions": true,"resolveJsonModule": true,"isolatedModules": true,"noEmit": true,/* Linting */"strict": true,"noUnusedLocals": true,"noUnusedParameters": true,"noFallthroughCasesInSwitch": true,"jsx": "react-jsx"},"include": ["src"],"references": [{ "path": "./tsconfig.node.json" }]/*tsconfig.node.json{"compilerOptions": {"composite": true,"skipLibCheck": true,"module": "ESNext","moduleResolution": "bundler","allowSyntheticDefaultImports": true,"strict": true},"include": ["vite.config.ts"]}
*/
}
  1. 之后将项目中的ts可以改为tsx启动项目即可

react19新特性体验

表单相关Hooks

状态突变

什么是状态突变?状态突变是指系统或对象的状态在某个时间点发生突然、不可预测的变化。
例如,当用户提交表单以更改其姓名时,将发出 API 请求,然后处理响应。过去,需要手动处理挂起状态、错误、乐观更新和顺序请求。过去使用方式代码示例

function UpdateName({}) {const [name, setName] = useState("");const [error, setError] = useState(null);const [isPending, setIsPending] = useState(false);const handleSubmit = async () => {setIsPending(true);const error = await updateName(name);setIsPending(false);if (error) {setError(error);return;} redirect("/path");};return (<div><input value={name} onChange={(event) => setName(event.target.value)} /><button onClick={handleSubmit} disabled={isPending}>Update</button>{error && <p>{error}</p>}</div>);
}

现在React提供了useTransition钩子,19使用示例

import {useState, useTransition} from "react";function updateName(name:string):Promise<string>{return new Promise((r)=>{setTimeout(()=>{if (!name)r("name不能为空")},2000)})
}export default ()=>{const [name, setName] = useState("");const [error, setError] = useState<string|null>(null);const [isPending, startTransition] = useTransition();const handleSubmit = () => {startTransition(async () => {const error = await updateName(name);if (error) {setError(error);return;}})};const renderLoading = ()=>{return <div className="loader"></div>}return (<div><input value={name} onChange={(event) => setName(event.target.value)}/>{isPending && renderLoading()}<button onClick={handleSubmit} disabled={isPending}>Update</button>{error && <p>{error}</p>}</div>)
}

效果展示
请添加图片描述

表单提交状态+行为useActionState

useActionState 接受一个函数(“Action”),并返回一个包装的 Action 进行调用。调用包装的 Action 时, useActionState 将 Action 的最后一个结果返回为data作为state的值 ,并将 Action 的挂起状态返回 pending

//函数签名
useActionState<State,Payload>(action: (state: Awaited<State>,payload: Payload) => State | Promise<State>,//表单提交行为initialState: Awaited<State>, // 初始表单的值permalink?: string,  // 目前不太了解,推测是表单提交后达到某个条件跳转到该链接上。有明白的小伙伴可以评论区留言
): [state: Awaited<State>, dispatch: (payload: Payload) => void, isPending: boolean];

示例

import {useActionState, useEffect} from "react";
function updateName(name:string):Promise<string>{return new Promise((r)=>{setTimeout(()=>{if (!name)r("name不能为空")r(name)},2000)})
}
export default ()=>{const [state, submitAction, isPending] = useActionState<string>(async (previousState:string, formData) => {const state = await updateName(formData.get("name"));// handle successreturn state;},"初始name值",);return (<form action={submitAction}><input type="text" name="name" /><button type="submit" disabled={isPending}>Update</button>{isPending && <div className="loader"></div>}{state && <p style={{color:"green"}}>{state}</p>}</form>);
}

请添加%图片描述

获取父组件表单状态useFormStatus

该Hooks为Form下面的子组件提供form状态信息,让我们不依赖父组件注入的Context就能获取到父组件的表单状态。

子组件

import {useFormStatus} from "react-dom";export default ()=>{const {pending} = useFormStatus();return <button type="submit" disabled={pending} >提交表单</button>
}

父组件部分代码展示

 <form action={submitAction}><input type="text" name="name" /><ExpUseFormStatus></ExpUseFormStatus>{isPending && <div className="loader"></div>}{state && <p style={{color:"green"}}>{state}</p>}</form>

效果展示请添加图片描述

乐观更新useOptimistic

有时候有些结果99%会成功,我们希望让用户尽快看到页面展示效果。可以采用该钩子。
子组件

import {useOptimistic} from "react";
interface Props{currentName:stringonUpdateName:(name:string)=>void
}
function updateName(name:string):Promise<string>{return new Promise((r)=>{setTimeout(()=>{if (!name)r("name不能为空")r(name)},2000)})
}
export default({currentName, onUpdateName}:Props)=> {const [optimisticName, setOptimisticName] = useOptimistic(currentName);const submitAction = async (formData: { get: (arg0: string) => any; }) => {const newName = formData.get("name");setOptimisticName(newName);const updatedName = await updateName(newName);onUpdateName(updatedName);};return (<form action={submitAction}><p>Your name is(currentName):<span style={{color:"green"}}>{currentName}</span> </p><p>Your name is(optimisticName): {optimisticName}</p><p><label>Change Name:</label><inputtype="text"name="name"disabled={currentName !== optimisticName}/></p><button type="submit">提交</button></form>);
}

父组件

export default ()=>{const [currentName, setCurrentName] = useState("fancy")return (<><ExpUseOptimistic currentName={currentName} onUpdateName={(name)=>setCurrentName(name)}></ExpUseOptimistic></>)
}

结果展示请添加图片描述

其他

use

use Hook让我们可以读取Context和Promise的值并且可以在循环和条件语句(如 if)中调用 use。但需要注意的是,调用 use 的函数仍然必须是一个组件或 Hook。

import { use } from 'react';function MessageComponent({ messagePromise }) {const message = use(messagePromise);const theme = use(ThemeContext);// ...

ref

以后不需要forward ref做转发了

function MyInput({placeholder, ref}) {return <input placeholder={placeholder} ref={ref} />
}<MyInput ref={ref} />

ref的清理函数,当组件卸载时,React 将调用从回调返回的 ref 清理函数。这适用于 DOM 引用、类组件引用和 useImperativeHandle .

<inputref={(ref) => {// ref created// NEW: return a cleanup function to reset// the ref when element is removed from DOM.return () => {// ref cleanup};}}
/>

Context 不再需要<Context.Provider>

const ThemeContext = createContext('');function App({children}) {return (<ThemeContext value="dark">{children}</ThemeContext>);  
}

支持在组件中编写Meta标签

当 React 渲染这个组件时,它会看到 <title> <link><meta> 标签,并自动将它们提升到文档 <head> 部分。通过本机支持这些元数据标记,我们能够确保它们适用于仅限客户端的应用、流式处理 SSR 和服务器组件。

function BlogPost({post}) {return (<article><h1>{post.title}</h1><title>{post.title}</title><meta name="author" content="Josh" /><link rel="author" href="https://twitter.com/joshcstory/" /><meta name="keywords" content={post.keywords} /><p>Eee equals em-see-squared...</p></article>);
}

支持预加载资源

文档
在初始文档加载和客户端更新期间,告知浏览器可能需要尽早加载的资源可能会对页面性能产生巨大影响。React 19 包含许多用于加载和预加载浏览器资源的新 API,以便尽可能轻松地构建出色的体验,而不会因资源加载效率低下而受到阻碍。

import { prefetchDNS, preconnect, preload, preinit } from 'react-dom'
function MyComponent() {preinit('https://.../path/to/some/script.js', {as: 'script' }) // loads and executes this script eagerlypreload('https://.../path/to/font.woff', { as: 'font' }) // preloads this fontpreload('https://.../path/to/stylesheet.css', { as: 'style' }) // preloads this stylesheetprefetchDNS('https://...') // when you may not actually request anything from this hostpreload("https://example.com/font.woff2", {as: "font"});//加载字体preload("https://example.com/style.css", {as: "style"});//预加载css文件preconnect('https://...') // when you will request something but aren't sure what}

这些会被转化为以下形式

  <head><!-- links/scripts are prioritized by their utility to early loading, not call order --><link rel="prefetch-dns" href="https://..."><link rel="preconnect" href="https://..."><link rel="preload" as="font" href="https://.../path/to/font.woff"><link rel="preload" as="style" href="https://.../path/to/stylesheet.css"><script async="" src="https://.../path/to/some/script.js"></script></head>

我们可以在渲染时和事件处理中进行预加载。
如果知道组件或其子组件将使用特定资源,那么在渲染组件时调用 preload。
在渲染时示例

import { preload } from 'react-dom';function AppRoot() {preload("https://example.com/font.woff2", {as: "font"});// ……
}

时间中

import { preload } from 'react-dom';function CallToAction() {const onClick = () => {preload("https://example.com/wizardStyles.css", {as: "style"});startWizard();}return (<button onClick={onClick}>Start Wizard</button>);
}

相关文章:

React19学习-初体验

升级react19版本 安装 npm install reactbeta react-dombeta如果使用ts则需要在package.json中添加。等正式版发布直接可以使用types/react了 "overrides": {"types/react": "npm:types-reactbeta","types/react-dom": "npm:ty…...

【UE5】数字人基础

这里主要记录一下自己在实现数字人得过程中涉及导XSens惯性动捕&#xff0c;视频动捕&#xff0c;LiveLinkFace表捕&#xff0c;GRoom物理头发等。 一、导入骨骼网格体 骨骼网格体即模型要在模型雕刻阶段就要雕刻好表捕所需的表情体(blendshape)&#xff0c;后面表捕的效果直…...

OSTEP Projects:KV

本文将介绍操作系统导论&#xff08;Operating Systems: Three Easy Pieces&#xff09;作者所开源的操作系统相关课程项目 的 KV 部分&#xff0c;包含个人的代码实现和设计思路。 思路 题目要求实现一个最简单的数据库&#xff0c;以支持数据的持久化。 每个操作由格式为 o…...

JAVA学习笔记(第三周)

文章目录 继承概述使用场景继承的特点子类继承的内容成员变量访问特点成员方法访问特点方法的重写构造方法this super 多态多态的表现形式多态的前提成员变量和方法调用instanceof优势弊端 包包名的规则全类名final常量 权限修饰符代码块 继承 概述 继承就是子类继承父类的特征…...

linux 内核驱动 -- reboot -f 导致内核死机 而 reboot则不会引起问题

问题描述&#xff0c;定于与解决&#xff1a;...

【vue-echarts】 报错问题解决 “Error: Component series.pie not exists. Load it first.“

目录 问题描述解决【解决1】【解决2】 问题描述 使用 vue-echarts 时导入的文件 import VChart from vue-echarts/components/ECharts import echarts/lib/chart/line import echarts/lib/chart/bar import echarts/lib/chart/pie import echarts/lib/component/legend impor…...

MySQL慢查询SQL优化

一、慢查询日志 描述&#xff1a;通过慢查询日志等定位那些执行效率较低的SQL语句 查看 # 慢查询是否开启 show variables like slow_query_log%; # 慢查询超时时间 show variables like long_query_time%;执行SQL 开启慢查询日志 set global slow_query_log ON;设置慢查…...

【嵌入式DIY实例】-DDS信号生成器

DDS信号生成器 文章目录 DDS信号生成器1、AD9805介绍2、硬件准备与接线3、代码实现在本文中,将详细介绍如何使用AD9850来搭建一个简易的DDS(Direct Digital signal )信号生成器。 1、AD9805介绍 AD9850是一款高度集成的器件,采用先进的DDS技术,内置一个高速、高性能数模转…...

java设计模式四 桥接模式

桥接模式关注于将抽象部分与实现部分分离&#xff0c;使它们可以独立变化。它通过在抽象和实现之间建立一个桥梁来实现这一目的。这种设计模式属于结构型模式。 假设我们要设计一个图形编辑器&#xff0c;其中图形&#xff08;如圆形、正方形&#xff09;可以有不同的颜色填充…...

《Python编程从入门到实践》day24

# 昨日知识点学习 创建外星人从一个到一行 # 主程序snipdef _create_fleet(self):"""创建外星人群"""# 创建一个外星人并计算一行可容纳多少个外星人# 外星人的间距为外星人的宽度alien Alien(self)alien_width alien.rect.widthavailable_sp…...

【hackmyvm】 Animetronic靶机

靶机测试 arp-scanporturl枚举exiftool套中套passwordsudo 提权 arp-scan arp-scan 检测局域网中活动的主机 192.168.9.203 靶机IP地址port 通过nmap扫描&#xff0c;获取目标主机的端口信息 ┌──(root㉿kali)-[/usr/share/seclists] └─# nmap -sT -sV -O 192.16…...

[附源码]石器时代_恐龙宝贝内购版_三网H5手游_带GM工具

石器时代之恐龙宝贝内购版_三网H5经典怀旧Q萌全网通手游_Linux服务端源码_视频架设教程_GM多功能授权后台_CDK授权后台 本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff0…...

RS2255XN功能和参数介绍及PDF资料

RS2255XN是一款由Runic&#xff08;润石&#xff09;公司生产的模拟开关。以下是关于RS2255XN的一些技术参数和特点&#xff1a; 封装&#xff1a;MSOP-10 电源电压范围&#xff1a;2.5V至5.5V 工作温度范围&#xff1a;-40C至125C 类型&#xff1a;模拟开关 品牌&#xff1a;R…...

设计模式——外观模式(Facade)

外观模式&#xff08;Facade Pattern&#xff09; 是一种结构型设计模式&#xff0c;它为一个子系统中的一组接口提供一个统一的高层接口&#xff0c;使得子系统更加容易使用。这种类型的设计模式属于结构型模式&#xff0c;它向客户端提供了一个接口&#xff0c;隐藏了子系统的…...

【linux软件基础知识】Linux 中的普通进程的调度机制

活动集Active processes和过期集Expired processes 为了实现静态优先级较低的进程没有完全锁定并有机会运行,Linux 调度程序维护两个不相交的可运行进程集:活动集和过期集。 此机制是完全公平调度程序 (CFS) 算法的一部分。 以下是这两组的工作原理: 活动集Active proces…...

keil5软件安装教程(MDKv5.39)

keil5软件安装分为三部分&#xff1a; 目录 1.安装mdk 2.激活mdk 3.安装STM32芯片包 1.安装mdk 安装包链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1PZoGhzI5Y19ROv7xe9QJKA?pwdgt3s 提取码&#xff1a;gt3s 1、下载keil5的压缩包并解压&#xff0c;鼠…...

改变视觉创造力:图像合成中基于样式的生成架构的影响和创新

原文地址&#xff1a;revolutionizing-visual-creativity-the-impact-and-innovations-of-style-based-generative 2024 年 4 月 30 日 介绍 基于风格的生成架构已经开辟了一个利基市场&#xff0c;它将机器学习的技术严谨性与类人创造力的微妙表现力融为一体。这一发展的核…...

【LAMMPS学习】八、基础知识(5.8)LAMMPS 中热化 Drude 振荡器教程

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…...

基于SpringBoot的全国风景区WebGIS按省展示实践

目录 前言 一、全国风景区信息介绍 1、全国范围内数据分布 2、全国风景区分布 3、PostGIS空间关联查询 二、后台查询的设计与实现 1、Model和Mapper层 2、业务层和控制层设计 三、WebGIS可视化 1、省份范围可视化 2、省级风景区可视化展示 3、成果展示 总结 前…...

深入理解网络原理3----TCP核心特性介绍(上)【面试高频考点】

文章目录 前言TCP协议段格式一、确认应答【保证可靠性传输的机制】二、超时重传【保证可靠性传输的机制】三、连接管理机制【保证可靠性传输的机制】3.1建立连接&#xff08;TCP三次握手&#xff09;---经典面试题3.2断开连接&#xff08;四次挥手&#xff09;3.3TCP状态转换 四…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...