日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

震驚!用 Suspense 解決請(qǐng)求依賴的復(fù)雜場景居然這么簡單!

來源: 責(zé)編: 時(shí)間:2024-06-11 17:52:06 212觀看
導(dǎo)讀有一種復(fù)雜場景 React 新手經(jīng)常處理不好。那就是一個(gè)頁面有多個(gè)模塊,每個(gè)模塊都有自己的數(shù)據(jù)需要請(qǐng)求。與此同時(shí),可能部分模塊的數(shù)據(jù)還要依賴父級(jí)的異步數(shù)據(jù)才能正常請(qǐng)求自己的數(shù)據(jù)。如下圖所示,當(dāng)我們直接訪問該頁面時(shí),

有一種復(fù)雜場景 React 新手經(jīng)常處理不好。9Wy28資訊網(wǎng)——每日最新資訊28at.com

那就是一個(gè)頁面有多個(gè)模塊,每個(gè)模塊都有自己的數(shù)據(jù)需要請(qǐng)求。與此同時(shí),可能部分模塊的數(shù)據(jù)還要依賴父級(jí)的異步數(shù)據(jù)才能正常請(qǐng)求自己的數(shù)據(jù)。如下圖所示,當(dāng)我們直接訪問該頁面時(shí),頁面請(qǐng)求的數(shù)據(jù)就非常多。而且這些數(shù)據(jù)還有一定的先后依賴關(guān)系。9Wy28資訊網(wǎng)——每日最新資訊28at.com

9Wy28資訊網(wǎng)——每日最新資訊28at.com

一、重新考慮初始化

和之前的方案一樣,我們先定義父組件的請(qǐng)求接口。9Wy28資訊網(wǎng)——每日最新資訊28at.com

const getMessage = async () => {  const res = await fetch('https://api.chucknorris.io/jokes/random')  return res.json()}

然后在父組件中,將 getMessage() 執(zhí)行之后返回的 promise 作為狀態(tài)存儲(chǔ)在 useState 中。這樣,當(dāng)我點(diǎn)擊時(shí),只需要重新執(zhí)行依次 getMessage() 就可以更新整個(gè)組件。9Wy28資訊網(wǎng)——每日最新資訊28at.com

const [  messagePromise,   setMessagePromise] = useState(null)

但是此時(shí)我們發(fā)現(xiàn),messagePromise 并沒有初始值,因此初始化時(shí),接口并不會(huì)請(qǐng)求。這種情況下,有兩種交互我們需要探討。一種是通過點(diǎn)擊按鈕來初始化接口。另外一種就是組件首次渲染就要初始化接口。9Wy28資訊網(wǎng)——每日最新資訊28at.com

我們之前的案例中,使用了取巧的方式,在函數(shù)組件之外提前獲取了數(shù)據(jù),這會(huì)導(dǎo)致訪問任何頁面該數(shù)據(jù)都會(huì)加載,因此并非合適的手段。9Wy28資訊網(wǎng)——每日最新資訊28at.com

// 我們之前的案例這樣做是一種取巧的方式const api = getMessage()function Message() {  ...

但是如果我們直接把 getMessage() 放在組件內(nèi)部執(zhí)行,也存在不小的問題。因?yàn)楫?dāng)組件因?yàn)槠渌臓顟B(tài)發(fā)生變化需要重新執(zhí)行時(shí),此時(shí) getMessage() 也會(huì)冗余的多次執(zhí)行。9Wy28資訊網(wǎng)——每日最新資訊28at.com

// 此時(shí)會(huì)冗余多次執(zhí)行const [  messagePromise,   setMessagePromise] = useState(getMessage())

理想的情況是 getMessage() 只在組件首次渲染時(shí)執(zhí)行依次,后續(xù)狀態(tài)的改變就不在執(zhí)行。而不需要多次執(zhí)行。9Wy28資訊網(wǎng)——每日最新資訊28at.com

