摘要:難道還不允許設(shè)計得對新人更友好了我們先把做成就是找罵啊這怎么怪到我們頭上了事實(shí)是,即使在內(nèi)部,也顯然不是所有程序員都熟悉函數(shù)式編程的概念。
1.前言介紹
歷史
React在2013年開源,在2015引入函數(shù)式組件,不過在日常開發(fā)中經(jīng)常被忽略。
ReactJS Core Team 確實(shí)大部分成員都曾在推特上公開夸贊過對函數(shù)式編程 與 ML 系語言(或其特性)的優(yōu)點(diǎn):Sebastian 日常提到 OCaml,Sophie 至少提過 Rust/Kotlin/Swift 并且嫌棄過 Dart 沒有 ADT 和 non-nullability,Dan 和 Andrew 的 Redux 主要受 Elm 影響,Dan 曾提過學(xué)習(xí)高階函數(shù)后省去了一半設(shè)計模式,Andrew 的 Recompose 主要利用了函數(shù)的組合性,其他成員未知。
為什么引入class組件:
Chenglou: God forbid React api led newcomers into something familiar instead of FP purists’ agendas lol。
難道還不允許 React API 設(shè)計得對新人更友好了?
Cristiano: So I guess also making React in JS in the first place was the ultimate trolling.
我們先把 React 做成 JS 就是找罵啊……
Jordan: They"re onto us.
這怎么怪到我們頭上了……
事實(shí)是,即使在 FB 內(nèi)部,也顯然不是所有程序員都熟悉函數(shù)式編程的概念。做一個前端框架是拿來用的,如果有大家熟悉的概念可以對照,為什么刻意要去用大家不熟悉的概念呢?對于遷移至 ES6 Class,主要的目的是為了減少 React 特有的 API,畢竟 并不因為它「接受一個函數(shù)」就比 ES6 class 更函數(shù)式了……
2.函數(shù)式組件和類組件的區(qū)別在之前class組件通常被認(rèn)為有更多的功能,例如可以擁有state,可以調(diào)用生命周期,而現(xiàn)在在hooks引入之后這個說法就不成立了。以前Function組件沒有state,所以也叫SFC(stateless functional component),現(xiàn)在更新叫做FC(functional component)?;蛟S你也聽說過,這兩類組件中,有一類的性能更好。哪一類呢?很多這方面的性能測試,都是 有缺陷的 ,因此要從這些測試中 得出結(jié)論 ,不得不謹(jǐn)慎一點(diǎn)。性能主要取決于你代碼要實(shí)現(xiàn)的功能(以及你的具體實(shí)現(xiàn)邏輯),和使用函數(shù)組件還是類組件,沒什么關(guān)系。我們觀察發(fā)現(xiàn),盡管函數(shù)組件和類組件的性能優(yōu)化策略 有些不同 ,但是他們性能上的差異是很微小的。
構(gòu)建時的差別先看下面兩個組件:
函數(shù)式組件在父組件中執(zhí)行的函數(shù)的方法:
function Greeting() { returnHello
; } // Inside React const result = Greeting(props); //Hello
類組件在父組件中先實(shí)例化一個對象,然后執(zhí)行這個對象上的render方法:
class Greeting extends React.Component { render() { return運(yùn)行時的差別Hello
; } } // Inside React const instance = new Greeting(props); // Greeting {} const result = instance.render(); //Hello
再來看兩段代碼
一個兩秒后執(zhí)行alter的按鈕的函數(shù)式組件
function ProfilePage(props) { const showMessage = () => { alert("我是 " + props.user); }; const handleClick = () => { setTimeout(showMessage, 2000); }; return ( ); }
一個兩秒后執(zhí)行alter的按鈕的函數(shù)式組件
class ProfilePage extends React.Component { showMessage = () => { alert("我是" + this.props.user); }; handleClick = () => { setTimeout(this.showMessage, 2000); }; render() { return ; } }
一般我們會認(rèn)為上面兩個組件是完全等價的。開發(fā)者經(jīng)常像上面這樣,在函數(shù)組件和類組件之間重構(gòu)代碼,卻沒有意識到他們隱含的差異。然而這兩個是有一些差別,你有看出這兩個的區(qū)別嗎?
我們用一個組件將上面兩個組件包裹
function App() { const [user, setUser] = useState("小碼王") return (); }{user}
當(dāng)我們先點(diǎn)擊Class按鈕然后再點(diǎn)擊changName按鈕,alert出的我是小碼世界,而我們先點(diǎn)擊Function再點(diǎn)擊changName,alter出的我是小碼王。
為什么會這樣呢?
我們可以看到在函數(shù)式組件中user是在props中讀取的,而在類組件中user是從this.props中讀取的,區(qū)別就在this上,在react中props是不可變,而this是可變的,所以當(dāng)父組件的值改變時this也改變了。
有什么方法使類組件也實(shí)現(xiàn)函數(shù)式組件的效果呢?
class ProfilePage extends React.Component { render() { // Capture the props! const props = this.props; const showMessage = () => { alert("我是 " + props.user); }; const handleClick = () => { setTimeout(showMessage, 2000); }; return ; } }
在render函數(shù)中創(chuàng)造了一個props的閉包,這個問題就解決了,是不是感覺段代碼比較熟悉,其實(shí)在render函數(shù)里面的代碼抽離出來就是函數(shù)式的組件了。所以當(dāng)函數(shù)式組件有render方法以外的功能,就可以實(shí)現(xiàn)類組件的任何功能了,這就是hooks了。
3. Hooks在 Hooks 的協(xié)議設(shè)計考量上,與原本的 React HoC Design 其實(shí)會有很多的不同,主要原因也許就在于 HoC 總的來說是 Props 導(dǎo)向的設(shè)計,而 Hooks 則是更 functional 風(fēng)格的調(diào)用形態(tài)。并且,HoC 可能會傾向于避免產(chǎn)生過多的 HoC 層級,而產(chǎn)生過深的 VDOM Tree。Hooks 大可以更自由地講更多的 use 方法分離式的調(diào)用,也能夠得到更大的自由度;Hooks解決的問題
代碼重用:在hooks出來之前,常見的代碼重用方式是HOCs和render props,這兩種方式帶來的問題是:你需要解構(gòu)自己的組件,同時會帶來很深的組件嵌套
復(fù)雜的組件邏輯:在class組件中,有許多的lifecycle 函數(shù),你需要在各個函數(shù)的里面去做對應(yīng)的事情。這種方式帶來的痛點(diǎn)是:邏輯分散在各處,開發(fā)者去維護(hù)這些代碼會分散自己的精力,理解代碼邏輯也很吃力
class組件的困惑:對于初學(xué)者來說,需要理解class組件里面的this是比較吃力的(這個理由有點(diǎn)勉強(qiáng)~),同時,基于class的組件難以優(yōu)化(舉個不恰當(dāng)?shù)睦?,看一下babel轉(zhuǎn)移出來的class代碼量增長了多少)
從react team 公布 hooks的概念時,淘寶內(nèi)部做了一些簡單的研究與調(diào)研,結(jié)論是hooks是類react體系的未來主流編程模式,無論是基于hooks后業(yè)務(wù)代碼會更簡練還是復(fù)用更容易,這些都是降低了react 編程的門檻。
尤雨溪也稱vue3.0的特性吸取了很多hooks的靈感,并在最新的RFC(意見征求稿)中發(fā)布了Function API + Hooks 。
React Hook讓無狀態(tài)組件擁有了許多只有有狀態(tài)組件的能力,如自更新能力(setState,使用useState),訪問ref(使用useRef或useImperativeMethods),訪問context(使用useContext),使用更高級的setState設(shè)置(useReducer),及進(jìn)行類似生命周期的階段性方法(useEffect或useLayoutEffect)。
hooks之間的關(guān)系 useState useReducer useRef關(guān)系function useReducer(reducer, initialArg,init){ var initialState = void 0; if (init !== undefined) { initialState = init(initialArg); } else { initialState = initialArg; } function dispatch(action){ memoizedState = reducer(memoizedState,action); render(); } memoizedState = memoizedState||initialState; return [memoizedState, dispatch]; } function useState(initialState){ return useReducer((oldState, newState)=>newState, initialState); }
?useRef() === useState({current: initialValue })[0]useEffect useLayoutEffect的關(guān)系 useMemo useCallback的關(guān)系
useCallback和useMemo的參數(shù)跟useEffect一致,他們之間最大的區(qū)別有是useEffect會用于處理副作用,而前兩個hooks不能。
useMemo和useCallback都會在組件第一次渲染的時候執(zhí)行,之后會在其依賴的變量發(fā)生改變時再次執(zhí)行;并且這兩個hooks都返回緩存的值,useMemo返回緩存的變量,useCallback返回緩存的函數(shù)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105819.html
摘要:他們的應(yīng)用是比較復(fù)雜的,組件樹也是非常龐大,假設(shè)有一千個組件要渲染,每個耗費(fèi)一千個就是由于是單線程的,這里都在努力的干活,一旦開始,中間就不會停。 悄悄的, React v16.7 發(fā)布了。 React v16.7: No, This Is Not The One With Hooks. showImg(https://segmentfault.com/img/bVblq9L?w=97...
摘要:但我認(rèn)為談不上的毛病,而是編程模型和之間的一種模式差異。相比類,更貼近編程模型,使得這種差異更加突出。聲明本文采用循序漸進(jìn)的示例來解釋問題。本文假設(shè)讀者已經(jīng)使用超過一個小時。這是通過組件生命周期上綁定與的組合完成的。 本文由云+社區(qū)發(fā)表作者:Dan Abramov 接觸 React Hooks 一定時間的你,也許會碰到一個神奇的問題: setInterval 用起來沒你想的簡單。 R...
摘要:在線傳遞給的是而不是,返回值即是想要透傳的數(shù)據(jù)了。所以函數(shù)組件在每次渲染的時候如果有傳遞函數(shù)的話都會重渲染子組件。在學(xué)會使用React Hooks之前,可以先看一下相關(guān)原理學(xué)習(xí)React Hooks 前言 在 React 的世界中,有容器組件和 UI 組件之分,在 React Hooks 出現(xiàn)之前,UI 組件我們可以使用函數(shù),無狀態(tài)組件來展示 UI,而對于容器組件,函數(shù)組件就顯得無能為力,我...
摘要:前言樓主最近在整理的一些資料,為項目重構(gòu)作準(zhǔn)備,下午整理成了這篇文章。給傳入的是一個初始值,比如,這個按鈕的最初要顯示的是。取代了提供了一個統(tǒng)一的。 showImg(https://segmentfault.com/img/bVbpUle?w=900&h=550); Hooks are a new addition in React 16.8. They let you use sta...
摘要:前言樓主最近在整理的一些資料,為項目重構(gòu)作準(zhǔn)備,下午整理成了這篇文章。給傳入的是一個初始值,比如,這個按鈕的最初要顯示的是。取代了提供了一個統(tǒng)一的。 showImg(https://segmentfault.com/img/bVbpUle?w=900&h=550); Hooks are a new addition in React 16.8. They let you use sta...
閱讀 919·2021-10-25 09:48
閱讀 662·2021-08-23 09:45
閱讀 2524·2019-08-30 15:53
閱讀 1780·2019-08-30 12:45
閱讀 667·2019-08-29 17:21
閱讀 3456·2019-08-27 10:56
閱讀 2577·2019-08-26 13:48
閱讀 721·2019-08-26 12:24