React高頻面試題

原文地址

1. 生命周期

  • 初始化階段

  • constructor 構(gòu)造函數(shù)

  • getDefaultProps props默認(rèn)值

  • getInitialState state默認(rèn)值

  • 掛載階段

  • componentWillMount 組件初始化渲染前調(diào)用

  • render 組件渲染

  • componentDidMount組件掛載到 DOM后調(diào)用

  • 更新階段

  • componentWillReceiveProps 組件將要接收新 props前調(diào)用

  • shouldComponentUpdate 組件是否需要更新

  • componentWillUpdate 組件更新前調(diào)用

  • render 組件渲染

  • componentDidUpdate 組件更新后調(diào)用

  • 卸載階段

  • componentWillUnmount 組件卸載前調(diào)用

2. 生命周期

  • 初始化階段

  • constructor 構(gòu)造函數(shù)

  • getDefaultProps props默認(rèn)值

  • getInitialState state默認(rèn)值

  • 掛載階段

  • staticgetDerivedStateFromProps(props,state)

  • render

  • componentDidMount

getDerivedStateFromProps:組件每次被 rerender的時(shí)候卖毁,包括在組件構(gòu)建之后(虛擬 dom之后踪区,實(shí)際 dom掛載之前),每次獲取新的 propsstate之后褒傅;每次接收新的props之后都會(huì)返回一個(gè)對(duì)象作為新的 state捧存,返回null則說(shuō)明不需要更新 state粪躬;配合 componentDidUpdate,可以覆蓋 componentWillReceiveProps的所有用法

  • 更新階段

  • staticgetDerivedStateFromProps(props,state)

  • shouldComponentUpdate

  • render

  • getSnapshotBeforeUpdate(prevProps,prevState)

  • componentDidUpdate

getSnapshotBeforeUpdate:觸發(fā)時(shí)間:update發(fā)生的時(shí)候昔穴,在render之后镰官,在組件dom渲染之前;返回一個(gè)值吗货,作為componentDidUpdate的第三個(gè)參數(shù)泳唠;配合componentDidUpdate, 可以覆蓋componentWillUpdate`的所有用法

  • 卸載階段

  • componentWillUnmount

  • 錯(cuò)誤處理

  • componentDidCatch

React16新的生命周期棄用了 componentWillMount、componentWillReceivePorps宙搬,componentWillUpdate新增了 getDerivedStateFromProps笨腥、getSnapshotBeforeUpdate來(lái)代替棄用的三個(gè)鉤子函數(shù)。

React16并沒(méi)有刪除這三個(gè)鉤子函數(shù)勇垛,但是不能和新增的鉤子函數(shù)混用脖母,React17將會(huì)刪除這三個(gè)鉤子函數(shù),新增了對(duì)錯(cuò)誤的處理(componentDidCatch`)

3. setState是同步的還是異步的窥摄?

  • 生命周期和合成事件中

React的生命周期和合成事件中镶奉, React仍然處于他的更新機(jī)制中,這時(shí)無(wú)論調(diào)用多少次 setState,都會(huì)不會(huì)立即執(zhí)行更新哨苛,而是將要更新的·存入 _pendingStateQueue鸽凶,將要更新的組件存入 dirtyComponent

當(dāng)上一次更新機(jī)制執(zhí)行完畢建峭,以生命周期為例玻侥,所有組件,即最頂層組件 didmount后會(huì)將批處理標(biāo)志設(shè)置為 false亿蒸。這時(shí)將取出 dirtyComponent中的組件以及 _pendingStateQueue中的 state進(jìn)行更新凑兰。這樣就可以確保組件不會(huì)被重新渲染多次。

當(dāng)我們?cè)趫?zhí)行 setState后立即去獲取 state边锁,這時(shí)是獲取不到更新后的 state的姑食,因?yàn)樘幱?React的批處理機(jī)制中, state被暫存起來(lái)茅坛,待批處理機(jī)制完成之后音半,統(tǒng)一進(jìn)行更新。

