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

當前位置:首頁 > 科技  > 軟件

喔!React19 中的 Hook 可以寫在 If 條件判斷中了。Use 實踐:點擊按鈕更新數(shù)據(jù)

來源: 責(zé)編: 時間:2024-06-06 17:41:31 181觀看
導(dǎo)讀接下來,我們將會以大量的實踐案例來展開 React 19 新 hook 的運用。本文模擬的實踐案例為點擊按鈕更新數(shù)據(jù)。這在開發(fā)中是一個非常常見的場景。案例完成之后的最終演示效果圖如下:我們直接用 React 19 新的開發(fā)方式來完

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

接下來,我們將會以大量的實踐案例來展開 React 19 新 hook 的運用。nJf28資訊網(wǎng)——每日最新資訊28at.com

本文模擬的實踐案例為點擊按鈕更新數(shù)據(jù)。這在開發(fā)中是一個非常常見的場景。nJf28資訊網(wǎng)——每日最新資訊28at.com

案例完成之后的最終演示效果圖如下:nJf28資訊網(wǎng)——每日最新資訊28at.com

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

我們直接用 React 19 新的開發(fā)方式來完成這個需求。nJf28資訊網(wǎng)——每日最新資訊28at.com

一、基礎(chǔ)實現(xiàn)

首先創(chuàng)建一個方法用于請求數(shù)據(jù)。nJf28資訊網(wǎng)——每日最新資訊28at.com

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

這里一個非常關(guān)鍵的地方就在于,當我們要更新的數(shù)據(jù)時,我們不再需要設(shè)計一個 loading 狀態(tài)去記錄數(shù)據(jù)是否正在發(fā)生請求行為,因為 Suspense 幫助我們解決了 Loading 組件的顯示問題。nJf28資訊網(wǎng)——每日最新資訊28at.com

與此同時,use() 又幫助我們解決了數(shù)據(jù)獲取的問題。那么問題就來了,這個就是,好像我們也不需要設(shè)計一個狀態(tài)去存儲數(shù)據(jù)。那么應(yīng)該怎么辦呢?nJf28資訊網(wǎng)——每日最新資訊28at.com

這里有一個非常巧妙的方式,就是把創(chuàng)建的 promise 作為狀態(tài)值來觸發(fā)組件的重新執(zhí)行。每次點擊,我們都需要創(chuàng)建新的 promisenJf28資訊網(wǎng)——每日最新資訊28at.com

代碼如下:nJf28資訊網(wǎng)——每日最新資訊28at.com

// 記住這個初始值const [api, setApi] = useState(null)

這個時候,當我們點擊事件執(zhí)行時,則只需要執(zhí)行如下代碼去觸發(fā)組件的更新。nJf28資訊網(wǎng)——每日最新資訊28at.com

function __clickToGetMessage() {  // 每次點擊,都會創(chuàng)建新的 promise  setApi(getApi())}

getApi() 執(zhí)行,新的請求會發(fā)生。他的執(zhí)行結(jié)果,又返回了一個新的 promise。nJf28資訊網(wǎng)——每日最新資訊28at.com

因此,點擊之后會創(chuàng)建的新 promise 值,api 此時就會作為狀態(tài)更改觸發(fā)組件的更新。nJf28資訊網(wǎng)——每日最新資訊28at.com

完整代碼如下:nJf28資訊網(wǎng)——每日最新資訊28at.com

export default function Index() {  const [api, setApi] = useState(null)  function __clickToGetMessage() {    setApi(getApi())  }  return (    <div>      <div id='tips'>點擊按鈕獲取一條新的數(shù)據(jù)</div>      <button onClick={__clickToGetMessage}>獲取數(shù)據(jù)</button>      <div className="content">        <Suspense fallback={<div>loading...</div>}>          <Item api={api} />        </Suspense>      </div>    </div>  )}const Item = (props) => {  if (!props.api) {    return <div>nothing</div>  }  const joke = use(props.api)  return (    <div className='a_value'>{joke.value}</div>  )}

案例寫完之后。我們基本上就能夠?qū)崿F(xiàn)最開始截圖中的交互效果了。但是現(xiàn)別急,還沒有完。我們還需要進一步分析一下這個案例。nJf28資訊網(wǎng)——每日最新資訊28at.com

二、案例分析

這里我們需要注意觀察兩個事情。nJf28資訊網(wǎng)——每日最新資訊28at.com

一個是觀察當前組件更新,更上層的父組件是否發(fā)生了變化。我們可以在 App 組件中執(zhí)行一次打印。nJf28資訊網(wǎng)——每日最新資訊28at.com

