最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React的Fiber的實(shí)現(xiàn), Vue為什么不需要Fiber

 更新時(shí)間:2026年06月24日 09:24:13   作者:超絕大帥哥  
本文主要介紹了React的Fiber的實(shí)現(xiàn),React的Fiber架構(gòu)通過(guò)分緩沖和優(yōu)先級(jí)調(diào)度解決了長(zhǎng)時(shí)間阻塞頁(yè)面渲染的問(wèn)題,實(shí)現(xiàn)了任務(wù)切片和中斷恢復(fù)功能,顯著提升了用戶(hù)體驗(yàn)

在React的早期版本,React渲染組件的時(shí)候必須遞歸的處理虛擬DOM樹(shù),這就意味著要等到整顆樹(shù)都處理完畢后才會(huì)把控制權(quán)返回給瀏覽器,這就導(dǎo)致長(zhǎng)時(shí)間的阻塞頁(yè)面渲染,導(dǎo)致頁(yè)面掉幀,F(xiàn)iber就是為了解決這個(gè)問(wèn)題出現(xiàn)的, 所以Fiber就是為了將大計(jì)算量的任務(wù)分片處理出現(xiàn)的,但同時(shí)Fiber也是React通向并發(fā)渲染的地基,分片是最能被看見(jiàn)的收益

Fiber為React帶來(lái)的新活力

Fiber為React引入了在處理大任務(wù)的更多強(qiáng)大特性。在Fiber架構(gòu)下,計(jì)算虛擬DOM和將虛擬DOM映射入真實(shí)DOM兩步操作分為render階段和commit階段。

優(yōu)先級(jí)調(diào)度

在render階段React允許你中斷任務(wù),并且這個(gè)時(shí)候如果有高優(yōu)先級(jí)別的任務(wù)要處理,React會(huì)調(diào)度暫停當(dāng)前任務(wù),立即執(zhí)行高優(yōu)先級(jí)別的任務(wù),這就是React提供的優(yōu)先級(jí)調(diào)度能力。

中斷

其中低優(yōu)先級(jí)的任務(wù)被暫停的,這就是React提供的可中斷能力。

可恢復(fù)

對(duì)于被高優(yōu)先級(jí)的任務(wù),React是直接丟棄,對(duì)于時(shí)間切片的任務(wù),使用nextUnitOfWork保存執(zhí)行節(jié)點(diǎn),在下一次執(zhí)行恢復(fù)執(zhí)行

雙緩沖

在React的計(jì)算中,它不是去修改已有的虛擬dom樹(shù),而是從需要更新的組件開(kāi)始(嚴(yán)格講其實(shí)是從根開(kāi)始,只是React通過(guò)優(yōu)化手段把上面剪掉了,所以實(shí)際上是可以從訂閱了狀態(tài)的組件開(kāi)始),重新計(jì)算一套虛擬DOM, 我們就得到了兩套虛擬DOM, 一個(gè)是舊虛擬DOM, 這個(gè)虛擬DOM被映射在瀏覽器的界面上,可以說(shuō)是current樹(shù),而我們?cè)趓ender階段創(chuàng)建的新的虛擬dom樹(shù),可以說(shuō)是work-in-progress樹(shù),這是React可隨意中斷恢復(fù)的基礎(chǔ)。

特性說(shuō)明
可中斷render階段的工作可以隨時(shí)暫停(主動(dòng)暫?;虮桓邇?yōu)先級(jí)任務(wù)被動(dòng)調(diào)度中斷),瀏覽器主線程不會(huì)被長(zhǎng)時(shí)間占用
可恢復(fù)暫停后可以在下一幀從斷點(diǎn)繼續(xù),不丟失進(jìn)度
優(yōu)先級(jí)調(diào)度緊急更新可以打斷低優(yōu)先級(jí)更新
雙緩沖內(nèi)存中維護(hù)兩顆樹(shù),current樹(shù)和work-in-progress樹(shù),commit節(jié)點(diǎn)切換兩顆樹(shù)

代碼演示

render階段

下面是一個(gè)完整的演示例子用于展示React的Fiber架構(gòu), 首先我們創(chuàng)建一個(gè)虛擬DOM

const App = createElement("div", null, 
                         createElement("h1", null, "Hello Fiber"),
                         createElement("p", { onClick: () => alert("clicked") }, "Click me")); 