所以贡蓖。setState本身并不是異步的曹鸠,而是 React的批處理機(jī)制給人一種異步的假象。

  • 異步代碼和原生事件中
    當(dāng)我們?cè)诋惒酱a中調(diào)用 setState時(shí)斥铺,根據(jù) JavaScript的異步機(jī)制彻桃,會(huì)將異步代碼先暫存,等所有同步代碼執(zhí)行完畢后在執(zhí)行晾蜘,這時(shí) React的批處理機(jī)制已經(jīng)走完,處理標(biāo)志設(shè)被設(shè)置為 false笙纤,這時(shí)再調(diào)用 setState即可立即執(zhí)行更新耗溜,拿到更新后的結(jié)果组力。

在原生事件中調(diào)用 setState并不會(huì)出發(fā) React的批處理機(jī)制省容,所以立即能拿到最新結(jié)果。

  • 最佳實(shí)踐

setState的第二個(gè)參數(shù)接收一個(gè)函數(shù)燎字,該函數(shù)會(huì)在 React的批處理機(jī)制完成之后調(diào)用腥椒,所以你想在調(diào)用 setState后立即獲取更新后的值,請(qǐng)?jiān)谠摶卣{(diào)函數(shù)中獲取候衍。

為什么有時(shí)連續(xù)多次setState只有一次生效笼蛛?

原因就是 React會(huì)批處理機(jī)制中存儲(chǔ)的多個(gè) setState進(jìn)行合并,來(lái)看下 React源碼中的 _assign函數(shù)蛉鹿,類似于 Objectassign

如果傳入的是對(duì)象滨砍,很明顯會(huì)被合并成一次,所以上面的代碼兩次打印的結(jié)果是相同的

  • 最佳實(shí)踐

React會(huì)對(duì)多次連續(xù)的 setState進(jìn)行合并,如果你想立即使用上次 setState后的結(jié)果進(jìn)行下一次 setState惋戏,可以讓 setState 接收一個(gè)函數(shù)而不是一個(gè)對(duì)象领追。這個(gè)函數(shù)用上一個(gè) state 作為第一個(gè)參數(shù),將此次更新被應(yīng)用時(shí)的 props 做為第二個(gè)參數(shù)响逢。

4. React如何實(shí)現(xiàn)自己的事件機(jī)制绒窑?

React事件并沒(méi)有綁定在真實(shí)的 Dom節(jié)點(diǎn)上,而是通過(guò)事件代理舔亭,在最外層的 document上對(duì)事件進(jìn)行統(tǒng)一分發(fā)些膨。

組件掛載、更新時(shí):

  • 通過(guò) lastProps钦铺、 nextProps判斷是否新增订雾、刪除事件分別調(diào)用事件注冊(cè)、卸載方法矛洞。

  • 調(diào)用 EventPluginHubenqueuePutListener進(jìn)行事件存儲(chǔ)

  • 獲取 document對(duì)象葬燎。

  • 根據(jù)事件名稱(如 onClickonCaptureClick)判斷是進(jìn)行冒泡還是捕獲缚甩。

  • 判斷是否存在 addEventListener方法谱净,否則使用 attachEvent(兼容IE)。

  • document注冊(cè)原生事件回調(diào)為 dispatchEvent(統(tǒng)一的事件分發(fā)機(jī)制)擅威。

事件初始化:

  • EventPluginHub負(fù)責(zé)管理 React合成事件的 callback壕探,它將 callback存儲(chǔ)在 listenerBank中,另外還存儲(chǔ)了負(fù)責(zé)合成事件的 Plugin郊丛。

  • 獲取綁定事件的元素的唯一標(biāo)識(shí) key李请。

  • callback根據(jù)事件類型,元素的唯一標(biāo)識(shí) key存儲(chǔ)在 listenerBank中厉熟。

  • listenerBank的結(jié)構(gòu)是: listenerBank[registrationName][key]导盅。

觸發(fā)事件時(shí):

  • 觸發(fā) document注冊(cè)原生事件的回調(diào) dispatchEvent

  • 獲取到觸發(fā)這個(gè)事件最深一級(jí)的元素

  • 遍歷這個(gè)元素的所有父元素,依次對(duì)每一級(jí)元素進(jìn)行處理揍瑟。

  • 構(gòu)造合成事件白翻。

  • 將每一級(jí)的合成事件存儲(chǔ)在 eventQueue事件隊(duì)列中。

  • 遍歷 eventQueue绢片。

  • 通過(guò) isPropagationStopped判斷當(dāng)前事件是否執(zhí)行了阻止冒泡方法滤馍。

  • 如果阻止了冒泡,停止遍歷底循,否則通過(guò) executeDispatch執(zhí)行合成事件巢株。

  • 釋放處理完成的事件。

React在自己的合成事件中重寫了 stopPropagation方法熙涤,將 isPropagationStopped設(shè)置為 true阁苞,然后在遍歷每一級(jí)事件的過(guò)程中根據(jù)此遍歷判斷是否繼續(xù)執(zhí)行困檩。這就是 React自己實(shí)現(xiàn)的冒泡機(jī)制。

5. 為何React事件要自己綁定this那槽?

在上面提到的事件處理流程中窗看, Reactdocument上進(jìn)行統(tǒng)一的事件分發(fā), dispatchEvent通過(guò)循環(huán)調(diào)用所有層級(jí)的事件來(lái)模擬事件冒泡和捕獲倦炒。

React源碼中显沈,當(dāng)具體到某一事件處理函數(shù)將要調(diào)用時(shí),將調(diào)用 invokeGuardedCallback方法逢唤。

     function invokeGuardedCallback(name, func, a)  {

        try  {

            func(a);

        }  catch  (x)  {

                if  (caughtError ===  null)  {

                    caughtError = x;
                }

        }

      }}