此時可以發(fā)現(xiàn),當我們重新請求時,當前組件更新,但是上層組件并不會重新執(zhí)行。nJf28資訊網(wǎng)——每日最新資訊28at.com

我們可以出得結(jié)論:更簡潔的狀態(tài)設(shè)計,有利于命中 React 默認的性能優(yōu)化規(guī)則。nJf28資訊網(wǎng)——每日最新資訊28at.com

具體的規(guī)則請在 React 知命境合集中查看。nJf28資訊網(wǎng)——每日最新資訊28at.com

更簡潔的狀態(tài)設(shè)計,也是 React 19 所倡導(dǎo)的開發(fā)思路。nJf28資訊網(wǎng)——每日最新資訊28at.com

另外一個事情,是我們要特別特別注意觀察子組件 Item 的實現(xiàn)。nJf28資訊網(wǎng)——每日最新資訊28at.com

首先因為我們初始化時,給 api 賦予的默認值是 null。nJf28資訊網(wǎng)——每日最新資訊28at.com

// 記住這個初始值const [api, setApi] = useState(null)

之后,我們就將 api 傳給了子組件 Item。nJf28資訊網(wǎng)——每日最新資訊28at.com

<Item api={api} />

然后在 Item 組件的內(nèi)部實現(xiàn)中,因為我們直接把 api 傳給了 use,那么此時直接執(zhí)行肯定會報錯。nJf28資訊網(wǎng)——每日最新資訊28at.com

const joke = use(props.api)

要注意的是,我們剛才說,使用 Suspense 會捕獲子組件的異常,但是不是捕獲所有異常,它只能識別 promise 的異常。因此,這里的報錯會直接影響到整個頁面。nJf28資訊網(wǎng)——每日最新資訊28at.com

所以,為了處理好初始化時傳入 api 值為 null,我在內(nèi)部實現(xiàn)代碼邏輯中,使用了 if 判斷該條件,然后執(zhí)行了一次 return。我試圖讓 use(null) 得不到執(zhí)行的時機。nJf28資訊網(wǎng)——每日最新資訊28at.com

const Item = (props) => {  if (!props.api) {    console.log('初始化時,api == null')    return <div>nothing</div>  }  const joke = use(props.api)  return (    <div className='a_value'>{joke.value}</div>  )}

那么,我的意圖是否能成功呢?nJf28資訊網(wǎng)——每日最新資訊28at.com

我們在 return 后面插入一個 console.log 來觀察代碼的執(zhí)行情況,代碼如下:nJf28資訊網(wǎng)——每日最新資訊28at.com

const Item = (props) => {  if (!props.api) {    console.log('初始化時,api == null')    return <div>nothing</div>  }    console.log('初始化時這里是否執(zhí)行');  const joke = use(props.api)  return (    <div className='a_value'>{joke.value}</div>  )}

演示效果如下圖所示:nJf28資訊網(wǎng)——每日最新資訊28at.com

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

我們發(fā)現(xiàn),當我反復(fù)刷新頁面,讓初始化流程執(zhí)行時,return 后面的代碼并不會執(zhí)行。nJf28資訊網(wǎng)——每日最新資訊28at.com

再然后,我們新增一點內(nèi)容,比如在 return 后面使用一個 useEffect。nJf28資訊網(wǎng)——每日最新資訊28at.com

const Item = (props) => {  if (!props.api) {    console.log('初始化時,api == null')    return <div>nothing</div>  }  useEffect(() => {    console.log('xxx')  }, [])  console.log('初始化時這里是否執(zhí)行')  const joke = use(props.api)  return (    <div className='a_value'>{joke.value}</div>  )}

然后演示再看看。我們發(fā)現(xiàn) effect 也不會執(zhí)行。然后我們還可以搞點好玩的。nJf28資訊網(wǎng)——每日最新資訊28at.com

Item 代碼改造如下:nJf28資訊網(wǎng)——每日最新資訊28at.com

const Item = (props) => {  if (!props.api) {    const [count, setCount] = useState(0)    console.log('初始化時,api == null')    return <div onClick={() => setCount(count + 1)}>nothing, {count}</div>  }  console.log('初始化時這里是否執(zhí)行')  const joke = use(props.api)  return (    <div className='a_value'>{joke.value}</div>  )}

注意看,我們在 if 條件判斷中,單獨創(chuàng)建了一個 useState,并在對應(yīng)的元素上添加了一個讓 count 遞增的交互。nJf28資訊網(wǎng)——每日最新資訊28at.com