我們先來考慮通過點(diǎn)擊事件初始化接口的交互。此時(shí)我們可以先設(shè)置 messagePrmoise 的初始值為 null。9Wy28資訊網(wǎng)——每日最新資訊28at.com

const [  messagePromise,   setMessagePromise] = useState(null)

不過這樣做有一個(gè)小問題就是如果我將 messagePromise 值為 null 時(shí)傳遞給了子組件。那么子組件就會(huì)報(bào)錯(cuò),因此我們需要特殊處理。一種方式就是在子組件內(nèi)部判斷。9Wy28資訊網(wǎng)——每日最新資訊28at.com

const MessageOutput = ({messagePromise}) => {  if (!messagePromise) return  const messageContent = use(messagePromise)

或者:9Wy28資訊網(wǎng)——每日最新資訊28at.com

// 這種寫法是在需要默認(rèn)顯示狀態(tài)時(shí)的方案const MessageOutput = ({messagePromise}) => {  const messageContent = messagePromise ? use(messagePromise) : {value: '默認(rèn)值'}

另外一種思路就是設(shè)置一個(gè)狀態(tài),子組件基于該狀態(tài)的值來是否顯示。然后在點(diǎn)擊時(shí)將其設(shè)置為 true。9Wy28資訊網(wǎng)——每日最新資訊28at.com

const [show, setShow] = useState(false)function __clickHandler() {  setMessagePromise(getMessage())  setShow(true)}
{show && <MessageContainer messagePromise={messagePromise} />}

另外一種交互思路就是初始化時(shí)就需要馬上請(qǐng)求數(shù)據(jù)。此時(shí)我們?yōu)榱舜_保 getMessage() 只執(zhí)行一次,可以新增一個(gè)非 state 狀態(tài)來記錄組件的初始化情況。默認(rèn)值為 false,初始化之后設(shè)置為 true。9Wy28資訊網(wǎng)——每日最新資訊28at.com

const i = useRef(false)let __api = i.current ? null : getMessage()const [  messagePromise,   setMessagePromise] = useState(null)

然后在 useEffect 中,將其設(shè)置為 true,表示組件已經(jīng)初始化過了。9Wy28資訊網(wǎng)——每日最新資訊28at.com

useEffect(() => {  i.current = true}, [])

這是利用 useState 的內(nèi)部機(jī)制,初始化值只會(huì)賦值一次來做到的。從而我們可以放心更改后續(xù) __api 的值為 null.9Wy28資訊網(wǎng)——每日最新資訊28at.com

從這個(gè)細(xì)節(jié)的角度來說,函數(shù)組件多次執(zhí)行的確會(huì)給開發(fā)帶來一些困擾,Vue3/Solid 只執(zhí)行一次的機(jī)制會(huì)更舒適一些,不過處理得當(dāng)也能避免這個(gè)問題。9Wy28資訊網(wǎng)——每日最新資訊28at.com

二、Suspense 嵌套

接下來,我們需要考慮的就是 Suspense 嵌套執(zhí)行的問題就行了。這個(gè)執(zhí)行起來非常簡單。我們只需要將有異步請(qǐng)求的模塊用 Suspense 包裹起來當(dāng)成一個(gè)子組件。然后該子組件可以當(dāng)成一個(gè)常規(guī)的子組件作為 Suspense 組件的子組件。9Wy28資訊網(wǎng)——每日最新資訊28at.com

例如,我們聲明一個(gè)子組件如下所示:9Wy28資訊網(wǎng)——每日最新資訊28at.com

const getApi = async () => {  const res = await fetch('https://api.chucknorris.io/jokes/random')  return res.json()}export default function Index(props) {  const api = getApi()  return (    <div>      <div id='tips'>多個(gè) Suspense 嵌套,子組件第一部分</div>      <div className="content">        <div className='_05_dou1_message'>父級(jí)消息: {props.value}</div>        <Suspense fallback={<div>Loading...</div>}>          <Item api={api} />        </Suspense>      </div>    </div>  )}const Item = ({api}) => {  const joke = api ? use(api) : {value: 'nothing'}  return (    <div className='_03_a_value_update'>子級(jí)消息:{joke.value}</div>  )}

