<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          React新文檔:不要濫用effect哦

          共 2689字,需瀏覽 6分鐘

           ·

          2022-06-13 19:31

          作者:卡頌

          介:《React技術(shù)揭秘》作者

          來源:SegmentFault  思否社區(qū) 


          大家好,我卡頌。


          你或你的同事在使用useEffect時有沒有發(fā)生過以下場景:


          當你希望狀態(tài)a變化后發(fā)起請求,于是你使用了useEffect


          useEffect(() => {  fetch(xxx);
          }, [a])

          這段代碼運行符合預期,上線后也沒問題。


          隨著需求不斷迭代,其他地方也會修改狀態(tài)a。但是在那個需求中,并不需要狀態(tài)a改變后發(fā)起請求。


          你不想動之前的代碼,又得修復這個bug,于是你增加了判斷條件:


          useEffect(() => {  if (xxxx) {    fetch(xxx);
            }
          }, [a])

          某一天,需求又變化了!現(xiàn)在請求還需要b字段。


          這很簡單,你順手就將b作為useEffect的依賴加了進去:


          useEffect(() => {  if (xxxx) {    fetch(xxx);
            }
          }, [a, b])


          隨著時間推移,你逐漸發(fā)現(xiàn):


          • 是否發(fā)送請求與if條件相關(guān)
          • 是否發(fā)送請求還與a、b等依賴項相關(guān)
          • a、b等依賴項又與很多需求相關(guān)

          根本分不清到底什么時候會發(fā)送請求,真是頭大...

          如果以上場景似曾相識,那么React新文檔里已經(jīng)明確提供了解決辦法。

          一些理論知識



          新文檔中這一節(jié)名為Synchronizing with Effects,當前還處于草稿狀態(tài)。
          但是其中提到的一些概念,所有React開發(fā)者都應該清楚。

          首先,effect這一節(jié)隸屬于Escape Hatches(逃生艙)這一章。


          從命名就能看出,開發(fā)者并不一定需要使用effect,這僅僅是特殊情況下的逃生艙。

          React中有兩個重要的概念:

          • Rendering code(渲染代碼)
          • Event handlers(事件處理器)

          Rendering code開發(fā)者編寫的組件渲染邏輯,最終會返回一段JSX。

          比如,如下組件內(nèi)部就是Rendering code

          function App() {  const [name, update] = useState('KaSong');  
            return <div>Hello {name}</div>;
          }

          Rendering code的特點是:他應該是不帶副作用的純函數(shù)。

          如下Rendering code包含副作用(count變化),就是不推薦的寫法:

          let count = 0;function App() {
            count++;  const [name, update] = useState('KaSong');  
            return <div>Hello {name}</div>;
          }


          處理副作用


          Event handlers組件內(nèi)部包含的函數(shù),用于執(zhí)行用戶操作,可以包含副作用。

          下面這些操作都屬于Event handlers

          • 更新input輸入框
          • 提交表單
          • 導航到其他頁面

          如下例子中組件內(nèi)部的changeName方法就屬于Event handlers

          function App() {  const [name, update] = useState('KaSong');  
            const changeName = () => {    update('KaKaSong');
            }  
            return <div onClick={changeName}>Hello {name}</div>;
          }

          但是,并不是所有副作用都能在Event handlers中解決。

          比如,在一個聊天室中,發(fā)送消息是用戶觸發(fā)的,應該交給Event handlers處理。

          除此之外,聊天室需要隨時保持和服務(wù)端的長連接,保持長連接的行為屬于副作用,但并不是用戶行為觸發(fā)的。

          對于這種:在視圖渲染后觸發(fā)的副作用,就屬于effect,應該交給useEffect處理。

          回到開篇的例子:

          當你希望狀態(tài)a變化后發(fā)起請求,首先應該明確,你的需求是:

          狀態(tài)a變化,接下來需要發(fā)起請求

          還是

          某個用戶行為需要發(fā)起請求,請求依賴狀態(tài)a作為參數(shù)?

          如果是后者,這是用戶行為觸發(fā)的副作用,那么相關(guān)邏輯應該放在Event handlers中。

          假設(shè)之前的代碼邏輯是:

          1. 點擊按鈕,觸發(fā)狀態(tài)a變化
          2. useEffect執(zhí)行,發(fā)送請求

          應該修改為:

          1. 點擊按鈕,在事件回調(diào)中獲取狀態(tài)a的值
          2. 在事件回調(diào)中發(fā)送請求

          經(jīng)過這樣修改,狀態(tài)a變化與發(fā)送請求之間不再有因果關(guān)系,后續(xù)對狀態(tài)a的修改不會再有無意間觸發(fā)請求的顧慮

          總結(jié)



          當我們編寫組件時,應該盡量將組件編寫為純函數(shù)。

          對于組件中的副作用,首先應該明確:

          是用戶行為觸發(fā)的還是視圖渲染后主動觸發(fā)的?

          對于前者,將邏輯放在Event handlers中處理。

          對于后者,使用useEffect處理。

          這也是為什么useEffect所在章節(jié)在新文檔中叫做Escape Hatches —— 大部分情況下,你不會用到useEffect,這只是其他情況都不適應時的逃生艙。



          點擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動和交流,掃描下方”二維碼“或在“公眾號后臺回復“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~

          - END -


          瀏覽 19
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青娱乐性爱视频 | www,色婷婷 | 成人无码区免费AV毛片 | 加勒比无码在线视频 | 婷婷五月天激情丁香 |