可見(jiàn)拉讯,事件處理函數(shù)是直接調(diào)用的,并沒(méi)有指定調(diào)用的組件鳖藕,所以不進(jìn)行手動(dòng)綁定的情況下直接獲取到的 this是不準(zhǔn)確的魔慷,所以我們需要手動(dòng)將當(dāng)前組件綁定到 this上。

6. 原生事件和React事件的區(qū)別著恩?

  • React 事件使用駝峰命名院尔,而不是全部小寫。

  • 通過(guò) JSX , 你傳遞一個(gè)函數(shù)作為事件處理程序喉誊,而不是一個(gè)字符串邀摆。

  • React 中你不能通過(guò)返回 false 來(lái)阻止默認(rèn)行為。必須明確調(diào)用 preventDefault伍茄。

7. React的合成事件是什么栋盹?

React 根據(jù) W3C 規(guī)范定義了每個(gè)事件處理函數(shù)的參數(shù),即合成事件敷矫。

事件處理程序?qū)鬟f SyntheticEvent 的實(shí)例例获,這是一個(gè)跨瀏覽器原生事件包裝器。它具有與瀏覽器原生事件相同的接口曹仗,包括 stopPropagation()preventDefault()榨汤,在所有瀏覽器中他們工作方式都相同。

React合成的 SyntheticEvent采用了事件池怎茫,這樣做可以大大節(jié)省內(nèi)存收壕,而不會(huì)頻繁的創(chuàng)建和銷毀事件對(duì)象。

另外遭居,不管在什么瀏覽器環(huán)境下啼器,瀏覽器會(huì)將該事件類型統(tǒng)一創(chuàng)建為合成事件旬渠,從而達(dá)到了瀏覽器兼容的目的俱萍。

8. React和原生事件的執(zhí)行順序是什么?可以混用嗎告丢?

React的所有事件都通過(guò) document進(jìn)行統(tǒng)一分發(fā)枪蘑。當(dāng)真實(shí) Dom觸發(fā)事件后冒泡到 document后才會(huì)對(duì) React事件進(jìn)行處理损谦。

所以原生的事件會(huì)先執(zhí)行,然后執(zhí)行 React合成事件岳颇,最后執(zhí)行真正在 document上掛載的事件