然后我可以將這個(gè)子組件放在 Suspense 內(nèi)就可以了。9Wy28資訊網(wǎng)——每日最新資訊28at.com

import DouPlus1 from './Dou1'import DouPlus2 from './Dou2'
const MessageOutput = ({messagePromise}) => {  const messageContent = use(messagePromise)  return (    <div>      <p>{messageContent.value}</p>      <DouPlus1 value={messageContent.value} />      <DouPlus2 value={messageContent.value} />    </div>  )}

在另外一個(gè)子組件中,我們還設(shè)計(jì)了內(nèi)部狀態(tài),用于實(shí)現(xiàn)切換按鈕,來增加頁面交互的復(fù)雜度。并且每次切換都會(huì)請(qǐng)求接口。9Wy28資訊網(wǎng)——每日最新資訊28at.com

9Wy28資訊網(wǎng)——每日最新資訊28at.com

如果切換時(shí),上一個(gè)接口沒有請(qǐng)求完成,React 會(huì)自己處理好數(shù)據(jù)的先后問題。不需要我們額外考慮競態(tài)條件的情況。完整代碼如下:9Wy28資訊網(wǎng)——每日最新資訊28at.com

var tabs = ['首頁', '視頻', '探索']export default function Index() {  var r = useRef(false)  var api = r.current ? null : getApi()  const [promise, setPromise] = useState(api)  const [current, setCurrent] = useState(0)  useEffect(() => {    r.current = true  }, [])  return (    <div>      <div id='tips'>多個(gè) Suspense 嵌套,子組件第二部分</div>      <div className="content">        {tabs.map((item, index) => (          <button             id='btn_05_item'             className={current == index ? 'active' : ''}            onClick={() => {              setCurrent(index)              setPromise(getApi())            }}            key={item}          >{item}</button>        ))}                <Suspense fallback={<div className='_05_a_value_item'>Loading...</div>}>          <Item api={promise} />        </Suspense>      </div>    </div>  )}const Item = ({api}) => {  const joke = use(api)  return (    <div className='_05_a_value_item'>{joke.value}</div>  )}

三、總結(jié)

當(dāng)我們要在復(fù)雜交互的情況下使用嵌套 Suspense 來解決問題,如果我們組件劃分得當(dāng)、與數(shù)據(jù)依賴關(guān)系處理得當(dāng),那么代碼就會(huì)相當(dāng)簡單。不過這對(duì)于開發(fā)者來說,會(huì)有另外一個(gè)層面的要求。那就是如何合理的處理好組件歸屬問題。9Wy28資訊網(wǎng)——每日最新資訊28at.com

許多前端頁面開發(fā)難度往往都是由于組件劃分不合理,屬性歸屬問題處理不夠到位導(dǎo)致的。因此 Suspense 在這個(gè)層面有了一個(gè)剛需,開發(fā)者必須要具備合理劃分組件的能力,否則即使使用了 Suspense,也依然可能導(dǎo)致頁面一團(tuán)混亂。9Wy28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-93090-0.html震驚!用 Suspense 解決請(qǐng)求依賴的復(fù)雜場景居然這么簡單!

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: C++ 首度超越 C 語言僅次榜首 Python,TIOBE 編程指數(shù)六月排行榜公布

