React18中的useDeferredValue示例詳解

接著上一篇React18的簡介和自動批處理的特性,今天我們來聊下useDeferredValue。
有什么用?
lets you defer updating the less important parts of the screen
我們翻譯下,允許用戶推遲屏幕更新優(yōu)先級不高部分。
說“人話”就是,如果說某些渲染比較消耗性能,比如存在實時計算和反饋,我們可以使用這個Hook降低其計算的優(yōu)先級,使得避免整個應用變得卡頓。
較多的場景可能就在于用戶反饋輸入上。比如百度的輸入框,用戶可能輸入的很快,相信大家還有個體會,就是我們使用輸入法的時候,中間還在選打哪個字呢,拼音或者輸入片段就已經(jīng)被搜索了。

這里就存在問題了,用戶連續(xù)輸入的時候,不停地在進行計算或者調(diào)用后端服務,其實中間態(tài)的很多輸入片段的信息是無用的,既浪費了服務資源,也因為React應用實時更新和JS的單線程特性導致其他渲染任務卡頓。那我們使用useDeferredValue來使用下,如何避免這個問題。
實操起來
還是沿用上期的代碼項目
import React, {useState, useEffect} from 'react';
const List = (props) => {
const [list, setList] = useState([]);
const [count, setCount] = useState(0);
useEffect(() => {
setCount(count => count + 1);
setTimeout(() => {
setList([
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
]);
}, 500);
}, [props.text]);
return [<p>{'我被觸發(fā)了' + count + '次'}</p>
, <ul>{list.map(item => <li>Hello:{item.name} value:{item.value}</li>)}</ul>]
};
export default function App() {
const [text, setText] = useState("喵爸");
const handleChange = (e) => {
setText(e.target.value);
};
return (
<div className="App">
<input value={text} onChange={handleChange}/>
<List text={text}/>
</div>
);
};一般我們的代碼是這樣寫的。輸入框的值變化的時候,我們使用setTimeout來模擬下向后端請求數(shù)據(jù),或者大量計算的耗時操作。這個時候只要輸入框的內(nèi)容發(fā)生變化就會觸發(fā)useEffect,我們用count來進行計數(shù)。
\
我們每次的輸入或者變化,都會觸發(fā)一次更新,那我們接下來改造下。

我們僅需要修改外部組件,使得傳入List的Text變量是一個延遲更新的值。

細心的同學可以發(fā)現(xiàn)了,咦?!好像沒什么區(qū)別呀。其實原因在于,首先timeoutMs這個參數(shù)的含義是延遲的值允許延遲多久,事實上網(wǎng)絡和設備允許的情況下,React會嘗試使用更低的延遲。這一點是不是非常nice呀。
跟防抖的區(qū)別
估計有很多同學在一開始看到筆者這個場景的時候會去想,這就是防抖嗎?一開始故意賣了個關子,沒有提防抖的概念。這里跟防抖還是有比較大的區(qū)別的,那么不論機器快慢,網(wǎng)絡情況如何,始終會在用戶停止輸入后的固定之間才執(zhí)行。筆者直接放出兩者的比較,為了簡單起見,我們使用下ahooks的useDebounce,大家可以對比理解下。
import React, {useState, useEffect, useDeferredValue} from 'react';
import {useDebounce} from 'ahooks';
const List = (props) => {
const [list, setList] = useState([]);
const [count, setCount] = useState(0);
useEffect(() => {
setCount(count => count + 1);
setTimeout(() => {
setList([
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
{name: props.text, value: Math.random()},
]);
}, 500);
}, [props.text]);
return [<p>{'我被觸發(fā)了' + count + '次'}</p>,
<ul>{list.map(item => <li>Hello:{item.name} value:{item.value}</li>)}</ul>]
};
export default function App() {
const [text, setText] = useState("喵爸");
const deferredText = useDeferredValue(text, {timeoutMs: 1000});
const debouncedValue = useDebounce(text, { wait: 1000 });
const handleChange = (e) => {
setText(e.target.value);
};
return (
<div className="App">
<input value={text} onChange={handleChange}/>
<List text={deferredText}/>
<List text={debouncedValue}/>
</div>
);
};
到此這篇關于React18中的useDeferredValue的文章就介紹到這了,更多相關React18 useDeferredValue內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
react+axios實現(xiàn)github搜索用戶功能(示例代碼)
這篇文章主要介紹了react+axios實現(xiàn)搜索github用戶功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09
jsoneditor二次封裝實時預覽json編輯器組件react版
這篇文章主要為大家介紹了jsoneditor二次封裝實時預覽json編輯器組件react版示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
解決React報錯Rendered more hooks than during
這篇文章主要為大家介紹了React報錯Rendered more hooks than during the previous render解決方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12