其中的createElement是一個(gè)用于創(chuàng)建虛擬DOM的函數(shù),作用和用法其實(shí)相當(dāng)于vue的h函數(shù)。

    function createElement(type, props, ...children) {
        return {
          type,
          props: {
            ...props,
            children: children.flat().map((item) => typeof item === "object" ? item : createTextElement(item))
          }
        }
      }

    function createTextElement(text) {
      return {
        type: "TEXT_ELEMENT",
        props: {
          nodeValue: text
        }
      }
    }

最后我們得到的虛擬dom是這樣的

{
  "type": "div",
  "props": {},
  "children": [
    {
      "type": "h1",
      "props": {},
      "children": [
        {
          "type": "TEXT_ELEMENT",
          "props": {
            "nodeValue": "Hello Fiber"
          }
        }
      ]
    },
    {
      "type": "p",
      "props": {},
      "children": [
        {
          "type": "TEXT_ELEMENT",
          "props": {
            "nodeValue": "Click me"
          }
        }
      ]
    }
  ]
}

我們現(xiàn)在進(jìn)行任務(wù)調(diào)度,生成Fiber根節(jié)點(diǎn),F(xiàn)iber節(jié)點(diǎn)是虛擬DOM的增強(qiáng)版本,用于樹(shù)的遍歷

    let wipRoot = null;
    let nextUnitOfWork = null;
    function render(vnode, container) {
      wipRoot = {
        type: "Root",
        dom: container,
        props: {
          children: [vnode]
        },
        parent: null,
        child: null,
        sibling: null,
        effectTag: null
      };

      nextUnitOfWork = wipRoot;
    }

寫(xiě)一個(gè)workLoop ,流程是先處理render階段,然后每幀的空閑時(shí)間處理一個(gè)Fiber節(jié)點(diǎn),然后在render完成后開(kāi)啟commit階段

    function workLoop(deadline) {
      while (nextUnitOfWork && deadline.timeRemaining() > 1) {
        nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
        //處理一個(gè)Fiber節(jié)點(diǎn)
      }

      if (!nextUnitOfWork && wipRoot) {
        commitRoot(); //開(kāi)啟commit階段
      }

      requestIdleCallback(workLoop);
    }

    requestIdleCallback(workLoop);

在我們的render階段,核心就是performUnitOfWork, 這個(gè)函數(shù)的目標(biāo)就是創(chuàng)建真實(shí)dom, 然后把子組件轉(zhuǎn)成一個(gè)Fiber鏈表, 逐個(gè)處理

function performUnitOfWork (fiber) {
  if (!fiber.dom && fiber.type !== "Root") {
    fiber.dom = createDom(fiber);
  }
}

這里的createDom用于創(chuàng)建真實(shí)DOM, 根據(jù)我們上述的虛擬節(jié)點(diǎn)dom的數(shù)據(jù)結(jié)構(gòu),可以很輕松的創(chuàng)建出有相應(yīng)的屬性和事件處理函數(shù)的dom節(jié)點(diǎn)

    function createDom(fiber) {
      const dom = fiber.type === "TEXT_ELEMENT" ? 
        document.createTextNode(fiber.props.nodeValue) : 
        document.createElement(fiber.type);

      updateDom(dom, {}, fiber.props);//附加上對(duì)應(yīng)的屬性和事件監(jiān)聽(tīng)器
      return dom;
    }

      const isEvent = (key) => key.startsWith("on");
      const isProp = (key) => !isEvent(key) && key !== "children";
      const getEventName = (key) => key.split("on")[1].toLowerCase();

      function updateDom(dom, source, target) {
        const sourceKeys = Object.keys(source);
        const targetKeys = Object.keys(target);

        const { event: sourceEvent = [], prop: sourceProp = [] } = Object.groupBy(sourceKeys, (key) => {
          return isEvent(key) ? "event" : isProp(key) ? "prop" : "none";
        });

        const { event: targetEvent = [], prop: targetProp = [] } = Object.groupBy(targetKeys, (key) => {
          return isEvent(key) ? "event" : isProp(key) ? "prop" : "none";
        });


        sourceEvent.forEach((originName) => {
          const eventName = getEventName(originName);
          dom.removeEventListener(eventName, source[originName]);
        });
        sourceProp.forEach((key) => {
          dom[key] = "";
        });
        targetEvent.forEach((originName) => {
          const eventName = getEventName(originName);
          dom.addEventListener(eventName, target[originName]);
        });
        targetProp.forEach((key) => {
          dom[key] = target[key];
        });
      }