React事件和原生事件最好不要混用照捡。原生事件中如果執(zhí)行了 stopPropagation方法,則會(huì)導(dǎo)致其他 React事件失效话侧。因?yàn)樗性氐氖录o(wú)法冒泡到 document上栗精,導(dǎo)致所有的 React事件都將無(wú)法被觸發(fā)。瞻鹏。

9. 虛擬Dom是什么悲立?

在原生的 JavaScript程序中,我們直接對(duì) DOM進(jìn)行創(chuàng)建和更改新博,而 DOM元素通過(guò)我們監(jiān)聽(tīng)的事件和我們的應(yīng)用程序進(jìn)行通訊薪夕。

React會(huì)先將你的代碼轉(zhuǎn)換成一個(gè) JavaScript對(duì)象,然后這個(gè) JavaScript對(duì)象再轉(zhuǎn)換成真實(shí) DOM赫悄。這個(gè) JavaScript對(duì)象就是所謂的虛擬 DOM原献。

當(dāng)我們需要?jiǎng)?chuàng)建或更新元素時(shí), React首先會(huì)讓這個(gè) VitrualDom對(duì)象進(jìn)行創(chuàng)建和更改埂淮,然后再將 VitrualDom對(duì)象渲染成真實(shí)DOM姑隅。

當(dāng)我們需要對(duì) DOM進(jìn)行事件監(jiān)聽(tīng)時(shí),首先對(duì) VitrualDom進(jìn)行事件監(jiān)聽(tīng)倔撞, VitrualDom會(huì)代理原生的 DOM事件從而做出響應(yīng)粤策。

10. 虛擬Dom比普通Dom更快嗎?

很多文章說(shuō) VitrualDom可以提升性能误窖,這一說(shuō)法實(shí)際上是很片面的叮盘。

直接操作 DOM是非常耗費(fèi)性能的,這一點(diǎn)毋庸置疑霹俺。但是 React使用 VitrualDom也是無(wú)法避免操作 DOM的柔吼。

如果是首次渲染, VitrualDom不具有任何優(yōu)勢(shì)丙唧,甚至它要進(jìn)行更多的計(jì)算愈魏,消耗更多的內(nèi)存。

VitrualDom的優(yōu)勢(shì)在于 ReactDiff算法和批處理策略想际, React在頁(yè)面更新之前培漏,提前計(jì)算好了如何進(jìn)行更新和渲染 DOM。實(shí)際上胡本,這個(gè)計(jì)算過(guò)程我們?cè)谥苯硬僮?DOM時(shí)牌柄,也是可以自己判斷和實(shí)現(xiàn)的,但是一定會(huì)耗費(fèi)非常多的精力和時(shí)間侧甫,而且往往我們自己做的是不如 React好的珊佣。所以蹋宦,在這個(gè)過(guò)程中 React幫助我們"提升了性能"。

所以咒锻,我更傾向于說(shuō)冷冗, VitrualDom幫助我們提高了開發(fā)效率,在重復(fù)渲染時(shí)它幫助我們計(jì)算如何更高效的更新惑艇,而不是它比 DOM操作更快蒿辙。

11. 虛擬Dom中的$$typeof屬性的作用是什么?

ReactElement中有一個(gè) $$typeof屬性滨巴,它被賦值為 REACT_ELEMENT_TYPE

      var REACT_ELEMENT_TYPE =`(typeof  Symbol  ===  'function'  &&  Symbol.for  &&  Symbol.for('react.element'))  ||  0xeac7`;

可見(jiàn)须板, $$typeof是一個(gè) Symbol類型的變量,這個(gè)變量可以防止 XSS兢卵。

