React18介绍及setState、suspense、useTransition、useDeferredValue的使用

article/2025/10/13 3:24:21

文章目录

  • 1. 带来了什么
  • 2. 创建项目
  • 3. 入口文件的改变
  • 4. setState
  • 5. 条件渲染传异步数据给子组件
  • 6. suspense结合异步组件实现条件渲染
  • 7. useTransition降级渲染
  • 8. useDeferredValue节流处理


1. 带来了什么

  • 改进已有属性,如自动批量处理【setState】、改进Suspense、组件返回undefined不再报错等
  • 支持Concurrent模式,带来新的API,如useTransition、useDeferredValue等

注意:React升级对于开发者而言,无需重写代码就能够使用React18

2. 创建项目

用以下几种方案创建出来的项目使用为react18版本:

  1. npx create-react-app myapp
  2. npm init react-app myapp
  3. yarn create react-app myapp

注意:

  1. nodejs版本一定要为16.x及以上版本,如果你用的是win笔记本,则操作系统不能低于win10
  2. react18中的webpack版本为5版本

3. 入口文件的改变

import React from 'react'
// react18它引入ReactDOM类的位置发生改变
import ReactDOM from 'react-dom/client'
// 在react18之后,不要用此方案来引入ReactDOM类
// import ReactDOM from 'react-dom'
import App from './App'// 把虚拟dom挂载到真实dom中的方法也发生了改变 由原来的render方法,变为 createRoot(dom节点).render(<App/>)
// 支持Concurrent模式[批处理,让setState都为异步] -- 提升性能
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<React.StrictMode><App /></React.StrictMode>
);// 也可以使用 React17 中的方案
// 不支持Concurrent模式,所以在react18之后就不要写此方案
// ReactDOM.render(
//   <React.StrictMode>
//     <App />
//   </React.StrictMode>,
//   document.getElementById('root')
// )

4. setState

在 react18 之后,setState 都为异步,无论写在什么样的语法环境中。

