亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

精讀《react-easy-state 源碼》

curlyCheng / 2550人閱讀

摘要:會(huì)自動(dòng)觸發(fā)函數(shù)內(nèi)回調(diào)函數(shù)的執(zhí)行。因此利用并將依賴置為使代碼在所有渲染周期內(nèi),只在初始化執(zhí)行一次。同時(shí)代碼里還對(duì)等公共方法進(jìn)行了包裝,讓這些回調(diào)函數(shù)中自帶效果。前端精讀幫你篩選靠譜的內(nèi)容。

1. 引言

react-easy-state 是個(gè)比較有趣的庫,利用 Proxy 創(chuàng)建了一個(gè)非常易用的全局?jǐn)?shù)據(jù)流管理方式。

import React from "react";
import { store, view } from "react-easy-state";

const counter = store({ num: 0 });
const increment = () => counter.num++;

export default view(() => );

上手非常輕松,通過 store 創(chuàng)建一個(gè)數(shù)據(jù)對(duì)象,這個(gè)對(duì)象被任何 React 組件使用時(shí),都會(huì)自動(dòng)建立雙向綁定,任何對(duì)這個(gè)對(duì)象的修改,都會(huì)讓使用了這個(gè)對(duì)象的組件重渲染。

當(dāng)然,為了實(shí)現(xiàn)這一點(diǎn),需要對(duì)所有組件包裹一層 view。

2. 精讀

這個(gè)庫利用了 nx-js/observer-util 做 Reaction 基礎(chǔ) API,其他核心功能分別是 store view batch,所以我們就從這四個(gè)點(diǎn)進(jìn)行解讀。

Reaction

這個(gè)單詞名叫 “反應(yīng)”,是實(shí)現(xiàn)雙向綁定庫的最基本功能單元。

擁有最基本的兩個(gè)單詞和一個(gè)概念:observable observe 與自動(dòng)觸發(fā)執(zhí)行的特性。

import { observable, observe } from "@nx-js/observer-util";

const counter = observable({ num: 0 });
const countLogger = observe(() => console.log(counter.num));

// 會(huì)自動(dòng)觸發(fā) countLogger 函數(shù)內(nèi)回調(diào)函數(shù)的執(zhí)行。
counter.num++;

在第 35 期精讀 精讀《dob - 框架實(shí)現(xiàn)》 “抽絲剝繭,實(shí)現(xiàn)依賴追蹤” 一節(jié)中有詳細(xì)介紹實(shí)現(xiàn)原理,這里就不贅述了。

有了一個(gè)具有反應(yīng)特性的函數(shù),與一個(gè)可以 “觸發(fā)反應(yīng)” 的對(duì)象,那么實(shí)現(xiàn)雙向綁定更新 View 就不遠(yuǎn)了。

store

react-easy-state 的 store 就是 observable(obj) 包裝一下,唯一不同是,由于支持本地?cái)?shù)據(jù):

import React from "react"
import { view, store } from "react-easy-state"

export default view(() => {
  const counter = store({ num: 0 })
  const increment = () => counter.num++
  return {counter.num}
})

所以當(dāng)監(jiān)測(cè)到在 React 組件內(nèi)部創(chuàng)建 store 且是 Hooks 環(huán)境時(shí),會(huì)返回:

return useMemo(() => observable(obj), []);

這是因?yàn)?React Hooks 場(chǎng)景下的 Function Component 每次渲染都會(huì)重新創(chuàng)建 Store,會(huì)導(dǎo)致死循環(huán)。因此利用 useMemo 并將依賴置為 [] 使代碼在所有渲染周期內(nèi),只在初始化執(zhí)行一次。

更多 Hooks 深入解讀,可以閱讀 精讀《useEffect 完全指南》。
view

根據(jù) Function Component 與 Class Component 的不同,分別進(jìn)行兩種處理,本文主要介紹對(duì) Function Component 的處理方式,因?yàn)楣P者推薦使用 Function Component 風(fēng)格。

首先最外層會(huì)套上 memo,這類似 PureComponent 的效果:

return memo(/**/);

然后構(gòu)造一個(gè) forceUpdate 用來強(qiáng)制渲染組件:

const [, forceUpdate] = useState();

之后,只要利用 observe 包裹組件即可,需要注意兩點(diǎn):

使用剛才創(chuàng)建的 forceUpdatestore 修改時(shí)調(diào)用。

observe 初始化不要執(zhí)行,因?yàn)槌跏蓟M件自己會(huì)渲染一次,再渲染一次就會(huì)造成浪費(fèi)。

所以作者通過 scheduler lazy 兩個(gè)參數(shù)完成了這兩件事:

const render = useMemo(
  () =>
    observe(Comp, {
      scheduler: () => setState({}),
      lazy: true
    }),
  []
);

return render;

最后別忘了在組件銷毀時(shí)取消監(jiān)聽:

useEffect(() => {
  return () => unobserve(render);
}, []);
batch

這也是雙向綁定數(shù)據(jù)流必須解決的經(jīng)典問題,批量更新合并。

由于修改對(duì)象就觸發(fā)渲染,這個(gè)過程太自動(dòng)化了,以至于我們都沒有機(jī)會(huì)告訴工具,連續(xù)的幾次修改能否合并起來只觸發(fā)一次渲染。 尤其是 For 循環(huán)修改變量時(shí),如果不能合并更新,在某些場(chǎng)景下代碼幾乎是不可用的。

所以 batch 就是為解決這個(gè)問題誕生的,讓我們有機(jī)會(huì)控制合并更新的時(shí)機(jī):

import React from "react";
import { view, store, batch } from "react-easy-state";

