前言
现在几乎所有的单页面应用框架都大同小异,也就是意味着你只要精通一个框架其他的思想基本保持了一致,现在主流的react
与vue
也是如此,二者版本迭代也在逐渐的吸取对方的优势,他们的语法也将越来越接近。
小编最早接触react得时候,es6正是流行的时候,vue框架也刚刚起步,那时候react还基本都是通过class
组件继承的形式来开发整个应用。随着不断的版本升级,react
也迎来了历史性的重大改变。接下来看一下react历史性的变化。
react16.8新增Hook
它的出现绝对堪称react的历史性突破,组件不在局限于class
继承的写法,而是以一个函数的形式,同时也提供了更为直观强大的api,props, state,context,refs 以及生命周期等。几乎能覆盖class
写法的api
如果使用的是函数式组件,也能同时帮我们省去大量的重复的代码判断,如:
React18并发
大家都知道js是单线程的编程语言,即上游不执行结束,下游就会有对应的影响,对用户来讲很有可能界面就会面临短暂性的卡死情况。假如我们执行了一次setState
,但是这个setState
是比较耗时的,这时候用户在此期间几乎是无法交互的。因此在react18
中提出了并发这个概念
react团队基于时间切片(time slicing)
与Scheduler调度
完成了此类的优化,其实就是通过Fiber结构将不紧急的更新拆分成多段更新,并通过宏任务的方式将其合理分配到浏览器的帧当中。
react18新增了几个对应的Hook API:
Suspense
新增fallback
属性
在v18中,Suspense加入了fallback属性,用于将读取数据和指定加载状态分离。这样就不用去过多的关注页面的加载状态,也能节约大量的代码。
<Suspense fallback={<div>Loading...</div>}>
<components />
</Suspense>
useTransition/useDeferredValue
由于渲染界面会占用线程,因此导致用户输入时,无法立即响应,useDeferredValue
快速变化的时候,React会合并触发的更新,渲染最后的一个更新。
常见的像防抖节流的函数,虽然利用了setTimeout
解决了频繁触发的问题,但是是无法解决更新耗时过长的问题。
在每次更新之前,useTransition
会将优先级更新为transition
,低优先级进行,再通过时间切片的形式,从而不阻塞其他紧急的渲染。
import React, { useState, useDeferredValue, useTransition } from 'react'
const Defer = () => {
const [searchValue, setSearchValue] = useState(100)
const deferredSearchValue = useDeferredValue(searchValue)
const [loading, startTransition] = useTransition(500);
return (
<>
<input
type="number"
value={searchValue}
onChange={(e) => {
startTransition(()=>{
setSearchValue(Number(e.target.value) || 0)
})
}}
/>
{loading?(
<p>loading...</p>
):(new Array(deferredSearchValue).fill(0).map((_, idx) => (
<li key={idx}>{idx}</li>
)))}
</>
)
}
export default Defer
useSyncExternalStore
相当于对并发更新使用到的额外数据进行监听,当并发更新时数据发生变化,进行强制渲染。这个通常我们的实际业务中用不到,可以自行了解。