新聞中心
大家好,我卡頌。

崆峒ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)建站的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話(huà)聯(lián)系或者加微信:028-86922220(備注:SSL證書(shū)合作)期待與您的合作!
有3個(gè)容易混淆的前端框架概念:
- 響應(yīng)式更新
- 單向數(shù)據(jù)流
- 雙向數(shù)據(jù)綁定
在繼續(xù)閱讀本文前,讀者可以思考下是否明確知道三者的含義。
這三者之所以容易混淆,是因?yàn)樗麄冸m然同屬前端框架范疇內(nèi)的概念,但又不是同一抽象層級(jí)的概念,不好直接比較。
本文會(huì)從3個(gè)抽象層級(jí)入手講解這三者的區(qū)別。
響應(yīng)式更新
?「響應(yīng)式更新」也叫「細(xì)粒度更新」。同時(shí),最近前端圈比較火的??Signal??這一概念描述的也是「響應(yīng)式更新」。
籠統(tǒng)的講,「響應(yīng)式更新」描述的是「狀態(tài)與UI之間的關(guān)系」,即「狀態(tài)變化如何映射到UI變化」。
考慮如下例子(例子來(lái)自what are signals[1]一文):
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 (
)
}在TodoApp組件中,定義了兩個(gè)狀態(tài):
- 待辦事項(xiàng)todos
- 是否展示完成的事項(xiàng)showCompleted
以及根據(jù)上述狀態(tài)派生出的狀態(tài)filteredTodos?。最終,返回
如果todos?狀態(tài)變化,UI該如何變化?即「我們?cè)撊绾沃罓顟B(tài)變化的影響范圍」?這時(shí),有兩個(gè)思路:
- 推(push)
- 拉(pull)
推的原理
我們可以從變化的狀態(tài)(例子中為todos)出發(fā),根據(jù)狀態(tài)的派生關(guān)系,一路推下去。
圖片來(lái)自what are signals一文
在例子中:
- todos變化
- filteredTodos?由todos派生而來(lái),變化傳導(dǎo)到他這里
?組件依賴(lài)了filteredTodos,變化傳導(dǎo)到他這里 - 確定了todos變化的最終影響范圍后,更新對(duì)應(yīng)UI
這就建立了「狀態(tài)與UI之間的關(guān)系」。
除了「推」之外,還有一種被稱(chēng)為「拉」的方式。
拉的原理
同樣的例子,我們也能建立「狀態(tài)與可能的UI變化的關(guān)系」,再反過(guò)來(lái)推導(dǎo)??UI??變化的范圍。
圖片來(lái)自what are signals一文
在例子中:
- todos變化。
- 可能有UI變化(因?yàn)榻⒘恕笭顟B(tài)與可能的UI變化的關(guān)系」)。
- UI?與
組件相關(guān),判斷他是否變化。 ?組件依賴(lài)filteredTodos,filteredTodos由todos派生而來(lái),所以filteredTodos是變化的。 - 既然filteredTodos變化了,那么
組件可能變化。 - 計(jì)算變化的影響范圍,更新UI。
在主流框架中,React?的更新以「推」為主,Vue?、Preact?、Solid.js等更多框架使用「拉」的方式。
本文聊的「響應(yīng)式更新」就是「拉」這種方式的一種實(shí)現(xiàn)。
單向數(shù)據(jù)流
我們可以發(fā)現(xiàn),不管是「推」還是「拉」,他們都需要計(jì)算變化的影響范圍,即「一個(gè)狀態(tài)變化后,究竟有多少組件會(huì)受影響」。
那么,從框架作者的角度出發(fā),是希望增加一些約束,來(lái)減少「計(jì)算影響范圍」這一過(guò)程的復(fù)雜度。
同樣,從框架使用者的角度出發(fā),也希望增加一些約束,當(dāng)「計(jì)算影響范圍」出??bug??后,更容易排查問(wèn)題。
這就有了「單向數(shù)據(jù)流」。
「單向數(shù)據(jù)流」是一條約定,他規(guī)定了「當(dāng)狀態(tài)變化后,變化產(chǎn)生的影響只會(huì)從上往下傳遞」。
考慮如下例子:
function Parent() {
const [num] = useState(0);
return ;
}
function Child({data}) {
const isEven = data % 2 === 0;
return ;
}
function GrandChild({data}) {
return {data}
;
} 「單向數(shù)據(jù)流」并不是實(shí)現(xiàn)前端框架必須遵循的原則,他的存在主要是為了減少開(kāi)發(fā)者的心智負(fù)擔(dān),讓「狀態(tài)變化后,計(jì)算影響范圍」這一過(guò)程更可控。
雙向數(shù)據(jù)綁定
當(dāng)本文開(kāi)篇聊「響應(yīng)式更新」時(shí),討論的是「狀態(tài)與UI的關(guān)系」,這是將框架作為一個(gè)整體來(lái)討論,抽象層級(jí)比較高。
當(dāng)我們繼續(xù)聊到「單向數(shù)據(jù)流」時(shí),討論的是「狀態(tài)變化的影響范圍在組件間單向擴(kuò)散」,這是「組件與組件之間的關(guān)系」,抽象層級(jí)下降了一級(jí)。
接下來(lái)我們要討論的「雙向數(shù)據(jù)綁定」,討論的是單個(gè)組件內(nèi)發(fā)生的事。
「雙向數(shù)據(jù)綁定」是「狀態(tài)+改變狀態(tài)后觸發(fā)的回調(diào)」相結(jié)合的語(yǔ)法糖。
這里不討論框架語(yǔ)境下「語(yǔ)法糖」一詞是否完全準(zhǔn)確
比較知名的「雙向數(shù)據(jù)綁定」實(shí)現(xiàn),比如??Vue??中的??v-model??語(yǔ)法:
相當(dāng)于如下?tīng)顟B(tài)+事件回調(diào)的組合:
實(shí)際上早期React中也有類(lèi)似實(shí)現(xiàn),名叫LinkedStateMixin[2],只是早已被廢棄
總結(jié)
我們可以用一張圖概括本文介紹的3個(gè)概念之間的關(guān)系:
概括起來(lái)主要是兩點(diǎn):
- 他們都是前端框架范疇內(nèi)的概念
- 他們屬于不同抽象層級(jí)的概念
其中:
- 「雙向數(shù)據(jù)綁定」描述的是「組件內(nèi)邏輯與視圖的關(guān)系」
- 「單向數(shù)據(jù)流」描述的是「組件之間的關(guān)系」
- 「響應(yīng)式更新」描述的是「狀態(tài)與UI之間的關(guān)系」
參考資料
[1]what are signals:https://signia.tldraw.dev/docs/what-are-signals。
[2]LinkedStateMixin:https://reactjs.org/docs/two-way-binding-helpers.html。
名稱(chēng)欄目:三個(gè)容易混淆的前端框架概念
鏈接URL:http://m.fisionsoft.com.cn/article/cddpjgo.html


咨詢(xún)
建站咨詢(xún)