這段在之前版本的開發(fā)中一定會觸發(fā)語法錯誤提示的代碼。nJf28資訊網(wǎng)——每日最新資訊28at.com

最終也是能勉強運行,但是代碼會瘋狂報錯。nJf28資訊網(wǎng)——每日最新資訊28at.com

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

然后,我繼續(xù)一個騷操作,我在 if 中條件判斷中,使用 useEffect,代碼如下:nJf28資訊網(wǎng)——每日最新資訊28at.com

const Item = (props) => {  if (!props.api) {    useEffect(() => {      console.log('useEffect 在 if 中執(zhí)行')    }, [])    return <div>nothing</div>  }  console.log('初始化時這里是否執(zhí)行')  const joke = use(props.api)  return (    <div className='a_value'>{joke.value}</div>  )}

也能正常執(zhí)行。觀察一下演示效果:nJf28資訊網(wǎng)——每日最新資訊28at.com

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

結(jié)論:nJf28資訊網(wǎng)——每日最新資訊28at.com

很明顯,react 19 的 hook 在底層發(fā)生了一些優(yōu)化更新,我們可以不用非得把所有的 hook 都放在函數(shù)組件的最前面去執(zhí)行了。nJf28資訊網(wǎng)——每日最新資訊28at.com

在 React 19 中,我們可以把 hook 放到 return 之后,也可以放到條件判斷中去執(zhí)行。nJf28資訊網(wǎng)——每日最新資訊28at.com

但是,我們一定要注意的是,并非表示我們可以隨便亂寫。當條件互斥時,狀態(tài)之間如果存在不合理的耦合關(guān)系,依然不能正常執(zhí)行。我們列舉兩個案例來觀察這個事情。nJf28資訊網(wǎng)——每日最新資訊28at.com

第一個案例,我們依然在 if 中執(zhí)行一個 useEffect,但是不同的是,我把在 if 之外的狀態(tài) counter 作為依賴項傳入。nJf28資訊網(wǎng)——每日最新資訊28at.com

代碼如下。nJf28資訊網(wǎng)——每日最新資訊28at.com

const Item = (props) => {  const [counter, setCounter] = useState(0)  if (!props.api) {    useEffect(() => {      console.log('useEffect 在 if 中執(zhí)行')    }, [counter])    return <div>nothing</div>  }  console.log('初始化時這里是否執(zhí)行')  const joke = use(props.api)  return (    <div className='a_value' onClick={() => setCounter(counter + 1)}>{joke.value}</div>  )}

此時一個很明顯的問題就是,if 內(nèi)部在 UI 邏輯上本和外部是互斥的關(guān)系,但是我們在狀態(tài)邏輯上卻相互關(guān)聯(lián)。因此這個之后,代碼執(zhí)行就會報錯,明確的告訴你這種寫法不合理。nJf28資訊網(wǎng)——每日最新資訊28at.com

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

非常的方便省事。nJf28資訊網(wǎng)——每日最新資訊28at.com

當然這樣寫會造成冗余的接口請求執(zhí)行。因此我們可以稍作調(diào)整就可以了。nJf28資訊網(wǎng)——每日最新資訊28at.com

這里需要根據(jù)需求調(diào)整,案例只做演示。nJf28資訊網(wǎng)——每日最新資訊28at.com

const _initApi = getApi()function Index() {  const [api, setApi] = useState(_initApi)  ...}

OK,今天的案例就介紹到這里,后續(xù)的章節(jié)我們還會繼續(xù)更多的實戰(zhàn)案例的分析。nJf28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-92464-0.html喔!React19 中的 Hook 可以寫在 If 條件判斷中了。Use 實踐:點擊按鈕更新數(shù)據(jù)

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

上一篇: 解密Tenacity:Python中最強大的重試庫

下一篇: 關(guān)于 Python 數(shù)據(jù)分析的 15 個 NumPy 應(yīng)用

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 宽城| 麻栗坡县| 台江县| 如东县| 达日县| 彭山县| 开阳县| 寻甸| 博爱县| 米泉市| 靖州| 西乡县| 凉城县| 重庆市| 绥滨县| 桂阳县| 乌海市| 壶关县| 鄱阳县| 南溪县| 措勤县| 兴义市| 安顺市| 屏山县| 恩施市| 邵武市| 常熟市| 柳河县| 文化| 禄丰县| 保康县| 东乌珠穆沁旗| 平邑县| 定兴县| 景洪市| 芜湖市| 南木林县| 寻乌县| 古蔺县| 黄浦区| 会同县|