React Hooks使用startTransition与useTransition教程示例
前端兰博 人气:0引言
今天带来的是react18版本推出的全新hooks:useTransition,它的使用范围主要是用于性能优化,今天我们一探究竟吧。
需求分析
假设现在有如下需求:当用户在输入框查询数据时,需要实时根据用户输入数据进行搜索提示项的展示。与以往不同的是,提示列表的个数是十分庞大的,每次都在10000条以上。
设计过程
import {useState} from "react"; import styles from "./index.module.css"; const Home:React.FC = () => { const [val,setVal] = useState(''); const [arr,setArr] = useState<number[]>([]); //根据用户输入获取查询列表 const getList = (e:any) => { setVal(e.target.value) let arr = Array.from(new Array(10000),item=>Date.now()) setArr(arr); } return ( <div className={styles.box}> <input value={val} onChange={getList}/> { arr.map((item,key)=>( <div key={key}>{item}</div> )) } </div> ) } export default Home;
效果展示
我们快速在表单输入了abcd,但是很明显出现了卡顿现象,大约2s后表单和列表数据都被渲染。
现象分析
由于我们使用了useState对表单和列表的数据进行了更新,二者触发批量更新机制但无优先级差异。实际上为了保证用户体验感,我们需要保证输入框的输入数据永远处于最新显示,而列表的提示可以稍微滞后显示。 基于优先级渲染问题,react提出了startTransition方案。使用startTransition触发的更新优先级会被降低,从而优雅降级,提高页面刷新和渲染性能。
startTransition使用
在更新大数据更新或者大列表dom时,为了页面性能和渲染优化,我们可以对大数据或列表的更新过程采用startTransition优雅降级处理。
使用
startTransition(()=>{ //大数据列表数据获取 do... })
例子改造
import {useState,startTransition} from "react"; import styles from "./index.module.css"; const Home:React.FC = () => { const [val,setVal] = useState(''); const [arr,setArr] = useState<number[]>([]); //根据用户输入获取查询列表 const getList = (e:any) => { setVal(e.target.value) let arr = Array.from(new Array(10000),item=>Date.now()); startTransition(()=>{ setArr(arr); }) } return ( <div className={styles.box}> <input value={val} onChange={getList}/> { arr.map((item,key)=>( <div key={key}>{item}</div> )) } </div> ) } export default Home;
效果展示
相对于上面未使用startTransition,此处的输入框数据优化了许多,并且大数据列表展示卡顿达到了一定程度优化。
useTransition
useTransition和startTransition的功能一模一样,只是通过hooks的展现方式出现,并且增加了保存列表是否在渲染等待的状态。
使用
第一个变量保存是否渲染中的状态,ture表示渲染等待中
第二个变量和startTransition的使用方式一模一样
import {useState,startTransition} from "react"; const [pending,transition] = useTransition();
例子改造
import React,{useState,useTransition} from "react"; const Home:React.FC = () => { const [val,setVal] = useState(''); const [arr,setArr] = useState<number[]>([]); const [pending,transition] = useTransition() const getList = (e:any) => { setVal(e.target.value) let arr = Array.from(new Array(10000),item=>Date.now()) transition(()=>{ setArr(arr); }) } return ( <div className={styles.box}> <input value={val} onChange={getList}/> { pending?<h2>loading....</h2>:( arr.map((item,key)=>( <div key={key}>{item}</div> )) ) } </div> ) } export default Home;
效果展示
我们根据useTransition返回的pending状态添加判断,如果列表在渲染中就添加提示加载状态,否则正常显示列表。
总结
在处理大批量数据渲染时,通过使用startTransition或useTransition可以很好的提升渲染性能,提高用户体验感。
加载全部内容