如果你的服務(wù)器有一個(gè)漏洞习瑰,允許用戶存儲(chǔ)任意 JSON對(duì)象, 而客戶端代碼需要一個(gè)字符串秽荤,這可能會(huì)成為一個(gè)問(wèn)題:


    // JSON  
    
    let expectedTextButGotJSON =  {  
    
        type:  'div',  

        props:  {

        dangerouslySetInnerHTML:  {  

        __html:  '/* put your exploit here */' 

        },

        },
    
    };
    
    let message =  { text: expectedTextButGotJSON };
    
    <p>{message.text}</p>

JSON中不能存儲(chǔ) Symbol類型的變量甜奄。

ReactElement.isValidElement函數(shù)用來(lái)判斷一個(gè) React組件是否是有效的∏钥睿可見(jiàn) React渲染時(shí)會(huì)把沒(méi)有 $$typeof標(biāo)識(shí)课兄,以及規(guī)則校驗(yàn)不通過(guò)的組件過(guò)濾掉。

當(dāng)你的環(huán)境不支持 Symbol時(shí)晨继, $$typeof被賦值為 0xeac7烟阐,至于為什么, React開發(fā)者給出了答案:

0xeac7看起來(lái)有點(diǎn)像 React紊扬。

12. React組件的渲染流程是什么蜒茄?

  • 使用 React.createElementJSX編寫 React組件,實(shí)際上所有的 JSX代碼最后都會(huì)轉(zhuǎn)換成 React.createElement(...)餐屎, Babel幫助我們完成了這個(gè)轉(zhuǎn)換的過(guò)程檀葛。

  • createElement函數(shù)對(duì) keyref等特殊的 props進(jìn)行處理,并獲取 defaultProps對(duì)默認(rèn) props進(jìn)行賦值腹缩,并且對(duì)傳入的孩子節(jié)點(diǎn)進(jìn)行處理屿聋,最終構(gòu)造成一個(gè) ReactElement對(duì)象(所謂的虛擬 DOM)。

  • ReactDOM.render將生成好的虛擬 DOM渲染到指定容器上藏鹊,其中采用了批處理润讥、事務(wù)等機(jī)制并且對(duì)特定瀏覽器進(jìn)行了性能優(yōu)化,最終轉(zhuǎn)換為真實(shí) DOM盘寡。

13. 為什么代碼中一定要引入React楚殿?

JSX只是為 React.createElement(component,props,...children)方法提供的語(yǔ)法糖。

所有的 JSX代碼最后都會(huì)轉(zhuǎn)換成 React.createElement(...)宴抚, Babel幫助我們完成了這個(gè)轉(zhuǎn)換的過(guò)程勒魔。

所以使用了 JSX的代碼都必須引入 React甫煞。

14. 為什么React組件首字母必須大寫菇曲?

babel在編譯時(shí)會(huì)判斷 JSX中組件的首字母冠绢,當(dāng)首字母為小寫時(shí),其被認(rèn)定為原生 DOM標(biāo)簽常潮, createElement的第一個(gè)變量被編譯為字符串弟胀;當(dāng)首字母為大寫時(shí),其被認(rèn)定為自定義組件喊式, createElement的第一個(gè)變量被編譯為對(duì)象孵户;

15. React在渲染真實(shí)Dom時(shí)做了哪些性能優(yōu)化?

IE(8-11)Edge瀏覽器中岔留,一個(gè)一個(gè)插入無(wú)子孫的節(jié)點(diǎn)夏哭,效率要遠(yuǎn)高于插入一整個(gè)序列化完整的節(jié)點(diǎn)樹。

React通過(guò) lazyTree献联,在 IE(8-11)Edge中進(jìn)行單個(gè)節(jié)點(diǎn)依次渲染節(jié)點(diǎn)竖配,而在其他瀏覽器中則首先將整個(gè)大的 DOM結(jié)構(gòu)構(gòu)建好,然后再整體插入容器里逆。

并且进胯,在單獨(dú)渲染節(jié)點(diǎn)時(shí), React還考慮了 fragment等特殊節(jié)點(diǎn)原押,這些節(jié)點(diǎn)則不會(huì)一個(gè)一個(gè)插入渲染胁镐。

16. 什么是高階組件?如何實(shí)現(xiàn)诸衔?

