從 useEffect 看 React、Vue 設計理念的不同
大家好,我卡頌。
我們知道,React
發佈Hooks
後,帶來了業界一波Hooks
熱。很多框架(比如Vue Composition API
、Solid.js
)都借鑑了Hooks
的模式。
但是,即使這些框架都借鑑了Hooks
,但由於框架作者的理念不同,發展方向也逐漸不同。
比如,在Vue Composition API
中,對標React useEffect API
的是watchEffect
,在Vue
文檔中,有一小段內容介紹他的用法:
而在React beta
文檔中,介紹useEffect
的,則有整整 6 節內容:
爲什麼會有這樣的區別?讓我們從useEffect
看看React
、Vue
設計理念的不同。
Vue 與 React 的差異
當Hooks
剛問世時,他被看作是類組件的替代方案。文檔中介紹Hooks
時也是將他與類組件對比。
其中useEffect
的執行時機囊括瞭如下 3 個生命週期函數:
-
componentDidMount
-
componentDidUpdate
-
componentWillUnmount
反觀借鑑了Hooks
的Vue Composition API
,則同時提供了watchEffect API
與不同場景的生命週期函數。
這裏已經體現出兩者設計理念的不同了:
React
作爲Facebook
爲探索 「UI 開發」 最佳實踐而生的框架,一貫的做法是 —— 保持API
穩定(比如this.setState
從React
誕生伊始就一直存在)。
而Vue
則借鑑了各種框架中的最佳實踐(比如虛擬DOM
、響應式更新
...)。
所以,從易用性上來說,Vue Composition API
是一定優於React Hooks
的,比如:
-
Hooks
不能在條件語句中聲明 -
Hooks
必須顯式指明依賴
並且,這種易用性的差異會隨着框架迭代,愈發明顯。
useEffect 會越來越複雜
本着 「保持 API 穩定」 的原則,當前useEffect
主要與上述三個生命週期函數相關。
但是,未來會有更多觸發時機與useEffect
掛鉤。
所以,React
團隊在努力做一件事 —— 淡化useEffect
與生命週期的關係,甚至淡化useEffect
與組件的關係(因爲當談到組件時,很自然的會想到組件生命週期)。
怎麼淡化呢?答案是 —— 在嚴格模式下,DEV
環境會觸發多次useEffect
回調。
如果你將useEffect
當作componentDidMount/WillUnmount
來用,這個特性很可能讓你的代碼出bug
。
React
團隊之所以這麼做,就是想教育開發者 —— useEffect
和生命週期沒有關係。開發者應該將useEffect
看作 「針對某個數據源的同步過程」。
比如,下述聊天室組件,其中的useEffect
可以看作是 「針對聊天室連接的同步過程」:
const serverUrl = 'https://localhost:1234';
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [roomId]);
// ...
}
當聊天室組件mount
、update
、unmount
時,對應的同步過程應該進行。
當roomId
變化時,對應的同步過程應該進行。
同理,如果React
原生支持了Vue
中的KeepAlive
,那麼當聊天室組件從 「可見」 變爲 「不可見」,以及從 「不可見」 變爲 「可見」 狀態,同步過程都應該進行。
所以,當我們從 「同步過程應該何時進行」 的角度看待useEffect
時,上述useEffect
觸發時機都是合理的。
但是,如果從生命週期函數的角度看待useEffect
,等未來(可能是 v18 的某個版本),Offscreen Component
特性落地(對標Vue
中的KeepAlive
),組件從 「可見」 變爲 「不可見」 狀態時,useEffect銷燬函數
與useEffect回調函數
會依次執行,就會讓人很頭大。
這就是爲什麼,我上文說,React
團隊一直在淡化useEffect
與生命週期的關係,甚至淡化useEffect
與組件的關係。
一切都是爲了 「未來其他特性與 useEffect 的掛鉤」 打下理論基礎。而這些特性從 「組件」 或 「生命週期函數」 的角度講不通。
這也是爲什麼在新文檔裏有 6 節內容與useEffect
相關的原因。
作爲對比,Vue
在遇到新的場景時會怎麼做呢?顯然是設計新的API
。
總結
到底是提供一個API
,但是能覆蓋更多場景(文檔有 6 節來介紹他)好,還是每個場景都提供一個API
好?
不同開發者有自己的答案。
但有一點很明確,對於前端新手,React
的上手難度會越來越高,而Vue
的上手難度會盡可能保持平滑。
這裏的前端新手,可能是想入行前端的新人,也可能是覺得 「前端我也能幹」 的後端。
所以,對於當前的從業者來說,這究竟是好事還是壞事呢?
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/jHBbKUmF6Ka9nQwr5kqOAQ