【轉】3個容易混淆的前端框架概念

大家好,我卡頌。

有3個容易混淆的前端框架概念:

  1. 響應式更新
  2. 單向數據流
  3. 雙向數據綁定

在繼續閱讀本文前,讀者可以思考下是否明確知道三者的含義。

這三者之所以容易混淆,是因爲他們雖然同屬前端框架範疇內的概念,但又不是同一抽象層級的概念,不好直接比較。

本文會從3個抽象層級入手講解這三者的區別。

歡迎加入人類高質量前端交流羣,帶飛

響應式更新

響應式更新也叫細粒度更新。同時,最近前端圈比較火的Signal這一概念描述的也是響應式更新

籠統的講,響應式更新描述的是狀態與UI之間的關係,即狀態變化如何映射到UI變化

考慮如下例子(例子來自what are signals一文):

function TodoApp() {
    const [todos, setTodos] = useState(
      [{ text: 'sleep', completed: false }]
    )

    const [showCompleted, setShowCompleted] = useState(false)

    const filteredTodos = useMemo(() => {
        return todos.filter((todo) => !todo.completed || showCompleted)
    }, [todos, showCompleted])

    return (
        <TodoList todos={filteredTodos} />
    )
}

TodoApp組件中,定義了兩個狀態:

  • 待辦事項todos
  • 是否展示完成的事項showCompleted

以及根據上述狀態派生出的狀態filteredTodos。最終,返回<TodoList/>組件。

如果todos狀態變化,UI該如何變化?即我們該如何知道狀態變化的影響範圍?這時,有兩個思路:

  • 推(push
  • 拉(pull

推的原理

我們可以從變化的狀態(例子中爲todos)出發,根據狀態的派生關係,一路推下去。

在例子中:

  1. todos變化
  2. filteredTodostodos派生而來,變化傳導到他這裏
  3. <TodoList/>組件依賴了filteredTodos,變化傳導到他這裏
  4. 確定了todos變化的最終影響範圍後,更新對應UI

這就建立了狀態與UI之間的關係

除了之外,還有一種被稱爲的方式。

拉的原理

同樣的例子,我們也能建立狀態與可能的UI變化的關係,再反過來推導UI變化的範圍。

在例子中:

  1. todos變化
  2. 可能有UI變化(因爲建立了狀態與可能的UI變化的關係
  3. UI<TodoList/>組件相關,判斷他是否變化
  4. <TodoList/>組件依賴filteredTodosfilteredTodostodos派生而來,所以filteredTodos是變化的
  5. 既然filteredTodos變化了,那麼<TodoList/>組件可能變化
  6. 計算變化的影響範圍,更新UI

在主流框架中,React的更新以爲主,VuePreactSolid.js等更多框架使用的方式。

本文聊的響應式更新就是這種方式的一種實現。

單向數據流

我們可以發現,不管是還是,他們都需要計算變化的影響範圍,即一個狀態變化後,究竟有多少組件會受影響

那麼,從框架作者的角度出發,是希望增加一些約束,來減少計算影響範圍這一過程的複雜度。

同樣,從框架使用者的角度出發,也希望增加一些約束,當計算影響範圍bug後,更容易排查問題。

這就有了單向數據流

單向數據流是一條約定,他規定了當狀態變化後,變化產生的影響只會從上往下傳遞

考慮如下例子:

function Parent() {
  const [num] = useState(0);
  return <Child data={num}/>;
}

function Child({data}) {
  const isEven = data % 2 === 0;
  return <GrandChild data={isEven}/>;
}

function GrandChild({data}) {
  return <p>{data}</p>;
}

<Parent/>組件的狀態num作爲props傳給<Child/>組件,再作爲props傳給<GrandChild/>組件,整個過程只能自上而下。

單向數據流並不是實現前端框架必須遵循的原則,他的存在主要是爲了減少開發者的心智負擔,讓狀態變化後,計算影響範圍這一過程更可控。

雙向數據綁定

當本文開篇聊響應式更新時,討論的是狀態與UI的關係,這是將框架作爲一個整體來討論,抽象層級比較高。

當我們繼續聊到單向數據流時,討論的是狀態變化的影響範圍在組件間單向擴散,這是組件與組件之間的關係,抽象層級下降了一級。

接下來我們要討論的雙向數據綁定,討論的是單個組件內發生的事。

雙向數據綁定狀態+改變狀態後觸發的回調相結合的語法糖。

這裏不討論框架語境下「語法糖」一詞是否完全準確

比較知名的雙向數據綁定實現,比如Vue中的v-model語法:

<input v-model=‘data’/>

相當於如下狀態+事件回調的組合:

<input @input='onInput' :value=‘data’ />

實際上早期React中也有類似實現,名叫LinkedStateMixin,只是早已被廢棄

總結

我們可以用一張圖概括本文介紹的3個概念之間的關係:

概括起來主要是兩點:

  • 他們都是前端框架範疇內的概念
  • 他們屬於不同抽象層級的概念

其中:

  • 雙向數據綁定描述的是組件內邏輯與視圖的關係
  • 單向數據流描述的是組件之間的關係
  • 響應式更新描述的是狀態與UI之間的關係

原文:https://segmentfault.com/a/1190000043512498

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章