高階組件可以看作 React對(duì)裝飾模式的一種實(shí)現(xiàn)盯漂,高階組件就是一個(gè)函數(shù),且該函數(shù)接受一個(gè)組件作為參數(shù)笨农,并返回一個(gè)新的組件宠能。

高階組件( HOC)是 React中的高級(jí)技術(shù),用來(lái)重用組件邏輯磁餐。但高階組件本身并不是 ReactAPI违崇。它只是一種模式,這種模式是由 React自身的組合性質(zhì)必然產(chǎn)生的诊霹。

function visible(WrappedComponent)  {

    return  class extends Component  {

        render()  {

            const  { visible,  ...props }  =  this.props;

            if  (visible ===  false)  return  null;

            return  <WrappedComponent  {...props}  />;

        }

    }

}

上面的代碼就是一個(gè) HOC的簡(jiǎn)單應(yīng)用羞延,函數(shù)接收一個(gè)組件作為參數(shù),并返回一個(gè)新組件脾还,新組建可以接收一個(gè) visible props伴箩,根據(jù) visible的值來(lái)判斷是否渲染Visible。

我們可以通過(guò)以下兩種方式實(shí)現(xiàn)高階組件:

17. 屬性代理

函數(shù)返回一個(gè)我們自己定義的組件鄙漏,然后在 render中返回要包裹的組件嗤谚,這樣我們就可以代理所有傳入的 props棺蛛,并且決定如何渲染,實(shí)際上 巩步,這種方式生成的高階組件就是原組件的父組件旁赊,上面的函數(shù) visible就是一個(gè) HOC屬性代理的實(shí)現(xiàn)方式。

    function proxyHOC(WrappedComponent)  {

        return  class extends Component  {

            render()  {

                return  <WrappedComponent  {...this.props}  />;

            }

        }

    }

對(duì)比原生組件增強(qiáng)的項(xiàng):

  • 可操作所有傳入的 props

  • 可操作組件的生命周期

  • 可操作組件的 static方法

  • 獲取 refs

18. 反向繼承

返回一個(gè)組件椅野,繼承原組件终畅,在 render中調(diào)用原組件的 render。由于繼承了原組件竟闪,能通過(guò)this訪問(wèn)到原組件的 生命周期离福、props、state炼蛤、render等妖爷,相比屬性代理它能操作更多的屬性。

    function inheritHOC(WrappedComponent)  {

        return  class extends WrappedComponent  {

            render()  {

                return super.render();

            }

        }

    }

對(duì)比原生組件增強(qiáng)的項(xiàng):

  • 可操作所有傳入的 props

  • 可操作組件的生命周期

  • 可操作組件的 static方法

  • 獲取 refs

  • 可操作 state

  • 可以渲染劫持

19. HOC在業(yè)務(wù)場(chǎng)景中有哪些實(shí)際應(yīng)用場(chǎng)景理朋?

HOC可以實(shí)現(xiàn)的功能:

  • 組合渲染

  • 條件渲染

  • 操作 props

  • 獲取 refs

  • 狀態(tài)管理

  • 操作 state

  • 渲染劫持

HOC在業(yè)務(wù)中的實(shí)際應(yīng)用場(chǎng)景:

  • 日志打點(diǎn)

  • 權(quán)限控制

  • 雙向綁定

  • 表單校驗(yàn)

20. 高階組件(HOC)和Mixin的異同點(diǎn)是什么絮识?

MixinHOC都可以用來(lái)解決 React的代碼復(fù)用問(wèn)題。

  • Mixin 可能會(huì)相互依賴暗挑,相互耦合笋除,不利于代碼維護(hù)

  • 不同的 Mixin中的方法可能會(huì)相互沖突

  • Mixin非常多時(shí),組件是可以感知到的炸裆,甚至還要為其做相關(guān)處理垃它,這樣會(huì)給代碼造成滾雪球式的復(fù)雜性