下一篇: PHP 服務(wù)實(shí)現(xiàn)性能剖析、跟蹤和可觀察性14444444444444】=102102102102102102102102102102102102102102102102實(shí)踐

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 一加Ace2 Pro真機(jī)揭曉 鈦空灰配色質(zhì)感拉滿

    終于,在經(jīng)過了幾波預(yù)熱之后,一加Ace2 Pro的外觀真機(jī)圖在網(wǎng)上出現(xiàn)了。還是博主數(shù)碼閑聊站曝光的,這次的外觀設(shè)計(jì)還是延續(xù)了一加11的方案,只是細(xì)節(jié)上有了調(diào)整,例如新加入了鈦空灰
  • 共享單車的故事講到哪了?

    來源丨海克財(cái)經(jīng)與共享充電寶相差不多,共享單車已很久沒有被國內(nèi)熱點(diǎn)新聞關(guān)照到了。除了一再漲價(jià)和用戶直呼用不起了。近日多家媒體再發(fā)報(bào)道稱,成都、天津、鄭州等地多個(gè)共享單
  • 騰訊蓋樓,字節(jié)拆墻

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之&ldquo;想重溫暴刷深淵、30+技能搭配暴搓到爽的游戲體驗(yàn)嗎?一起上晶核,即刻暴打!&rdquo;曾憑借直播騰訊旗下代理格斗游戲《DNF》一
  • AMD的AI芯片轉(zhuǎn)單給三星可能性不大 與臺(tái)積電已合作至2nm制程

    據(jù) DIGITIMES 消息,英偉達(dá) AI GPU 出貨逐季飆升,接下來 AMD MI 300 系列將在第 4 季底量產(chǎn)。而半導(dǎo)體業(yè)內(nèi)人士表示,近日傳出 AMD 的 AI 芯片將轉(zhuǎn)單給
  • iQOO Neo8 Pro真機(jī)諜照曝光:天璣9200+和V1+旗艦雙芯加持

    去年10月,iQOO推出了iQOO Neo7系列機(jī)型,不僅搭載了天璣9000+,而且是同價(jià)位唯一一款天璣9000+直屏旗艦,一經(jīng)上市便受到了用戶的廣泛關(guān)注。在時(shí)隔半年后,
  • 回歸OPPO兩年,一加贏了銷量,輸了品牌

    成為OPPO旗下主打性能的先鋒品牌后,一加屢創(chuàng)佳績。今年618期間,一加手機(jī)全渠道銷量同比增長362%,憑借一加 11、一加 Ace 2、一加 Ace 2V三款爆品,一加
  • OPPO K11搭載長壽版100W超級(jí)閃充:26分鐘充滿100%

    據(jù)此前官方宣布,OPPO將于7月25日也就是今天下午14:30舉辦新品發(fā)布會(huì),屆時(shí)全新的OPPO K11將正式與大家見面,將主打旗艦影像,和同檔位競品相比,其最大的賣
  • 英特爾Xe-HP項(xiàng)目終止,將專注Xe-HPC/HPG系列顯卡

    據(jù)10 月 31 日消息報(bào)道,英特爾高級(jí)副總裁兼加速計(jì)算系統(tǒng)和圖形事業(yè)部總經(jīng)理 表示,Xe-HP“ Arctic Sound” 系列服務(wù)器 GPU 已經(jīng)應(yīng)用于 oneAPI devcloud 云服
  • SN570 NVMe SSD固態(tài)硬盤 價(jià)格與性能兼具

    SN570 NVMe SSD固態(tài)硬盤是西部數(shù)據(jù)發(fā)布的最新一代WD Blue系列的固態(tài)硬盤,不僅閃存技術(shù)更為精進(jìn),性能也得到了進(jìn)一步的躍升。WD Blue SN570 NVMe SSD的包裝外
Top 主站蜘蛛池模板: 隆德县| 翁源县| 托里县| 百色市| 武清区| 大安市| 金湖县| 望江县| 建昌县| 秦皇岛市| 江阴市| 潞城市| 依兰县| 聂荣县| 拜泉县| 普宁市| 五家渠市| 文水县| 焦作市| 正安县| 微山县| 平泉县| 同江市| 阜平县| 进贤县| 高安市| 涟源市| 思南县| 常宁市| 垦利县| 枣庄市| 宁安市| 白河县| 石泉县| 辉县市| 武安市| 温宿县| 正阳县| 佳木斯市| 美姑县| 临海市|