- 如何更新
npm i react@18 react-dom@18
import{createRoot} from "react-dom/client"
const root = createRoot(document.getElementById("root"))
root.render(<App..)
Automatic Batching
自动批量更新state,减少渲染次数setTimenout(()=>{ setCount(c=>c+1) setFlag(f=>!f) },1000)
- react18更新之前,连续的更改state会触发多次渲染(点击事件中的除外)比如
promise
setTimeout
natice evnent handler
- 而react18更新之后只会触发一次渲染
Automatic Batching
是默认开启的,如果你不想用可以用react-dom
提供的flushSync
方法,但是官方不建议这样做.import{flushSync} from "react-dom" setTimenout(()=>{ flushSync(()=>{ setCount(c=>c+1) }) flushSync(()=>{ setFlag(f=>!f) }) },1000) ```
- react18更新之前,连续的更改state会触发多次渲染(点击事件中的除外)比如
Concurrent Mode
应对大量渲染的情况Concurrent
并不是一种功能,而是一种机制.- React18之前渲染都是线性的,无法被终止
- React18之后所有的渲染都是可暂停的,而且可以设置优先级.这样可以给用户带来更加流畅的体验
Transtion
设置优先级- 基于
Concurrent
,通过它来标记渲染优先级 - React18优先级有高地两种,
默认都是高优先级
const [isPending,startTranstion] = useTranstion() const onchange = (e)=>{ // startTranstion标记高优先级状态 startTranstion(()=>{ setSearchQuery(e.target.value) }) } return ( <> <Input onchange={onchange}/> {isPending && 组件} </> )
- 基于
Suspense
更方便组织并行请求和loading状态-
如下代码,如果
Component1
和Component2
没有被渲染出来之前直接渲染fallback中的内容. -
Suspense
也可以嵌套使用,来体现优先级 -
原理是在组件内部如果看到一个被
throw
出来的promise
,那react
就会catch
住它,并找到最近的Suspense
,这样Suspense就知道需要等这个promise完成,接着它就渲染fallback
中的内容.在promise resolve之后,Suspense就渲染内部需要显示的组件,所以为了使用suspense数据请求的方法需要符合某种约定,这也就意味着网络请求层需要适配React suspense的这种约定.React希望更多的网络请求库能够适配这种机制,这样开发者就能更方便的使用这个功能.比如swr
就支持了suspenseimport React,{ Suspense } from "react" return (<> <Suspense fallback={<h1>loading...</h1>}> <Component1/> </Suspense> <Suspense fallback={<h1>loading...</h1>}> <Component2/> </Suspense> </>)
-