結(jié)束創(chuàng)建DOM的工作,回到我們的performUnitOfWork,,接下來(lái)我們需要把Fiber節(jié)點(diǎn)的子虛擬DOM轉(zhuǎn)成一個(gè)工作流鏈表, 方便中斷和恢復(fù),樹(shù)的結(jié)構(gòu)是可以做的,但是沒(méi)有鏈表合適,

function performUnitOfWork (fiber) {
  ...
      reconcileChildren(fiber, fiber.props.children);
  ...
}
    function reconcileChildren(fiber, childs) {
        if (!(childs && Array.isArray(childs))) return null;
        let prev;
        childs.forEach((child, index) => {
          //創(chuàng)建一個(gè)Fiber節(jié)點(diǎn)
          const newFiber = {
            type: child.type,
            props: child.props,
            dom: null,
            parent: fiber,
            sibling: null,
            child: null,
            effectTag: "PLACEMENT"
          };
          if (index === 0) {
            fiber.child = newFiber;
          } else {
            prev.sibling = newFiber;
          }
          prev = newFiber;
        });

      }
      

把當(dāng)前節(jié)點(diǎn)的鏈表組件完畢后,繼續(xù)組裝下一個(gè)Fiber節(jié)點(diǎn), 回到performUnitOfWork

function performUnitOfWork(fiber) {
      ....
  
      if (fiber.child) return fiber.child;
      let nextFiber = fiber;
      while (nextFiber) {
        if (nextFiber.sibling) return nextFiber.sibling;
        nextFiber = nextFiber.parent;
      }
}

這里performUnitOfWork 最后返回下一個(gè)要處理的Fiber節(jié)點(diǎn),由workLoop在下一次空閑的時(shí)候繼續(xù)幫我們處理下一個(gè)Fiber節(jié)點(diǎn)。正是因?yàn)楸闅v被改寫(xiě)成了"沿 child → sibling → parent 指針走的循環(huán)",進(jìn)度才能用 nextUnitOfWork 一個(gè)變量記住,從而做到隨時(shí)中斷、隨時(shí)恢復(fù):

直到最后全部組裝完畢,我們查看一下我們?cè)趓ender階段得到的最終Fiber樹(shù)是什么樣的

JSON.stringify(wipRoot, (key, val) => {
    if (key === "dom" || key === "parent") return ;
    return val;
});

Fiber樹(shù)的最終結(jié)果如下

