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