日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:52010
  • 待審:67
  • 小程序:12
  • 文章:1106242
  • 會員:784

在這篇文章中,我將展示如何在 usestate hook react 應用程序中創建閉包。

我不會解釋什么是閉包,因為關于這個主題的資源有很多,我不想重復。我建議閱讀@imranabdulmalik的這篇文章。

簡而言之,一個closure是(來自mozilla):

…捆綁在一起(封閉)的函數及其周圍狀態(詞法環境)的引用的組合。換句話說,閉包使您可以從內部函數訪問外部函數的作用域。在 javascript 中,每次創建函數時都會創建閉包,在函數創建時.

以防萬一你不熟悉這個詞詞匯環境,你可以閱讀@soumyadey的這篇文章或者這篇文章。

問題

在 react 應用程序中,您可能會意外創建屬于使用 usestate 鉤子創建的組件狀態的變量的閉包。發生這種情況時,您將面臨staleclosure問題,也就是說,當您引用狀態的舊值時,它同時發生了變化,因此它不再相關。

poc

我創建了一個 demo react 應用程序,其主要目標是增加一個計數器(屬于狀態),該計數器可以在 settimeout 方法的回調中的閉包中關閉。

總之,這個應用程序可以:

顯示計數器的值

計數器加1
啟動計時器,在五秒后將計數器加1。
計數器加10

下圖中,顯示了應用程序的初始ui狀態,計數器為零。

我們將分三步模擬柜臺關閉

    計數器加1

    啟動計時器,五秒后加1

超時觸發前增加10

5秒后,計數器的值為2.

計數器的期望值應該是12,但是我們得到2。

發生這種情況的原因是因為我們在傳遞給settimeout的回調中創建了關閉計數器,并且當觸發超時時我們設置計數器從其舊值(即 1)開始。

settimeout(() => {
        setlogs((l) => [...l, `you closed counter with value: ${counter}\n and now i'll increment by one. check the state`])
        settimeoutinprogress(false)
        setstarttimeout(false)
        setcounter(counter + 1)
        setlogs((l) => [...l, `did you create a closure of counter?`])

      }, timeoutinseconds * 1000);

登錄后復制

下面是app組件的完整代碼

function app() {
  const [counter, setcounter] = usestate(0)
  const timeoutinseconds: number = 5
  const [starttimeout, setstarttimeout] = usestate(false)
  const [timeoutinprogress, settimeoutinprogress] = usestate(false)
  const [logs, setlogs] = usestate>([])

  useeffect(() => {
    if (starttimeout && !timeoutinprogress) {
      settimeoutinprogress(true)
      setlogs((l) => [...l, `timeout scheduled in ${timeoutinseconds} seconds`])
      settimeout(() => {
        setlogs((l) => [...l, `you closed counter with value: ${counter}\n and now i'll increment by one. check the state`])
        settimeoutinprogress(false)
        setstarttimeout(false)
        setcounter(counter + 1)
        setlogs((l) => [...l, `did you create a closure of counter?`])

      }, timeoutinseconds * 1000);
    }
  }, [counter, starttimeout, timeoutinprogress])

  function renderlogs(): react.reactnode {
    const listitems = logs.map((log, index) =>
      
  • {log} ); return {listitems}; } function updatecounter(value: number) { setcounter(value) setlogs([...logs, `the value of counter is now ${value}`]) } function reset() { setcounter(0) setlogs(["reset done!"]) } return (

    closure demo


    counter value: {counter}


    follow the istructions to create a closure of the state variable counter

      set the counter to preferred value start a timeout and wait for {timeoutinseconds} to increment the counter (current value is {counter}) increment by 10 the counter before the timeout

    { renderlogs() } ); } export default app;
  • 登錄后復制

    解決方案

    解決方案基于useref鉤子的使用,它可以讓你引用渲染不需要的值。

    所以我們在app組件中添加:

    const currentcounter = useref(counter)
    

    登錄后復制

    然后我們修改settimeout的回調,如下所示:

    settimeout(() => {
            setlogs((l) => [...l, `you closed counter with value: ${currentcounter.current}\n and now i'll increment by one. check the state`])
            settimeoutinprogress(false)
            setstarttimeout(false)
            setcounter(currentcounter.current + 1)
            setlogs((l) => [...l, `did you create a closure of counter?`])
    
          }, timeoutinseconds * 1000);
    

    登錄后復制

    我們的回調需要讀取計數器值,因為我們之前記錄了當前值以遞增它。

    如果您不需要讀取值,只需使用功能符號更新計數器即可避免計數器關閉。

    seCounter(c => c + 1)
    

    登錄后復制

    資源

    dmitri pavlutin 使用 react hooks 時要注意過時的閉包
    imran abdulmalik 掌握 javascript 中的閉包:綜合指南

    keyur paralkar javascript 中的詞法范圍 – 初學者指南

    souvik paul react 中的陳舊閉包

    soumya dey 理解 javascript 中的詞法范圍和閉包

    subash mahapatra stackoverflow

    分享到:
    標簽:React 關閉 陳舊
    用戶無頭像

    網友整理

    注冊時間:

    網站:5 個   小程序:0 個  文章:12 篇

    • 52010

      網站

    • 12

      小程序

    • 1106242

      文章

    • 784

      會員

    趕快注冊賬號,推廣您的網站吧!
    最新入駐小程序

    數獨大挑戰2018-06-03

    數獨一種數學游戲,玩家需要根據9

    答題星2018-06-03

    您可以通過答題星輕松地創建試卷

    全階人生考試2018-06-03

    各種考試題,題庫,初中,高中,大學四六

    運動步數有氧達人2018-06-03

    記錄運動步數,積累氧氣值。還可偷

    每日養生app2018-06-03

    每日養生,天天健康

    體育訓練成績評定2018-06-03

    通用課目體育訓練成績評定