{
  "type": "Root",
  "props": {
    "children": [
      {
        "type": "div",
        "props": {
          "children": [
            {
              "type": "h1",
              "props": {
                "children": [
                  {
                    "type": "TEXT_ELEMENT",
                    "props": {
                      "nodeValue": "Hello Fiber"
                    }
                  }
                ]
              }
            },
            {
              "type": "p",
              "props": {
                "children": [
                  {
                    "type": "TEXT_ELEMENT",
                    "props": {
                      "nodeValue": "Click me"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    ]
  },
  "sibling": null,
  "child": {
    "type": "div",
    "props": {
      "children": [
        {
          "type": "h1",
          "props": {
            "children": [
              {
                "type": "TEXT_ELEMENT",
                "props": {
                  "nodeValue": "Hello Fiber"
                }
              }
            ]
          }
        },
        {
          "type": "p",
          "props": {
            "children": [
              {
                "type": "TEXT_ELEMENT",
                "props": {
                  "nodeValue": "Click me"
                }
              }
            ]
          }
        }
      ]
    },
    "sibling": null,
    "child": {
      "type": "h1",
      "props": {
        "children": [
          {
            "type": "TEXT_ELEMENT",
            "props": {
              "nodeValue": "Hello Fiber"
            }
          }
        ]
      },
      "sibling": {
        "type": "p",
        "props": {
          "children": [
            {
              "type": "TEXT_ELEMENT",
              "props": {
                "nodeValue": "Click me"
              }
            }
          ]
        },
        "sibling": null,
        "child": {
          "type": "TEXT_ELEMENT",
          "props": {
            "nodeValue": "Click me"
          },
          "sibling": null,
          "child": null,
          "effectTag": "PLACEMENT"
        },
        "effectTag": "PLACEMENT"
      },
      "child": {
        "type": "TEXT_ELEMENT",
        "props": {
          "nodeValue": "Hello Fiber"
        },
        "sibling": null,
        "child": null,
        "effectTag": "PLACEMENT"
      },
      "effectTag": "PLACEMENT"
    },
    "effectTag": "PLACEMENT"
  },
  "effectTag": null
}

可以看到props里的children用于存儲(chǔ)虛擬dom, 而child和sibling,parent(因?yàn)闀?huì)導(dǎo)致循環(huán)引用,所以這里過(guò)濾掉了,沒(méi)有展示出來(lái))是存儲(chǔ)Fiber節(jié)點(diǎn),在children可以看到有很多重復(fù)對(duì)象,實(shí)際上是共用同一套引用對(duì)象,effectTag是一個(gè)二進(jìn)制掩碼,可以組合表示多種要處理的副作用,我們這里簡(jiǎn)化了,就處理單一副作用,用的是字符串枚舉, "PLACEMENT", 也沒(méi)有Deletion,

commit階段

這里進(jìn)入commit階段,在commit階段,主要是映射虛擬dom到真實(shí)dom

    function commitRoot() {
      commitWork(wipRoot.child);
      wipRoot = null;
    }

    function commitWork(fiber) {
      if (!fiber) return;

      if (fiber.effectTag === "PLACEMENT" && fiber.dom) {
        let parent = fiber.parent;

        while (parent && !parent.dom) {
          parent = parent.parent;
        }

        parent.dom.appendChild(fiber.dom);
      }

      commitWork(fiber.child);
      commitWork(fiber.sibling);
    }

可以看到commit是一個(gè)同步遞歸的任務(wù),而且是沒(méi)有辦法被打斷的,

完整代碼及演示結(jié)果查看如下

增強(qiáng)版本

上述代碼只是演示了一個(gè)最小Fiber架構(gòu)代碼,并沒(méi)有展現(xiàn)出我們Fiber架構(gòu)中優(yōu)先級(jí)調(diào)度中斷恢復(fù)雙緩沖等功能,下面我們逐步引入這幾大代碼。

雙緩沖

在React中的Fiber架構(gòu)中,每個(gè)節(jié)點(diǎn)通過(guò)alternate字段指向另一顆樹(shù)的對(duì)應(yīng)節(jié)點(diǎn),這樣在render階段,我們操作wip(work in progress)樹(shù),不影響到屏幕上的current樹(shù), 在commit階段新舊虛擬DOM樹(shù)交換的時(shí)候, 也不需要遍歷舊虛擬dom樹(shù)進(jìn)行節(jié)點(diǎn)更新, 只需要交換新舊虛擬dom樹(shù)就可以了,在關(guān)鍵的diff對(duì)比節(jié)點(diǎn),可以通過(guò)新舊節(jié)點(diǎn)的對(duì)比,判斷復(fù)用/更新/刪除

    let currentRoot = null;
    function render (element, dom) {
        wipRoot = {
            dom,
            props: {...},
            ...
            alternate: currentRoot
        }
    }
    

      let deletions = [];
      function reconcileChildren(wipFiber, elements) {
        let oldFiber = wipFiber.alternate && wipFiber.alternate.child;
        let preFiber = null;

        for (let i = 0, len  = elements.length; i < len || oldFiber; i++) {
          const element = elements[i];
          const sameType = oldFiber && element && oldFiber.type === element.type;
          let newFiber;

          if (sameType) {
            newFiber = {
              type: element.type,
              props: element.props,
              dom: oldFiber.dom,
              parent: wipFiber,
              child: null,
              sibling: null,
              alternate: oldFiber,
              effectTag: "UPDATE"
            }
          }

          if (!sameType && element) {
            newFiber = {
              type: element.type,
              props: element.props,
              dom: null,
              parent: wipFiber,
              child: null,
              sibling: null,
              alternate: oldFiber,
              effectTag: "PLACEMENT"
            }
          }

          if (!sameType && oldFiber) {
            oldFiber.effectTag = "DELETION";
            deletions.push(oldFiber);
          }

          if (oldFiber) oldFiber = oldFiber.sibling;


          if (newFiber) {
            if (i == 0) wipFiber.child = newFiber
            else preFiber.sibling = newFiber
            preFiber = newFiber;
          }
        }
      }

然后在commit階段我們只需要交換currentRoot和wipRoot兩顆樹(shù),然后把currentRoot樹(shù)重新映射到真實(shí)dom樹(shù)中即可

    function commitRoot () {
      deletions.forEach(commitWork);
      commitWork(wipRoot.child);
      currentRoot = wipRoot;
      deletions = [];
    } 


    function commitWork (fiber) {
      if (!fiber) return ;
      let domParentFiber = fiber.parent;
      while (domParentFiber && !domParentFiber.dom) domParentFiber = domParentFiber.parent;
      const domParent = domParentFiber.dom;

      if (fiber.effectTag === "PLACEMENT" && fiber.dom != null) 
        domParent.appendChild(fiber.dom);
      else if(fiber.effectTag === "UPDATE" && fiber.dom != null)
        updateDom(fiber.dom, fiber.alternate.props, fiber.props);
      else if (fiber.effectTag === "DELETION") {
        fiber.dom.remove();//這里簡(jiǎn)化只處理當(dāng)前節(jié)點(diǎn),不處理后代
        return false;
      }

      commitWork(fiber.child);
      commitWork(fiber.sibling)
    }

在上述代碼中,可以看到Fiber提供的current樹(shù)和wip樹(shù),在render階段我們進(jìn)行wip構(gòu)建,在commit階段則交換current樹(shù)和wip,一次性的同步映射到真實(shí)dom上,這也就避免了React在current樹(shù)做diff和修改,導(dǎo)致組件可能只完成一半(尤其是是高優(yōu)先級(jí)任務(wù)插隊(duì)的時(shí)候,低優(yōu)先級(jí)的渲染可能就執(zhí)行一半就中斷了),頁(yè)面呈現(xiàn)新舊UI混合的半成品狀態(tài),即"渲染撕裂";雙緩沖樹(shù)的體系下,React先展示舊內(nèi)容,然后默默構(gòu)建wip樹(shù),完成后一次性映射到DOM上,就沒(méi)有渲染一半的說(shuō)法了,就是一次完整的渲染

優(yōu)先級(jí)調(diào)度

React的調(diào)度,是為了快速響應(yīng)用戶(hù)交互而實(shí)現(xiàn)的,防止長(zhǎng)任務(wù)執(zhí)行過(guò)程中頁(yè)面點(diǎn)擊事件被阻塞, 用戶(hù)感覺(jué)頁(yè)面"卡死了",下面展示一個(gè)最小調(diào)度邏輯

function scheduleWork(priority) {
  if (priority < wipPriority) {
    wipRoot = {
      type: "Root",
      dom: currentRoot.dom,
      props: currentRoot.props,
      alternate: currentRoot
    };
    wipPriority = priority;
    deletions = [];
    nextUnitOfWork = wipRoot;
  }
}

在這個(gè)代碼中,要是有高優(yōu)先級(jí)別的任務(wù)調(diào)用了scheduleWork, 則我們?nèi)繌母?jié)點(diǎn)開(kāi)始構(gòu)建,React則在背后使用其它手段使得避免全量構(gòu)建,

在這里直接丟棄了之前的nextUnitOfWork

中斷/恢復(fù)

中斷/恢復(fù)功能其實(shí)在基礎(chǔ)版本就體現(xiàn)出來(lái)了,通過(guò)requestIdleCallback將任務(wù)分片,每次都斷在nextUnitOfWork,然后中斷,下一次又在nextUnitOfWork這個(gè)Fiber節(jié)點(diǎn)上恢復(fù)任務(wù),這是不丟棄的,在調(diào)度部分,則是直接把之前的工作丟棄了

為什么Vue不需要Fiber ?

vue得益于它的響應(yīng)式系統(tǒng), 所有的狀態(tài)改變可以精準(zhǔn)溯源到對(duì)應(yīng)的組件,在組件級(jí)別做更新就可以了,所以任務(wù)被拆分的小,沒(méi)有一次性要構(gòu)建整個(gè)虛擬DOM的需求,所以就沒(méi)有使用Fiber機(jī)制進(jìn)行任務(wù)切片的需求,相比之下, React的響應(yīng)式機(jī)制是沒(méi)有辦法做到vue這樣的細(xì)粒度的,只能去執(zhí)行一遍組件函數(shù),然后全量的構(gòu)建看看哪些地方是變化的,通過(guò)各種優(yōu)化手段把沒(méi)變的分支剪掉, 避免全量構(gòu)建虛擬dom。

到此這篇關(guān)于React的Fiber的實(shí)現(xiàn), Vue為什么不需要Fiber的文章就介紹到這了,更多相關(guān)React Fiber內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解react native頁(yè)面間傳遞數(shù)據(jù)的幾種方式

    詳解react native頁(yè)面間傳遞數(shù)據(jù)的幾種方式

    這篇文章主要介紹了詳解react native頁(yè)面間傳遞數(shù)據(jù)的幾種方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • React實(shí)現(xiàn)todolist功能

    React實(shí)現(xiàn)todolist功能

    這篇文章主要介紹了React實(shí)現(xiàn)todolist功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • 創(chuàng)建React項(xiàng)目的三個(gè)方式小結(jié)

    創(chuàng)建React項(xiàng)目的三個(gè)方式小結(jié)

    本文主要介紹了創(chuàng)建React項(xiàng)目的三個(gè)方式小結(jié),包括create-react-app、Vite和Next.js,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • 如何對(duì)react hooks進(jìn)行單元測(cè)試的方法

    如何對(duì)react hooks進(jìn)行單元測(cè)試的方法

    這篇文章主要介紹了如何對(duì)react hooks進(jìn)行單元測(cè)試的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • React19 新增Hooks中useOptimistic的使用

    React19 新增Hooks中useOptimistic的使用

    useOptimistic是React提供的一個(gè)Hooks,用于實(shí)現(xiàn)樂(lè)觀更新UI的效果,適用于評(píng)論發(fā)送等需要即時(shí)反饋的場(chǎng)景,下面就來(lái)詳細(xì)的介紹一下
    2026-05-05
  • React函數(shù)組件與類(lèi)的區(qū)別有哪些

    React函數(shù)組件與類(lèi)的區(qū)別有哪些

    函數(shù)式組件的基本意義就是,組件實(shí)際上是一個(gè)函數(shù),不是類(lèi),下面這篇文章主要給大家介紹了關(guān)于React中函數(shù)組件與類(lèi)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • 在React中用canvas對(duì)圖片標(biāo)注的實(shí)現(xiàn)

    在React中用canvas對(duì)圖片標(biāo)注的實(shí)現(xiàn)

    本文主要介紹了在React中用canvas對(duì)圖片標(biāo)注的實(shí)現(xiàn) ,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • React更新組件狀態(tài)的常用方法

    React更新組件狀態(tài)的常用方法

    React是一個(gè)用于構(gòu)建用戶(hù)界面的JavaScript庫(kù),廣泛應(yīng)用于開(kāi)發(fā)現(xiàn)代單頁(yè)應(yīng)用(SPA),在 React 中,狀態(tài)管理是一個(gè)關(guān)鍵概念,因?yàn)樗苯佑绊懙浇M件的渲染和用戶(hù)體驗(yàn),本文將深入探討 React 中如何更新組件狀態(tài),需要的朋友可以參考下
    2025-06-06
  • React注冊(cè)倒計(jì)時(shí)功能的實(shí)現(xiàn)

    React注冊(cè)倒計(jì)時(shí)功能的實(shí)現(xiàn)

    這篇文章主要介紹了React注冊(cè)倒計(jì)時(shí)功能的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • React路由組件傳參的三種方式(params、search、state)

    React路由組件傳參的三種方式(params、search、state)

    本文主要介紹了React路由組件傳參的三種方式,主要包括了params、search、state,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07

最新評(píng)論

蕉岭县| 营山县| 长顺县| 乾安县| 微山县| 咸丰县| 东山县| 上犹县| 安阳市| 安远县| 五原县| 工布江达县| 无棣县| 平泉县| 桃江县| 临安市| 分宜县| 安丘市| 德江县| 曲麻莱县| 马尔康县| 宁陕县| 抚州市| 酒泉市| 贵溪市| 呼和浩特市| 博罗县| 武功县| 永平县| 兴宁市| 怀远县| 平山县| 元朗区| 阿瓦提县| 临澧县| 梁平县| 台南市| 周至县| 上思县| 阳西县| 印江|