const user = store({ name: "Bob", age: 30 });

function mutateUser() {
  // this makes sure the state changes will cause maximum one re-render,
  // no matter where this function is getting invoked from
  batch(() => {
    user.name = "Ann";
    user.age = 32;
  });
}

export default view(() => (
  
name: {user.name}, age: {user.age}
));

react-easy-state 通過 scheduler 模塊完成 batch 功能,核心代碼只有五行:

export function batch(fn, ctx, args) {
  let result;
  unstable_batchedUpdates(() => (result = fn.apply(ctx, args)));
  return result;
}

利用 unstable_batchedUpdates,可以保證在其內(nèi)執(zhí)行的函數(shù)都不會(huì)觸發(fā)更新,也就是之前創(chuàng)建的 forceUpdate 雖然被調(diào)用,但是失效了,等回調(diào)執(zhí)行完畢時(shí)再一起批量更新。

同時(shí)代碼里還對(duì) setTimeout setInterval addEventListener WebSocket 等公共方法進(jìn)行了 batch 包裝,讓這些回調(diào)函數(shù)中自帶 batch 效果。

4. 總結(jié)

好了,react-easy-state 神奇的效果解釋完了,希望大家在使用第三方庫的時(shí)候都能理解背后的原理。

PS:最后,筆者目前不推薦在 Function Component 模式下使用任何三方數(shù)據(jù)流庫,因?yàn)楣俜焦δ芤呀?jīng)足夠好用了!

討論地址是:精讀《react-easy-state》 · Issue #144 · dt-fe/weekly

如果你想?yún)⑴c討論,請(qǐng) 點(diǎn)擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀 - 幫你篩選靠譜的內(nèi)容。

關(guān)注 前端精讀微信公眾號(hào)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/103311.html

相關(guān)文章

  • 精讀源碼學(xué)習(xí)》

    摘要:精讀原文介紹了學(xué)習(xí)源碼的兩個(gè)技巧,并利用實(shí)例說明了源碼學(xué)習(xí)過程中可以學(xué)到許多周邊知識(shí),都讓我們受益匪淺。討論地址是精讀源碼學(xué)習(xí)如果你想?yún)⑴c討論,請(qǐng)點(diǎn)擊這里,每周都有新的主題,周末或周一發(fā)布。 1. 引言 javascript-knowledge-reading-source-code 這篇文章介紹了閱讀源碼的重要性,精讀系列也已有八期源碼系列文章,分別是: 精讀《Immer.js》源...

    aboutU 評(píng)論0 收藏0
  • 精讀《Inject Instance 源碼

    摘要:引言本周精讀的源碼是這個(gè)庫。這個(gè)庫的目的是為了實(shí)現(xiàn)的依賴注入。精讀那么開始源碼的解析,首先是整體思路的分析。討論地址是精讀源碼如果你想?yún)⑴c討論,請(qǐng)點(diǎn)擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀幫你篩選靠譜的內(nèi)容。 1. 引言 本周精讀的源碼是 inject-instance 這個(gè)庫。 這個(gè)庫的目的是為了實(shí)現(xiàn) Class 的依賴注入。 比如我們通過 inject 描述一個(gè)成員變量,...

    hsluoyz 評(píng)論0 收藏0
  • 精讀《syntax-parser 源碼

    摘要:引言是一個(gè)版語法解析器生成器,具有分詞語法樹解析的能力。實(shí)現(xiàn)函數(shù)用鏈表設(shè)計(jì)函數(shù)是最佳的選擇,我們要模擬調(diào)用棧了。但光標(biāo)所在的位置是期望輸入點(diǎn),這個(gè)輸入點(diǎn)也應(yīng)該參與語法樹的生成,而錯(cuò)誤提示不包含光標(biāo),所以我們要執(zhí)行兩次。 1. 引言 syntax-parser 是一個(gè) JS 版語法解析器生成器,具有分詞、語法樹解析的能力。 通過兩個(gè)例子介紹它的功能。 第一個(gè)例子是創(chuàng)建一個(gè)詞法解析器 my...

    yuanxin 評(píng)論0 收藏0
  • 精讀《Epitath 源碼 - renderProps 新用法》

    摘要:精讀源碼一共行,我們分析一下其精妙的方式。更多討論討論地址是精讀新用法如果你想?yún)⑴c討論,請(qǐng)點(diǎn)擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀幫你篩選靠譜的內(nèi)容。 1 引言 很高興這一期的話題是由 epitath 的作者 grsabreu 提供的。 前端發(fā)展了 20 多年,隨著發(fā)展中國家越來越多的互聯(lián)網(wǎng)從業(yè)者涌入,現(xiàn)在前端知識(shí)玲瑯滿足,概念、庫也越來越多。雖然內(nèi)容越來越多,但作為個(gè)體的...

    Magicer 評(píng)論0 收藏0
  • 精讀《React PowerPlug 源碼

    摘要:今天我們就來解讀一下的源碼。比較有意思,將定時(shí)器以方式提供出來,并且提供了方法。實(shí)現(xiàn)方式是,在組件內(nèi)部維護(hù)一個(gè)定時(shí)器,實(shí)現(xiàn)了組件更新銷毀時(shí)的計(jì)時(shí)器更新銷毀操作,可以認(rèn)為這種定時(shí)器的生命周期綁定了組件的生命周期,不用擔(dān)心銷毀和更新的問題。 1. 引言 React PowerPlug 是利用 render props 進(jìn)行更好狀態(tài)管理的工具庫。 React 項(xiàng)目中,一般一個(gè)文件就是一個(gè)類,...

    teren 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<