HOC的出現(xiàn)可以解決這些問(wèn)題:

  • 高階組件就是一個(gè)沒(méi)有副作用的純函數(shù),各個(gè)高階組件不會(huì)互相依賴耦合

  • 高階組件也有可能造成沖突烹看,但我們可以在遵守約定的情況下避免這些行為

  • 高階組件并不關(guān)心數(shù)據(jù)使用的方式和原因国拇,而被包裹的組件也不關(guān)心數(shù)據(jù)來(lái)自何處。高階組件的增加不會(huì)為原組件增加負(fù)擔(dān)

21. Hook有哪些優(yōu)勢(shì)惯殊?

  • 減少狀態(tài)邏輯復(fù)用的風(fēng)險(xiǎn)

HookMixin在用法上有一定的相似之處酱吝,但是 Mixin引入的邏輯和狀態(tài)是可以相互覆蓋的,而多個(gè) Hook之間互不影響土思,這讓我們不需要在把一部分精力放在防止避免邏輯復(fù)用的沖突上务热。在不遵守約定的情況下使用 HOC也有可能帶來(lái)一定沖突,比如 props覆蓋等等己儒,使用 Hook則可以避免這些問(wèn)題崎岂。

  • 避免地獄式嵌套

大量使用 HOC的情況下讓我們的代碼變得嵌套層級(jí)非常深,使用 HOC闪湾,我們可以實(shí)現(xiàn)扁平式的狀態(tài)邏輯復(fù)用冲甘,而避免了大量的組件嵌套。

  • 讓組件更容易理解

在使用 class組件構(gòu)建我們的程序時(shí),他們各自擁有自己的狀態(tài)江醇,業(yè)務(wù)邏輯的復(fù)雜使這些組件變得越來(lái)越龐大濒憋,各個(gè)生命周期中會(huì)調(diào)用越來(lái)越多的邏輯,越來(lái)越難以維護(hù)陶夜。使用 Hook凛驮,可以讓你更大限度的將公用邏輯抽離,將一個(gè)組件分割成更小的函數(shù)律适,而不是強(qiáng)制基于生命周期方法進(jìn)行分割辐烂。

  • 使用函數(shù)代替class

相比函數(shù)遏插,編寫一個(gè) class可能需要掌握更多的知識(shí)捂贿,需要注意的點(diǎn)也越多,比如 this指向胳嘲、綁定事件等等厂僧。另外,計(jì)算機(jī)理解一個(gè) class比理解一個(gè)函數(shù)更快了牛。Hooks讓你可以在 classes之外使用更多 React的新特性颜屠。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鹰祸,隨后出現(xiàn)的幾起案子甫窟,更是在濱河造成了極大的恐慌,老刑警劉巖蛙婴,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粗井,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡街图,警方通過(guò)查閱死者的電腦和手機(jī)浇衬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)餐济,“玉大人耘擂,你說(shuō)我怎么就攤上這事⌒跄罚” “怎么了醉冤?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)篙悯。 經(jīng)常有香客問(wèn)我蚁阳,道長(zhǎng),這世上最難降的妖魔是什么辕近? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上归粉,老公的妹妹穿的比我還像新娘椿疗。我一直安慰自己,他們只是感情好届榄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布悼枢。 她就那樣靜靜地躺著埠忘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪馒索。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天绰上,我揣著相機(jī)與錄音旨怠,去河邊找鬼。 笑死蜈块,一個(gè)胖子當(dāng)著我的面吹牛鉴腻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疯趟,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼拘哨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了信峻?” 一聲冷哼從身側(cè)響起倦青,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盹舞,沒(méi)想到半個(gè)月后产镐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡踢步,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年癣亚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片获印。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡述雾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情玻孟,我是刑警寧澤唆缴,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站黍翎,受9級(jí)特大地震影響面徽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜匣掸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一趟紊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碰酝,春花似錦霎匈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)造挽。三九已至碱璃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間饭入,已是汗流浹背嵌器。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谐丢,地道東北人爽航。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像乾忱,于是被迫代替她去往敵國(guó)和親讥珍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345