import React, { Component } from 'react'class App extends Component {state = {count: 100}addCount = () => {// 异步的,写成回调函数的方式,可以获得最新的数据状态this.setState(state => ({ count: state.count + 1 }),() => console.log(this.state.count))// 此方案在react18之前,它里面的操作是同步的,但在react18之后,它都为concurrent模式,都为异步// setTimeout(() => {//   this.setState(state => ({ count: state.count + 1 }))//   console.log(this.state.count)// }, 1)}render() {return (<div><h3>{this.state.count}</h3><button onClick={this.addCount}>累加count</button></div>)}
}export default App

在这里插入图片描述

如果在 react18 中,我们想要让 setState 变为同步,我们可以使用 flushSync 方法:

import React, { Component } from 'react'
// flushSync它方法就可以让里面的操作为同步
import { flushSync } from 'react-dom'class App extends Component {state = {count: 100}addCount = () => {// react18中,就想让setState它为同步【可以,但不要在生产中去用,不建议】// setState它就是同步的flushSync(() => {this.setState(state => ({ count: state.count + 1 }))})// 因为setState放在flushSync方法里面了,则它现在是一个同步的,所以在此处可以得到最新的数据console.log(this.state.count)}render() {return (<div><h3>{this.state.count}</h3><button onClick={this.addCount}>累加count</button></div>)}
}export default App

在这里插入图片描述

5. 条件渲染传异步数据给子组件

mock 数据:

[{ "id": 1, "name": "张三" },{ "id": 2, "name": "英子" },{ "id": 3, "name": "乐乐" }
]

父组件:

import React, { useEffect, useState } from 'react'
import User from './pages/User'const fetchUser = async () => {let ret = await (await fetch('/users.json')).json()return ret
}const App = () => {let [data, setData] = useState([])useEffect(() => {fetchUser().then(ret => setData(ret))}, [])return (<div>{/* 条件渲染 */}{data.length == 0 ? <div>加载中...</div> : <User data={data} />}</div>)
}export default App

子组件:

import React from 'react'const User = ({ data }) => {return (<div><ul>{data.map(item => (<li key={item.id}>{item.name}</li>))}</ul></div>)
}export default User

在这里插入图片描述

6. suspense结合异步组件实现条件渲染

父组件:

import React, { Suspense, useEffect, useState } from 'react'
import User from './pages/User'// 网络请求
// 返回值为  Promise
const fetchUser = async () => {let ret = await (await fetch('/users.json')).json()return ret
}// 创建一个用于解析promise中数据的方法 仿promise的3个状态
const wrapperPromise = promise => {// 定义一个promise的状态let status = 'pending'// 它就是promise解析出来的数据接受的变量let resultconst callbackPromise = promise.then(ret => {// promise执行成功的,返回成功的状态,并把数据赋值给resultstatus = 'success'result = ret},err => {// 把状态修改为失败,并把错误赋值给resultstatus = 'error'result = err})return {// 此方法中,才是把数据获取到read() {if (status === 'pending') {// 抛一个异常,这样它就会再来执行,此时就会有上一次的结果throw callbackPromise} else if (status === 'success') {return result} else if (status === 'error') {return result}}}
}const App = () => {let [data, setData] = useState(wrapperPromise(fetchUser()))return (<div><Suspense fallback={<div>加载中 .......................................</div>}><User users={data} /></Suspense></div>)
}export default App

子组件:

import React from 'react'// 函数组件,它需要返回jsx而不是一个promise对象
const User = ({ users }) => {// 通过此方法把promise中的数据读取出来let data = users.read()return (<div><ul>{data.map(item => (<li key={item.id}>{item.name}</li>))}</ul></div>)
}export default User

在这里插入图片描述

7. useTransition降级渲染

概述:

如果你有很多没那么着急的内容要渲染更新就可以使用此hook函数。它可以对于更新渲染进行降级,提高更重要的组件的提前渲染

使用:

import React, { useState, useTransition } from 'react'
// 可以对于更新渲染进行降级,提高更重要的组件的提前渲染const App = () => {let [count, setCount] = useState(100)// isPending 如果在更新等待渲染时isPending为true,没有等待更新不渲染时为false// startTransition 它是一个函数,在里面写的更新数据会进行降级let [isPending, startTransition] = useTransition()const addCount = () => {// 对于更新count的数据时行了降级,更新也就会降级startTransition(() => {setCount(v => v + 1)})}return (<div>{/* count更新它没有哪么的着急,可以让别的数据更新渲染先执行 */}<h3>{isPending ? '加载中...' : count}</h3><button onClick={addCount}>++++++</button></div>)
}export default App

在这里插入图片描述

8. useDeferredValue节流处理

概述:

该方法使得我们可以延迟更新某个不那么重要的部分,有节流防抖效果。可以将原来的更新进行推迟渲染,把重要的更新数据推到前面去更新渲染去。

使用:

父组件:

import React, { useState, useDeferredValue } from 'react'
import Search from './pages/Search'const App = () => {let [kw, setKw] = useState('')// 让数据更新降级,起到了节流的效果,让渲染平滑一些let deferredValue = useDeferredValue(kw)return (<div><h3>{kw}</h3><input value={kw} onChange={e => setKw(e.target.value.trim())} /><Search kw={deferredValue} /></div>)
}export default App

子组件:

import React from 'react'const Search = ({ kw }) => {console.log(kw)const data = Array(1000).fill('').map((_, index) => {return '搜索 -- ' + index + ' -- ' + kw})return (<div><ul>{data.map(item => (<li key={item}>{item}</li>))}</ul></div>)
}export default Search

在这里插入图片描述


http://chatgpt.dhexx.cn/article/qyBwWmGG.shtml

相关文章

【VUE】vue3学习笔记(异步组件,包含defineAsyncComponent、Suspense的使用)

&#x1f431; 个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️ 作者简介&#xff1a;2022年度博客之星前端领域TOP 2&#xff0c;前端领域优质作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &am…

Vue3——Suspense组件

Suspense组件 官网中有提到他是属于实验性功能&#xff1a; <Suspense> 是一项实验性功能。它不一定会最终成为稳定功能&#xff0c;并且在稳定之前相关 API 也可能会发生变化。 <Suspense> 是一个内置组件&#xff0c;用来在组件树中协调对异步依赖的处理。它让我…

vue3中的Suspense

1、Suspense作用 等待异步组件时渲染一些额外内容&#xff0c;让应用有更好的用户体验 2、使用步骤 使用步骤&#xff1a; 异步引入组件 import {defineAsyncComponent} from vue const Child defineAsyncComponent(()>import(./components/Child.vue)) 使用Suspense包裹组…

react-Suspense工作原理分析

Suspense 基本应用 Suspense 目前在 react 中一般配合 lazy 使用&#xff0c;当有一些组件需要动态加载(例如各种插件)时可以利用 lazy 方法来完成。其中 lazy 接受类型为 Promise<() > {default: ReactComponet}> 的参数&#xff0c;并将其包装为 react 组件。React…

vue3新增Suspense组件

在开始介绍Vue的Suspense组件之前&#xff0c;我们有必要先了解一下React的Suspense组件&#xff0c;因为他们的功能类似。 React React 16.6 新增了 <Suspense> 组件&#xff0c;让你可以“等待”目标代码加载&#xff0c;并且可以直接指定一个加载的界面&#xff08;…

Suspense组件

先上官网&#xff1a;https://cn.vuejs.org/guide/built-ins/suspense.html 注意一下 <Suspense> 是一项实验性功能。它不一定会最终成为稳定功能&#xff0c;并且在稳定之前相关 API 也可能会发生变化。 在使用了之后在浏览器控制台会有如下打印&#xff0c;至少目前是…

详解Vue3 Suspense:是什么?能干什么?如何用?

本篇文章带大家深入了解一下Vue3 Suspense&#xff0c;聊聊Suspense是什么、能干什么&#xff0c;以及如何使用它&#xff0c;希望对大家有所帮助&#xff01; Suspense 不是你想的那样。是的&#xff0c;它帮助我们处理异步组件&#xff0c;但它的作用远不止于此。&#xff0…

Vue3.0的新特性(8)Suspense

Suspense是Vue3推出的一个内置组件&#xff0c;它允许我们的程序在等待异步组件时渲染一些后备的内容&#xff0c;可以让我们创建一个平滑的用户体验&#xff1b;Vue中加载异步组件其实在Vue2.x中已经有了&#xff0c;我们用的vue-router中加载的路由组件其实也是一个异步组件&…

实现分布式锁的解决方案

目录 1. 分布式锁1.1 什么是分布式锁1.2 为什么要使用分布式锁1.3 分布式锁应具有的特性 2 分布式锁实现方案2.1 数据库实现分布式锁2.2 ZooKeeper实现分布式锁2.3 Redis实现分布式锁2.3.1 版本一2.3.2 版本二2.3.3 版本三 3. Redisson3.1 Redisson介绍3.2 Redisson分布式锁使用…

什么是分布式锁,分布式锁有什么作用?

1 、什么是分布式锁 为了防止分布式系统中的多个进程之间相互干扰&#xff0c;我们需要一种分布式协调技术来对这些进程进行调度。而这个分布式协调技术的核心就是来实现这个分布式锁。 2、为什么要使用分布式锁 成员变量 A 存在 JVM1、JVM2、JVM3 三个 JVM 内存中&#xff1b…

分布式锁以及三种加锁方式

在很多场景中&#xff0c;我们为了保证数据的最终一致性&#xff0c;需要很多的技术方案来支持&#xff0c;比如分布式事务、分布式锁等。那具体什么是分布式锁&#xff0c;分布式锁应用在哪些业务场景、如何来实现分布式锁呢&#xff1f; 一 为什么要使用分布式锁 我们在开发…

分布式架构 --- 分布式锁

分布式锁 1. 研究背景及其意义2. 分布式锁的介绍2.1 分布式锁2.2 为什么需要分布式锁2.3 分布式锁的基本要求 3. 分布式锁的实现3.1 基于数据库的分布式锁3.1.1选用数据库实现分布式锁的原因3.1.2 基于数据库实现分布式锁的缺点3.1.3分布式锁的实现 3.2 基于Redis的分布式锁3.2…

分布式锁的区别

分布式锁&#xff0c;是一种思想&#xff0c;它的实现方式有很多。比如&#xff0c;我们将沙滩当做分布式锁的组件&#xff0c;那么它看起来应该是这样的 加锁 在沙滩上踩一脚&#xff0c;留下自己的脚印&#xff0c;就对应了加锁操作。其他进程或者线程&#xff0c;看到沙滩上…

分布式锁的实现方式

背景 分布式场景中的数据一致性问题一直是一个比较重要的话题。分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;和分区容错性&#xff08;Partition tolerance&#xff09…

分布式锁-Redisson

分布式锁 1、分布式锁1.1 本地锁的局限性1.1.1 测试代码1.1.2 使用ab工具测试(单节点)1.1.3 本地锁问题演示(集群情况) 1.2 分布式锁实现的解决方案1.3 使用Redis实现分布式锁(了解即可)1.3.1 编写代码1.3.2 压测 1.4 使用Redisson解决分布式锁1.4.1 实现代码1.4.1 压测1.4.2 可…

Redis 分布式锁

文章目录 一、分布式锁概念二、使用setnx实现锁三、编写代码测试分布式锁1. 使用Java代码测试分布式锁2. 优化之设置锁的过期时间 四、优化之给lock设置UUID防误删五、使用LUA脚本保证删除的原子性 一、分布式锁概念 随着业务发展的需要&#xff0c;原单机部署的系统被演化成分…

关于分布式锁

先别说了别的&#xff0c;先来一个总结。 synchronized 单机版可以&#xff0c;但是上了分布式就不行了。 nginx 分布式服务单机锁就不行 取消单机锁&#xff0c;上redis分布式锁setnx 注意的问题&#xff1a; 如果只加了锁&#xff0c;没有释放锁&#xff0c;出现异常的话…

Redisson分布式锁详解

概述 setnx分布式锁的问题 重入问题 重入问题是指获得锁的线程可以再次进入到相同的锁的代码块中&#xff0c;可重入锁的意义在于防止死锁&#xff0c;比如HashTable这样的代码中&#xff0c;它的方法都是使用synchronized修饰的&#xff0c;假如它在一个方法内&#xff0c;…

redission实现分布式锁

在开始提到Redis分布式锁之前&#xff0c;先说一下redis中的两个命令。 SETNX key valuesetnx 是SET if Not eXists(如果不存在&#xff0c;则 SET)的简写。 用法如图&#xff0c;如果不存在set成功返回int的1&#xff0c;这个key存在了返回0。 SETEX key seconds value上面…

Java分布式锁

文章目录 1.什么是锁&#xff1f;2.什么是分布式&#xff1f;分布式场景 3.什么是分布式锁&#xff1f;4.我们应该怎么设计分布式锁&#xff1f;5.基于数据库的分布锁5.1 基于表主键唯一做分布式锁5.2 基于表字段版本号做分布式锁 6.基于 Redis 做分布式锁6.1 基于 REDIS 的 SE…