關(guān)于 react 那些小知識(shí)點(diǎn)兒

react.jpg
說(shuō)在前面

關(guān)于 react 的總結(jié)過(guò)去半年就一直碎碎念著要搞起來(lái)廓潜,各(wo)種(tai)原(lan)因(le)俊扭。心心念的東西終于要重新拿了起來(lái)了讽坏。希望這個(gè)總結(jié)歸納能對(duì)你的日常開(kāi)發(fā)或者跳槽面試有幫助哪怕只有那么一點(diǎn)點(diǎn)休偶,反正對(duì)我?guī)椭峭Υ蟀磐欤瑴毓识侣铮?/p>

廢話說(shuō)了一堆食零, 這個(gè)總結(jié)可能大概也許會(huì)以問(wèn)答的形式總結(jié)
希望你能各個(gè)擊破困乒,像闖關(guān)卡一樣一個(gè)一個(gè)過(guò)!開(kāi)始吧 贰谣!Let's go!

【1】react component有幾種寫(xiě)法顶燕?分別是什么?

① 函數(shù)式定義的無(wú)狀態(tài)組件(Stateless Functional)

  • 性能更高效冈爹、代碼更簡(jiǎn)潔
  • 沒(méi)有 state涌攻,也就是無(wú)狀態(tài)
  • 不需要管理/維護(hù) 組件的生命周期
  • 純函數(shù),相同的 props 會(huì)得到同樣的UI渲染結(jié)果
    function List (props) {
        return <div>我是一個(gè)函數(shù)式定義的react組件</div>
    }

ES5方式 React.createClass 定義的組件(該方式已經(jīng)被廢棄频伤,推薦使用①和③)
③ ES6 方式定義的組件(Class Components)

    class List extends React.Component {
        render() {
            return <div>我是一個(gè)es6方式定義的react組件</div>
        }
    }

官方文檔寫(xiě)的還是頗具神秘感的恳谎,先告訴我們①和③方式在 UI 渲染效果是一毛一樣的,但是'Classes have some additional features...' Class 這種方式比 Functional 這種方式多了些不一樣的地方憋肖。那么問(wèn)題來(lái)了因痛。多了哪些不一樣的呢? 不一樣的地方你可能也發(fā)現(xiàn)了岸更,有無(wú) state鸵膏,有無(wú)生命周期...等

【2】那什么時(shí)候該用 Stateless Functional 什么時(shí)候用 Class 呢?

推薦使用 Functional怎炊,能用 Functional 就用 Functional谭企,就醬。
多說(shuō)一句评肆。
Class 是用來(lái)創(chuàng)建包含狀態(tài)生命周期用戶交互的復(fù)雜組件债查,而當(dāng)組件只是用來(lái)純展示或者 props 傳遞渲染時(shí)(展示性),二話不說(shuō)請(qǐng)用 Stateless Functional 來(lái)快速創(chuàng)建組件瓜挽。

【3】無(wú)狀態(tài)組件(Stateless Functional)有哪些優(yōu)缺點(diǎn)
  • 優(yōu)點(diǎn)
  1. 語(yǔ)法/代碼更加簡(jiǎn)潔
  2. 占用內(nèi)存许锿ⅰ(沒(méi)有 props 等屬性), 首次 render 性能更好
  3. 不需要管理/維護(hù)組件的生命周期
  4. 純函數(shù),相同的 props 會(huì)得到同樣的 UI 渲染結(jié)果
  5. 單元測(cè)試更容易進(jìn)行久橙。因?yàn)檫壿嫸急灰瞥隽?view 層俄占,所以單元測(cè)試時(shí)不需要渲染任何東西管怠,可以專(zhuān)注于單個(gè)邏輯。
  • 缺點(diǎn)
  1. 無(wú)生命周期函數(shù)缸榄。對(duì)于一個(gè)函數(shù)而言應(yīng)該是談不上生命周期渤弛。當(dāng)然了,我們其實(shí)可以使用高階組件去實(shí)現(xiàn)生命周期碰凶。
  2. 沒(méi)有 this。在Stateless中 this 是 undefined 鹿驼。
【4】React.Component 綁定方法的幾種方法欲低?
    //第一種方法:構(gòu)造函數(shù)中綁定
    
    class List extends React.Component {
        constructor(props) {
            super(props)
            this.onClickList = this.onClickList.bind(this)
        }
        
        onClickList() {
            console.log('我被點(diǎn)了')
        }
        
        render() {
            return <div onClick={this.onClickList}>點(diǎn)我點(diǎn)我點(diǎn)我</div>
        }
        
    }
    
    //第二種方法: 在render()行內(nèi)事件使用bind來(lái)綁定
    
    class List extends React.Component {
        
        onClickList() {
            console.log('我被點(diǎn)了')
        }
        
        render() {
            return <div onClick={this.onClickList.bind(this)}>點(diǎn)我點(diǎn)我點(diǎn)我</div>
        }
        
    }
    
    //第三種方法: 使用箭頭函數(shù) => 
    
    class List extends React.Component {
        
        onClickList = () => {
            console.log('我被點(diǎn)了')
        }
        
        render() {
            return <div onClick={this.onClickList}>點(diǎn)我點(diǎn)我點(diǎn)我</div>
        }
        
    }
    
    //第四種,當(dāng)然畜晰,你要在render()行內(nèi)使用箭頭函數(shù)也行
    
    class List extends React.Component {
        
        onClickList() {
            console.log('我被點(diǎn)了')
        }
        
        render() {
            return <div onClick={() => this.onClickList()}>點(diǎn)我點(diǎn)我點(diǎn)我</div>
        }
        
    }

我日常開(kāi)發(fā)都比較喜歡用箭頭函數(shù)的方法砾莱,代碼量比第一種少??。當(dāng)然凄鼻,官方說(shuō)在 render 中創(chuàng)建函數(shù)(第二腊瑟,和第四種)可能會(huì)有性能問(wèn)題。但往往需要傳遞參數(shù)或者回調(diào)時(shí)块蚌,都得用到闰非。例如:

    <button onClick={this.handleClick.bind(this, id)} />
    <button onClick={() => this.handleClick(id)} />
【5】智能組件 vs 木偶組件 ?(容器組件 vs 展示組件)

Smart 組件 和 Dumb 組件對(duì)于開(kāi)發(fā)過(guò) react 項(xiàng)目的朋友來(lái)說(shuō)應(yīng)該不陌生了峭范。

Dumb 組件财松,聽(tīng)名字你就知道這種組件很傻很木,因?yàn)槟九冀M件只關(guān)心一件事情就是 —— 根據(jù) props 進(jìn)行渲染纱控。
Smart 組件就很聰明辆毡,它專(zhuān)門(mén)做數(shù)據(jù)相關(guān)的邏輯,和各路數(shù)據(jù)打交道甜害,ajax獲取數(shù)據(jù)舶掖,定義好數(shù)據(jù)操作的相關(guān)函數(shù),然后將這些數(shù)據(jù)尔店、函數(shù)直接傳遞給具體實(shí)現(xiàn)的組件(Dumb 組件)即可眨攘。所以根據(jù)是否需要高度的復(fù)用性,把組件劃分為 Dumb 和 Smart 組件嚣州。

小提示1:Smart 組件復(fù)用性不強(qiáng)甚至不需要復(fù)用期犬,Dumb 組件往往是復(fù)用性強(qiáng)的,但是Dumb 組件對(duì)于 Smart 組件的帶入性不要太強(qiáng)避诽,因?yàn)閹胩噙壿嫊?huì)導(dǎo)致復(fù)用性降低龟虎。二者選擇,設(shè)計(jì)組件時(shí)需要斟酌一下沙庐。

小提示2:Dumb 組件 的子組件也應(yīng)該是 Dumb 組件鲤妥。

小提示3:redux store 相關(guān)的應(yīng)該和 Smart 組件連接起來(lái) 佳吞。

關(guān)于React生命周期

關(guān)于生命周期,面試的時(shí)候總喜歡問(wèn)點(diǎn)兒react生命周期相關(guān)的棉安,而且想要了解別人寫(xiě)的 react 代碼底扳,深刻理解 react 生命周期也是很重要的。先不要往下看贡耽,閉上眼睛想想看你所了解的 react 生命周期有哪些衷模?

...

...

...

...

...

...

liftcycle.jpg

ok 你應(yīng)該想完了哈。是不是大概有下面這么一個(gè)流程蒲赂?(忽略圖片的渣像素??圖片是經(jīng)典的組件掛載圖來(lái)源于網(wǎng)絡(luò))

react 組件的生命周期方法都可以被分割成四個(gè)階段:初始化阱冶、掛載階段(Mounting)、更新階段(Updating)滥嘴、卸載階段(Unmounting)木蹬。

接下來(lái)就讓我們?nèi)タ纯瓷芷诙加心男┬≈R(shí)點(diǎn)。

【6】Mounting -- 下面這些方法將會(huì)在 component 實(shí)例被創(chuàng)建和插入到DOM后調(diào)用若皱。
  • constructor()
  • componentWillMount()
  • render()
  • componentDidMount()
【7】Updating -- props 或者 state 的變化都會(huì)導(dǎo)致更新镊叁。下面這些方法會(huì)在 component 重新渲染時(shí)調(diào)用。
  • componentWillReceiveProps()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • render()
  • componentDidUpdate()
【8】Unmounting -- 該方法將會(huì)在 component 從DOM中移除時(shí)調(diào)用走触。
  • componentWillUnmount()

接下來(lái)簡(jiǎn)單的介紹一下幾個(gè)生命周期晦譬。

【9】1. componentWillMount

componentWillMount() 是在組件掛載(mount)之前被調(diào)用.
componentWillMount()是唯一一個(gè)在服務(wù)器端渲染(ssr)調(diào)用的生命周期鉤子

關(guān)于 setState 在 componentWillMount 使用:可以使用。因?yàn)樗?render 方法之前被調(diào)用互广,因此 setState 也不會(huì)導(dǎo)致重繪(re-render)

【10】2. componentDidMount

componentDidMount() 在組件掛載之后立即執(zhí)行

在這個(gè)鉤子里合適:

  • ajax 請(qǐng)求
  • 初始化DOM節(jié)點(diǎn)的操作
  • 設(shè)置計(jì)時(shí)器 setTimeout 或者 setInterval (溫馨提示蛔添,別忘了在 componentWillUnmount 關(guān)閉這些計(jì)時(shí)器)

關(guān)于 setState 在 componentDidMount 使用: 可以使用。但是經(jīng)常導(dǎo)致性能問(wèn)題兜辞。當(dāng)然非要在 render 前拿到 DOM 節(jié)點(diǎn)的大小和位置迎瞧,是可以用的。

插曲逸吵。面試題:ajax 請(qǐng)求應(yīng)該在哪個(gè)生命周期凶硅?為什么?

【11】3. componentWillReceiveProps(nextProps)

componentWillReceiveProps 將會(huì)在已掛載組件(mounted component)接收到新的 props 之前調(diào)用扫皱。所以初始化 props 的mount不會(huì)觸發(fā)這個(gè)函數(shù)足绅。直接 setState不會(huì)觸發(fā)這個(gè)函數(shù)。

在這個(gè)鉤子里合適:

  • 更新 state 的值(比如重置)
  • 比較 this.props 和 nextProps

特別特別特別要注意的是韩脑,當(dāng)父組件導(dǎo)致該組件 re-render 時(shí)氢妈,即便 props 沒(méi)有發(fā)生任何的改變,react 也有可能執(zhí)行該鉤子函數(shù)段多。所以呢首量,所以就是如果你想要真正處理 props 的變化,要記得比較當(dāng)前 props 和 nextProps.

關(guān)于setState在componentWillReceiveProps使用: 可以使用

【12】4. shouldComponentUpdate(nextProps, nextState)

當(dāng)改變state 或者 props 并且是在render之前會(huì)調(diào)用shouldComponentUpdate加缘,說(shuō)白了就是該鉤子函數(shù)用于告訴 React 組件是否需要重新渲染鸭叙。

shouldComponentUpdate 默認(rèn)return true,如果return false componentWillUpdate拣宏、render沈贝、componentDidUpdate都將不會(huì)被調(diào)用。千萬(wàn)記住一點(diǎn)勋乾, 當(dāng)return false時(shí)宋下,當(dāng)他們的 state 發(fā)生改變時(shí),并不會(huì)阻止子組件(child component)進(jìn)行重新渲染辑莫。

shouldComponentUpdate在兩種情況下不會(huì)被調(diào)用:

  • 組件初始化
  • 使用forceUpdate的情況

大家應(yīng)該都是 shouldComponentUpdate 還有一個(gè)知識(shí)點(diǎn)就是和 react 組件性能優(yōu)化相關(guān)的学歧。是的。你可以this.state 和 nextState摆昧、this.props 和 nextProps 做比較來(lái)決定出 return false 并告訴 react 可以不更新該組件撩满。如果做的只是一些淺層的數(shù)據(jù)比較完全可以用 PureComponent 來(lái)代替(深層的嵌套數(shù)據(jù)PureComponent也無(wú)能為力)

react 不建議在 shouldComponentUpdate 做深層的對(duì)比或者用 JSON.stringify()蜒程,因?yàn)檫@樣反而損害到性能绅你。

【13】5. componentWillUpdate(nextProps, nextState)

state 或者 props 更新后 re-render 之前調(diào)用。

注意:不要在componentWillUpdate 使用 this.setState, 或者 redux 分發(fā)一個(gè)action(dispatch a Redux action)昭躺,因?yàn)樵?componentWillUpdate 之前會(huì)觸發(fā)組件的更新忌锯。 如果非要在做以上操作的話,可以在componentWillReceiveProps 哦

【14】6. componentDidUpdate(prevProps, prevState)

在組件更新之后馬上調(diào)用 componentDidUpdate领炫。

在這個(gè)鉤子函數(shù)中你可以:

  • 操作 DOM
  • 發(fā)起網(wǎng)絡(luò)請(qǐng)求
【15】7. componentWillUnmount

在組件卸載(unmounted)和銷(xiāo)毀(destroyed)前調(diào)用偶垮。

在componentWillUnmount你可以執(zhí)行任何需要清除的方法。比如:

  • 清除計(jì)時(shí)器
  • 斷開(kāi)網(wǎng)絡(luò)請(qǐng)求
  • 解綁dom事件
  • 等等
【16】生命周期table
生命周期 是否可以調(diào)用this.setState 初始化是否執(zhí)行
componentWillMount 可以
componentDidMount 可以
componentWillReceiveProps 可以
shouldComponentUpdate 不可以
componentWillUpdate 不可以
componentDidUpdate 可以
componentWillUnmount 不可以

特別特別特別注意:
①componentWillMount 和 componentWillReceiveProps 調(diào)用 setState 不會(huì)重復(fù)渲染(re-render)
②componentDidUpdate帝洪,不能直接 this.setState, 不然會(huì)溢出棧似舵。需要對(duì) prevProps 與 this.props 和 prevState 和 this.state 做一個(gè)判斷再執(zhí)行 this.setState。就類(lèi)似while循環(huán)不能陷入死循環(huán)葱峡。

好吧砚哗。長(zhǎng)篇大論了一番 react 的生命周期。不為什么砰奕,就因?yàn)樗浅5闹匾虢妗2还苁菍?duì)你的面試或者日常開(kāi)發(fā)或者閱讀理解別人的代碼都是非常重要。哪個(gè)階段會(huì)觸發(fā)哪個(gè)生命周期军援,哪個(gè)能干什么哪個(gè)不能干什么仅淑,哪個(gè)更合適哪個(gè)不合適。來(lái)胸哥!干了它涯竟,咱們?cè)倮^續(xù)往下看!

......
.....
....
...
..
.
感謝你能看到這里,咱們繼續(xù)往下鑿....
.
..
...
....
.....
......

【17】props 和 state 的區(qū)別
  1. "props"是別人的, props實(shí)現(xiàn)組件間的狀態(tài)傳遞昆禽,props從父組件到子組建的數(shù)據(jù)傳遞蝗蛙;"state"是自己的,state只能定義在組件內(nèi)部醉鳖,定義組件的自己的狀態(tài)捡硅。
  2. props 是不可變的; state 可以通過(guò)this.setState改變
【18】props vs state
? props state
可以從父組件獲得初始值嗎盗棵? Yes Yes
可以被父組件改變嗎壮韭? Yes No
內(nèi)部(當(dāng)前)組件可以設(shè)置默認(rèn)值嗎? Yes Yes
可以改變內(nèi)部(當(dāng)前)組件嗎纹因? No Yes
可以為子組件設(shè)置初始值嗎喷屋? Yes Yes
可以改變子組件嗎? Yes No
【19】jsx是什么瞭恰?

剛接觸 react 的童鞋屯曹,看到 jsx,第一反應(yīng)就是“丑”。說(shuō)實(shí)在的一開(kāi)始寫(xiě) jsx 我也是拒絕的记某,但是沒(méi)想到 jsx 其語(yǔ)法和背后的邏輯讓構(gòu)建react組件變得極其簡(jiǎn)單衅鹿。
那 jsx 到底是什么呢?jsx 是一個(gè)看起來(lái)很像 XML 的 JavaScript 語(yǔ)法擴(kuò)展偷俭。說(shuō)白了 jsx 并不是什么高深的技術(shù),可以說(shuō)只是一個(gè)比較高級(jí)但很直觀的語(yǔ)法糖缰盏。它非常有用涌萤,卻不是一個(gè)必需品,沒(méi)有 jsx 的 React 也可以正常工作:只要你樂(lè)意用 JavaScript 代碼去創(chuàng)建這些虛擬 DOM 元素(但是真的超級(jí)麻煩)口猜。

jsx優(yōu)點(diǎn):

  • 執(zhí)行更快负溪,因?yàn)樗诰幾g為 JavaScript 代碼后進(jìn)行了優(yōu)化
  • 它是類(lèi)型安全的,在編譯過(guò)程中就能發(fā)現(xiàn)錯(cuò)誤
  • 編寫(xiě)模板更加簡(jiǎn)單快速
  • 更加直觀济炎,可讀性高

來(lái)看看以下代碼:
1.當(dāng)我們用HTML描述一個(gè)按鈕的時(shí)候川抡,你會(huì)發(fā)現(xiàn)一個(gè) DOM 元素包含的信息其實(shí)只有三個(gè):標(biāo)簽名,屬性冻辩,子元素猖腕。

    <div id="btn-wrap">
        <button class="btn">click</button>
    </div>

2.我們?nèi)绻胘s描述,可以通過(guò)JSON對(duì)象恨闪,且依然包括元素的標(biāo)簽名倘感、屬性,子元素

    {
        type: 'div',
        props: { id: 'btn-wrap' },
        children: {
            type: 'button',
            props: { className: 'btn' },
            children: 'click'
        }
    }

仔細(xì)觀察咙咽,你會(huì)發(fā)現(xiàn)HTML和js描述一個(gè)按鈕他們所對(duì)應(yīng)的結(jié)構(gòu)簡(jiǎn)直是一毛一樣的老玛,就是說(shuō)一個(gè)html構(gòu)建的UI界面我們完全可以用js來(lái)描述。你會(huì)發(fā)現(xiàn)HTML書(shū)寫(xiě)一個(gè)按鈕遠(yuǎn)比js書(shū)寫(xiě)方式來(lái)得蘇胡,而且結(jié)構(gòu)更加清晰蜡豹。但是如果 你堅(jiān)決要用js來(lái)寫(xiě)我也不會(huì)反對(duì)的麸粮。來(lái)!先寫(xiě)個(gè)div十層嵌套試試镜廉?

react提供jsx語(yǔ)法糖弄诲,將html語(yǔ)法直接加入到JavaScript代碼中去,再通過(guò)編譯器(babel)轉(zhuǎn)化為JavaScript后由瀏覽器執(zhí)行娇唯。

我們修改src/index.js的代碼如下

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class HappyReact extends Component {
  render() {
    return (
        <div>
            <h1 id="title">happy react !</h1>
        </div>
    )
  }
}

ReactDOM.render(<HappyReact />, document.getElementById('root'));

這時(shí)候你會(huì)看到頁(yè)面瀏覽器自動(dòng)刷新了且頁(yè)面顯示了'happy react !'字樣齐遵。

如果以上代碼經(jīng)過(guò)編譯會(huì)變成:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class HappyReact extends Component {
  render() {
    return (
      React.createElement(
        'div',
        null,
        React.createElement(
            'h1',
            { id: 'title' },
            'happy react !'
        )
      )
    )
  }
}

ReactDOM.render(
    React.createElement(
        HappyReact,
        null
    ),
    document.getElementById('root')
);

編譯前后兩段代碼渲染結(jié)果是一樣的,你一定發(fā)現(xiàn)了jsx的代碼更加直觀便于維護(hù)了吧塔插!

雖然你看到的html寫(xiě)在了js代碼中梗摇,但是你永遠(yuǎn)要記住"jsx最終其實(shí)就是JavaScript對(duì)象"。react通這個(gè)對(duì)象來(lái)創(chuàng)建或者更新虛擬元素最終來(lái)管理virtual DOM(虛擬DOM)

jsx對(duì)象元素可以理解為和真實(shí)元素一一對(duì)應(yīng)的想许,它的創(chuàng)建伶授、更新、刪除都是在內(nèi)存中完成的流纹。并不會(huì)直接渲染到真實(shí)DOM中去糜烹,整個(gè)react應(yīng)用程序唯一操作到DOM就是:

    ReactDOM.render(<HappyReact />, document.getElementById('root'));
【20】大概知道jsx是什么了。我們是得花點(diǎn)兒時(shí)間學(xué)習(xí)/了解/回憶一下jsx的寫(xiě)法捧颅。
  1. render函數(shù)只能return一個(gè)根節(jié)點(diǎn)景图,只允許被一個(gè)標(biāo)簽包裹
  2. Component 命名首字大寫(xiě)较雕,HTML 標(biāo)簽用小寫(xiě)
  3. 如果不存在子節(jié)點(diǎn)碉哑,可以使用自閉合 <div />
  4. jsx的注釋 {/* */}
  5. JavaScript 屬性表達(dá)式,屬性值用 {}
  6. 三元表達(dá)式
  7. 數(shù)組遞歸(渲染列表) map
  8. 兩個(gè)特殊屬性 class, for. 因?yàn)閏lass, for在JavaScript中這個(gè)兩個(gè)單詞都是關(guān)鍵詞亮蒋。因此需要做一手轉(zhuǎn)換扣典。其他屬性可以像寫(xiě)html一樣添加上去。
  9. jsx書(shū)寫(xiě)樣式
  10. 事件處理慎玖,使用inline方式的駝峰式寫(xiě)法贮尖,例如onClick、onChange
  11. HTML轉(zhuǎn)義 --> dangerouslySetInnerHTML={{__html: '<div>hhh</div>'}}
  12. 利用es6 中 ... 展開(kāi)運(yùn)算符趁怔。例如
    const helloProps = {
        value: 'hello',
        show: true,
    }
 <HelloWorld ...helloProps />
  1. 如果屬性值是true 這里直接寫(xiě)屬性名湿硝。例如
    <Button disabled={true} /> 
    可以寫(xiě)成
    <Button disabled /> 
  1. false, null, undefined, true 是有效的子內(nèi)容,但是不會(huì)被渲染出來(lái)润努。以下表達(dá)式渲染結(jié)果是一樣的:
    <div />
    <div></div>
    <div>{false}</div>
    <div>{null}</div>
    <div>{undefined}</div>
    <div>{true}</div>

15 ...

...好吧我可能暫時(shí)想到這么多了关斜。

【21】refs 是什么?(refs功能铺浇,如何實(shí)現(xiàn)痢畜?)

react 提供了一種特殊屬性, 允許您直接訪問(wèn)DOM元素或組件實(shí)例。
ref 可以返回一個(gè)字符串(string) 或者 一個(gè)回調(diào)函數(shù)(cb)丁稀,這個(gè)回調(diào)函數(shù)會(huì)在組件實(shí)例化或者銷(xiāo)毀之后立即執(zhí)行吼拥。

字符串refs在未來(lái)的版本中可能被移除,所以推薦回調(diào)的方式來(lái)代替线衫。

    class TextInput extends Component {
        componentDidMount() {
            this.textInput.focus()
        }
        
        render() {
            return (
                <input ref={(input) => this.textInpuf = input} />
            )
        }
    }

官方推薦幾種很好的方式使用refs:

  • 管理焦點(diǎn)凿可,文本選擇或者媒體播放
  • 觸發(fā)重要的動(dòng)畫(huà)
  • 整合第三方DOM庫(kù)

當(dāng)然能不用refs就盡量不要用refs,不要太過(guò)度依賴(lài)refs來(lái)解決問(wèn)題授账。

【22】什么是受控組件和什么是非受控組件

在react表單組件可被分為兩類(lèi):受控組件 和 非受控組件矿酵。

  • 受控組件
    我們簡(jiǎn)單的理解,設(shè)置了 value 的 <input>(表單標(biāo)簽) 是一個(gè)受控組件矗积。
    當(dāng)我們?cè)O(shè)置了value為"hi"(某個(gè)值)時(shí)全肮,且在頁(yè)面上渲染出改值時(shí),我們?cè)阡秩境鰜?lái)的元素里輸入任何值都不起作用棘捣。因?yàn)閞eact 已經(jīng)把value賦值為"hi"辜腺。 要想改變value值,還必須配合這onChange 和 setState 來(lái)實(shí)現(xiàn)乍恐。

當(dāng)然你也可以看看官網(wǎng)文檔來(lái)如何定義受控組件的评疗。

在 HTML 中,表單元素如 <input>茵烈,<textarea> 和 <select> 表單元素通常保持自己的狀態(tài)百匆,并根據(jù)用戶輸入進(jìn)行更新。而在 React 中呜投,可變狀態(tài)一般保存在組件的 state(狀態(tài)) 屬性中加匈,并且只能通過(guò) setState() 更新。

我們可以通過(guò)使 React 的 state 成為 “單一數(shù)據(jù)源原則” 來(lái)結(jié)合這兩個(gè)形式仑荐。然后渲染表單的 React 組件也可以控制在用戶輸入之后的行為雕拼。這種形式,其值由 React 控制的輸入表單元素稱(chēng)為“受控組件”粘招。

話不多說(shuō)啥寇,來(lái)呀,上代碼:

    class App extends Component {
        constructor(props) {
            super(props)
            this.state = { value: 'hi' }
        }
        
        onInputChange = (e) => {
            this.setState({ value: e.target.value })
        }
        
        render() {
            const { value } = this.state
            return (
                <input value={value} onChange={this.onInputChange} />
            )
        }
    }

React官方推薦使用受控表單組件洒扎〖穑總結(jié)一下上面受控組件代碼更新是state的流程:

  1. 初始化state設(shè)置表單的默認(rèn)值,例如 this.state = { value: 'hi' }
  2. 每當(dāng)表單值發(fā)生變化時(shí)袍冷,調(diào)用onChange事件
  3. 通過(guò)對(duì)象e拿到改變的狀態(tài)磷醋,例如e.target.value
  4. 通過(guò)setState更新應(yīng)用value 并 觸發(fā)視圖重新渲染,最終完成表單組件的更新
    // 第四步 setState 我們還可以對(duì)表單值進(jìn)行直接修改或者驗(yàn)證
    // 受控組件支持即時(shí)字段驗(yàn)證难裆,允許您有條件地禁用/啟用按鈕子檀,強(qiáng)制輸入格式
    onInputChange = (e) => {
        this.setState({ value: e.target.value.substring(0, 140).toUpperCase() })
    }

特別特的注意D饕础!9犹怠亩进! 如果 value 為 undefined,則變成了非受控組件缩歪。

  • 非受控組件
    理解了受控組件归薛,那你一定知道非受控組件就是沒(méi)有value(單選/復(fù)選按鈕為 checked)屬性的表單組件》蓑可以通過(guò)設(shè)置 defalutValue / defalutChecked 來(lái)設(shè)置組件初始值主籍。

多啰嗦一句,defalutValue / defalutChecked逛球,僅僅會(huì)被渲染一次千元,在后續(xù)渲染并不起作用。

因?yàn)椴皇躶tate / props控制颤绕,我們需要為其添加 ref 來(lái)訪問(wèn)渲染后的DOM元素幸海,才能最終拿到改變后的value/checked。還記得refs那句話怎么說(shuō)來(lái)著:“能不用refs就盡量不要用refs”奥务。so react官方還是比較推薦使用受控組件物独。

......
.....
....
...
..
.
看累了,我們留一點(diǎn)兒明天再來(lái)嘛氯葬。挡篓。。
.
..
...
....
.....
......

關(guān)于setState

setState 對(duì)于每一個(gè)使用過(guò)react的盆友來(lái)說(shuō)應(yīng)該并不陌生帚称。與之還能立刻聯(lián)想出來(lái)幾個(gè)詞 “更改state” “異步” “重新渲染”...

來(lái)一個(gè)道題練練手官研?雖然平時(shí)不會(huì)寫(xiě)這么*的代碼,但誰(shuí)知道面試會(huì)不會(huì)出現(xiàn)呢世杀? 歡迎寫(xiě)下你的答案阀参!

    ...
    this.state = { count : 0 }
    ...
    componentDidMount() {
        this.setState({ count: this.state.count + 1 }, () => {
            console.log(`apple...${this.state.count}`)
        })
        
        console.log(`orange...${this.state.count}`)
        
        setTimeout(() => {
            console.log(`lemen...${this.state.count}`)

            this.setState({ count: this.state.count + 1 }, () => {
                console.log(`banana...${this.state.count}`)
            })
            
            setTimeout(() => {
                console.log(`grape...${this.state.count}`)
            }, 0)
            
            this.setState({ count: this.state.count + 1 }, () => {
                console.log(`strawberry...${this.state.count}`)
            })
            
            console.log(`pear...${this.state.count}`)
        }, 0)
    }
【23】官方是這么定義setState

setState() 排隊(duì)更改組件的 state 肝集,并通過(guò)更新 state 來(lái)告訴 React 瞻坝,該組件及其子組件需要重新渲染。這是用于 響應(yīng)事件處理程序服務(wù)器響應(yīng) 更新用戶界面的主要方法杏瞻。

我記得我剛學(xué)習(xí)react的時(shí)候所刀,文檔上還沒(méi)有明確說(shuō)調(diào)用setState是異步的,只是說(shuō)了“不保證是同步的”捞挥。但最近去看了官方文檔浮创,文檔說(shuō)調(diào)用setState是異步的了。

【24】調(diào)用setState()實(shí)際上發(fā)生了什么砌函?

簡(jiǎn)單的說(shuō)斩披,就是 更改state溜族、更新UI
復(fù)雜的說(shuō),就是 怎么合并新的state垦沉,怎么根據(jù)新state來(lái)更新UI

【25】setState()第二個(gè)參數(shù)是什么煌抒?它有什么作用?

setState的第二個(gè)參數(shù)是一個(gè)可選的回調(diào)函數(shù)厕倍。這個(gè)回調(diào)函數(shù)將在 setState 完成后執(zhí)行寡壮,并且重新渲染組件。在這個(gè)回調(diào)函數(shù)中你可以拿到剛更新的state的值讹弯。但是這樣的邏輯 官方推薦 使用 componentDidUpdate况既。

【26】如何在 setState 后直接獲取修改后的值
  1. setState 第二個(gè)參數(shù),回調(diào)函數(shù)中獲取
  2. 使用setTimeout
    setTimeout(() => {
        this.setState({ value: 'hhh' })
        
        console.log(this.state.value) // hhh
    }, 0)
    // 看到這里最開(kāi)始的那道練手題组民,是不是已經(jīng)可以迎刃而解了棒仍。哈哈哈哈哈
【27】setState 第一個(gè)參數(shù)有兩種傳遞方式 1.一個(gè)對(duì)象 2. 一個(gè)函數(shù) 這兩種寫(xiě)法有什么區(qū)別呢?

舉個(gè)例子

    ...
    this.state = { text : '這是一個(gè)栗子' }
    ...

    // 使用傳遞對(duì)象的寫(xiě)法
    handleClick = () => {
        this.setState({ text: this.state.text + '111' })
        this.setState({ text: this.state.text + '222' })
    }
    
    // 使用傳遞函數(shù)的寫(xiě)法
    handleClick = () => {
        this.setState((prevState) => {
            return { text: prevState.text + '111' }
        })
        this.setState((prevState) => {
            return { text: prevState.text + '222' }
        })
    }

    render() {
        return <div onClick={this.handleClick}>{this.state.text}</div>
    }

兩種傳遞方式臭胜,得到的結(jié)果是不一樣的降狠。

  • 傳遞對(duì)象 => this.state.text => '這是一個(gè)栗子222'
  • 傳遞函數(shù) => this.state.text => '這是一個(gè)栗子111222'

setState為了提升性能,在批量執(zhí)行 state 改變?cè)谧鼋y(tǒng)一的DOM渲染庇楞。而在這個(gè)批量執(zhí)行的過(guò)程中榜配,如果你多次傳遞的是一堆對(duì)象,它就會(huì)做一些對(duì)象合并或者組合的操作吕晌,例如Object.assign({}, { a: '111' }, { a: '222' })蛋褥。如果key值一樣的話,后面的值會(huì)覆蓋掉前面的值睛驳。
但多次傳遞函數(shù)方式烙心,每次 React 從 setState 執(zhí)行函數(shù),并通過(guò)傳遞已更新的狀態(tài)來(lái)更新你的狀態(tài)乏沸。這使得功能 setState 可以基于先前狀態(tài)設(shè)置狀態(tài)淫茵。

使用setState要注意!5旁尽匙瘪!

  1. setState可能會(huì)引發(fā)不必要的渲染 (shouldComponentUpdate/PureComponent)
  2. setState無(wú)法完全掌控應(yīng)用中所有組件的狀態(tài)(Redux/Mbox)
【28】 什么是高階組件,它是如何使用蝶缀?

高階組件它是一個(gè)函數(shù)丹喻。高階組件它是一個(gè)函數(shù)。高階組件它是一個(gè)函數(shù)翁都。并不是一個(gè)組件碍论。通俗的講就是它接收一個(gè)React組件作為輸入,輸出一個(gè)新的增強(qiáng)版的React組件柄慰。

舉一個(gè)可能不太恰當(dāng)?shù)睦喻⒂疲蠹铱赡芏纪嫱跽咿r(nóng)藥税娜,打藍(lán)爸爸或者紅爸爸就是對(duì)英雄自身的一個(gè)增強(qiáng)版。吃了藍(lán)爸爸并不會(huì)影響你吃紅爸爸藏研,也不會(huì)影響你買(mǎi)了什么裝備等等巧涧。

好了,那么我們定義一個(gè)最最最簡(jiǎn)單的高階組件

    const MyContainer = (WrappedComponent) => {
        return class NewComponent extend Component {
            render() {
                return <WrappedComponent />
            }
        }
    }

將你的組件類(lèi)作為參數(shù)傳入高階組件這個(gè)函數(shù)即可

    class Welcome extends Component {
        ...
    }
    
    export default MyContainer(Welcome)

或者使用ES7的裝飾器

    @MyContainer
    class Welcome extends Component {
        ...
    }
    export default Welcome

關(guān)于裝飾器在create-react-app中的配置:

  1. npm run eject
  2. npm install --save-dev plugin-transform-decorators-legacy
  3. 在package.json中找到"babel"項(xiàng)遥倦,添加 "plugins": ["transform-decorators-legacy"]

在代碼優(yōu)化(抽離公共邏輯)或者組件解耦的時(shí)候我們可以考慮一下使用高階組件谤绳,這樣有助于提高我們代碼的靈活性,邏輯的復(fù)用性袒哥。

【29】什么是PureComponent缩筛? 介紹一下PureComponent和shouldComponentUpdate有什么區(qū)別?

PureComponent 和 Component是相同堡称,只要把繼承類(lèi)從 Component 換成 PureComponent 即可瞎抛。PureComponent改變了shouldComponentUpdate,它會(huì)自動(dòng)檢查組件是否重新渲染却紧。也就是說(shuō)桐臊,只有當(dāng)PureComponent檢查到props或者state變化時(shí),才會(huì)調(diào)用render函數(shù)晓殊,因此不用寫(xiě)額外的檢查断凶。還可以減少 Virtual DOM 的生成和比對(duì)過(guò)程,達(dá)到提升性能的目的巫俺。

注意:PureComponent 的 shouldComponentUpdate 只是進(jìn)行了淺比較(state认烁,props對(duì)象結(jié)構(gòu)簡(jiǎn)單,可以理解為對(duì)象只有一層)介汹,對(duì)于復(fù)雜且嵌套更深層數(shù)據(jù)的比較會(huì)出現(xiàn)偏差却嗡。對(duì)于深比較,你可以選擇在 shouldComponentUpdate 進(jìn)行深比較檢查來(lái)確定組件是否渲染嘹承,但是你要知道 深比較 是非常昂貴的窗价。 當(dāng)然,你可能知道 使用 Immutable 來(lái)幫助嵌套數(shù)據(jù)的快速比較叹卷。

【30】shouldComponentUpdate 的作用以及它的重要性?

shouldComponentUpdate 允許我們手動(dòng)地判斷是否要進(jìn)行組件更新撼港,根據(jù)組件的應(yīng)用場(chǎng)景設(shè)置函數(shù)的合理返回值能夠幫我們避免不必要的更新。

【31】為什么我們利用循環(huán)產(chǎn)生的組件中要用上key這個(gè)特殊的prop豪娜?
    // list = [{ id: 0, name: 'xiaoming', age: 18 }, { id: 1, name: 'xiaohong', age: 16 }]
    render() {
        return (
            <ul>
                list.map((item, index) => {
                    return <li key={item.id}>{item.name} - {item.age}</li>
                })
            </ul>
        )
    }

如果你沒(méi)添加上 key 屬性的話餐胀,會(huì)報(bào)一個(gè)警告: Warning: Each child in an array or iterator should have a unique "key" prop...

keys 是 React 用于追蹤哪些列表中元素被修改被添加或者被移除的輔助標(biāo)識(shí)
之所以需要key瘤载,因?yàn)閞eact 是非常高效的,它會(huì)借助元素的 key 值來(lái)判斷該元素是新創(chuàng)建的卖擅,或者移動(dòng)(交換位置)而來(lái)的鸣奔,從而減少不必要的元素重渲染墨技。更直觀一點(diǎn)兒就是 react 很懶,能復(fù)用的元素就復(fù)用挎狸,他不想重新創(chuàng)建新的元素扣汪。

那么,如果上面代碼 key={index} 呢锨匆?你會(huì)發(fā)現(xiàn)也不會(huì)有warning崭别,但是這樣做的效率是非常非常非常低的。

看看以下例子:

    // list = [a, b, c, d]
    <div>
        list.map((item, index) => <div key={index}>{item}</div>)
    </div>

渲染完成后我們abcd 分別對(duì)應(yīng)的是 0123恐锣。

    a -> 0
    b -> 1
    c -> 2
    d -> 3

假設(shè)我們只是將d的位置換到了首位 list = [d, a, b, c]

    a -> 1
    b -> 2
    c -> 3
    d -> 0

變換前和變換后茅主,你應(yīng)該發(fā)現(xiàn)了abcd所對(duì)應(yīng)的key都改變了,這樣react Virtual DOM就不論有沒(méi)有相同的項(xiàng)土榴,更新都會(huì)重新渲染了诀姚。所以我們要保證某個(gè)元素的 key 在其同級(jí)元素中具有唯一性,這個(gè)key 的值可以直接后臺(tái)數(shù)據(jù)返回的 id玷禽,因?yàn)楹笈_(tái)的 id 都是唯一的赫段。

記住實(shí)際開(kāi)發(fā)中,就別再直接用循環(huán)計(jì)數(shù)器 index 了矢赁,那就有點(diǎn)兒騙自己了哈糯笙。剛用react我也老用index...

react組件間的通信

組件之間的通信也是老生常談了。不僅在實(shí)際開(kāi)發(fā)中撩银,面試時(shí)估計(jì)也經(jīng)常被提及炬丸。

組件之間的通信大概可分為這么幾種:

  1. 父組件向子組件通信
  2. 子組件向父組件通信
  3. 兄弟組件之間通信
【32】父組件向子組件通信

在 react 中數(shù)據(jù)是單向傳遞的,父組件可以向子組件通過(guò)傳 props 的方式蜒蕾,子組件拿到 props 之后做相應(yīng)的處理稠炬,這就是父組件向子組件進(jìn)行通信方式。

    class Parent extends Component {
    
        constructor(props) {
            super(props)
            this.state = { wishes: '2018新年快樂(lè)咪啡!' }
        }
        
        render() {
            return (
                <Child title={this.state.wishes} />
            )
        }
    }
    
    class Child extends Component {
        
        render() {
            return (
                <h3>{this.props.title}</h3>
            )
        }
    }
【33】子組件向父組件通信

子組件向父組件傳遞數(shù)據(jù)(通信) 也是要通過(guò) props 傳遞一個(gè)函數(shù)首启,子組件調(diào)用這個(gè)函數(shù),并將子組件需要傳遞的數(shù)據(jù)作為參數(shù)撤摸,傳遞給父組件毅桃。

    class Parent extends Component {
    
        constructor(props) {
            super(props)
            this.state = { wishes: '2018新年快樂(lè)!' }
        }
    
        onSend = (msg) => {
            this.setState({ wishes: msg })
        }
        
        render() {
            return (
                <Child onSend={this.onSend} title={this.state.wishes} />
            )
        }
    }
    
    class Child extends Component {
    
        onChildSend = () => {
            this.props.onSend('謝謝你的祝福准夷!')
        }
        
        render() {
            return (
                <h3 onClick={this.onChildSend}>{this.props.title}</h3>
            )
        }
    }
【34】兄弟組件之間通信

兩個(gè)兄弟組件之間的數(shù)據(jù)傳遞钥飞,我們可以通過(guò)他們的共同父組件來(lái)實(shí)現(xiàn)。Child1 將要傳遞的信息傳遞給 Parent 然后 Parent 再將從 Child1 拿到的信息傳遞給 Child2 當(dāng)然衫嵌,我們同樣是利用 props读宙。

我們來(lái)寫(xiě)一段點(diǎn)擊 Child1,然后將 Child1 想傳遞給 Child2 的信息發(fā)送到 Child2 中楔绞。

    class Parent extends Component {
    
        constructor(props) {
            super(props)
            this.state = { wishes: '' }
        }
    
        onSend = (msg) => {
            this.setState({ wishes: msg })
        }
        
        render() {
            return (
              <div>
                <Child1 onSend={this.onSend} />
                <Child2 fromChild1Wishes={this.state.wishes} />
              </div>
            )
        }
    }
    
    class Child1 extends Component {
    
        onChild1Send = () => {
            this.props.onSend('嗨结闸,老二新年快樂(lè)唇兑!')
        }
        
        render() {
            return (
                <h3 onClick={this.onChild1Send}>我是老大Child1</h3>
            )
        }
    }
    
    class Child2 extends Component {
    
        onChild1Send = () => {
            this.props.onSend('嗨,老二新年快樂(lè)桦锄!')
        }
        
        render() {
            return (
                <div>
                    <h3>我是老二Child2</h3>
                    {
                      this.props.fromChild1Wishes ?
                      <p>來(lái)自老大的祝福 - this.props.fromChild1Wishes</p>
                      : null
                    }
                </div>
            )
        }
    }
【35】組件通信小總結(jié)

以上三種方式是最常見(jiàn)到的扎附。但是實(shí)際項(xiàng)目中往往比這種通信更復(fù)雜得多。因?yàn)閺?fù)雜項(xiàng)目的組件嵌套往往就像一顆枝繁葉茂的樹(shù)一樣结耀。
比如:

1留夜、跨n級(jí)組件之間通信,就是 Parent 組件和它子組件的子組件通信图甜,或者子組件的子組件的子組件通信....

2碍粥、非嵌套組件的通信,剛剛說(shuō)的兄弟組件是最簡(jiǎn)單非嵌套具则,還有更多不是同一父組件的非兄弟組件的嵌套即纲。說(shuō)得繞一點(diǎn)兒,你和你爺爺?shù)牡艿艿膶O子/兒子通信就是屬于這種情況博肋。

以上的解決方案肯定是有的低斋。

  1. 你不嫌麻煩一層一層傳遞 props (三層以上就不推薦)
  2. 利用 react 提供的 context , 它類(lèi)似一個(gè)全局大容器,我們把想傳遞的信息放在里面匪凡,需要的往里面取便是膊畴。
  3. 自定義事件的方式。自定義事件是典型的發(fā)布/訂閱模式病游,通過(guò)向事件對(duì)象上添加監(jiān)聽(tīng)器和觸發(fā)事件來(lái)實(shí)現(xiàn)組件間通信唇跨。
  4. 狀態(tài)管理工具 mobx redux 等

多嘮叨一句,所有通信方式肯定都可以用在任何項(xiàng)目下衬衬。但买猖,就像女朋友一樣,最適合的才是最好的滋尉。

【36】ajax 應(yīng)該在哪個(gè)生命周期調(diào)用呢玉控?why

既然有人問(wèn)了這個(gè)問(wèn)題,看來(lái)這個(gè)問(wèn)題還有有很多討論的空間狮惜。

對(duì)于 ajax 應(yīng)該是在哪個(gè)生命周期調(diào)用呢高诺? 備受爭(zhēng)議應(yīng)該就是在 componentDidmount 和 componentWillmount 這兩個(gè)生命周期之間了。網(wǎng)路上也眾說(shuō)紛紜碾篡∈看過(guò)官網(wǎng)文檔的小伙伴們應(yīng)該也是知道 官網(wǎng)說(shuō)的是 應(yīng)該在 componentDidmount 。 然鵝开泽。官網(wǎng)并沒(méi)有告訴我們 why 牡拇?

不少開(kāi)發(fā)過(guò) react 項(xiàng)目的同學(xué)應(yīng)該也分別嘗試過(guò)在 componentDidmount 和 componentWillmount 都做過(guò) ajax 的請(qǐng)求,好像沒(méi)啥問(wèn)題吧?好像都可以成功吧诅迷? 但是到底哪一個(gè)更合適呢佩番?

咱們先來(lái)看點(diǎn)兒代碼熱熱場(chǎng)子......

代碼一:

    componentWillMount() {
        console.log(1)
        this.setState({ isLoading: true })
    }
    
    render() {
        console.log(2)
        return <div>test</div>
    }

代碼二:

    componentWillMount() {
        console.log(1)
        setTimeout(() => {
          this.setState({ isLoading: true })
        }, 0)
    }
    
    render() {
        console.log(2)
        return <div>test</div>
    }

代碼三:

    componentDidMount() {
        console.log(1)
        this.setState({ isLoading: true })
    }
    
    render() {
        console.log(2)
        return <div>test</div>
    }

代碼四:

    componentDidMount() {
        console.log(1)
        setTimeout(() => {
          this.setState({ isLoading: true })
        }, 0)
    }
    
    render() {
        console.log(2)
        return <div>test</div>
    }

現(xiàn)在你可以告訴我代碼1, 2, 3, 4分別輸出的是什么众旗?
代碼一: 1, 2
代碼二: 1, 2, 2
代碼三: 2, 1, 2
代碼四: 2, 1, 2

很多盆友都知道 this.setState 在 componentWillMount 中并不會(huì)觸發(fā) re-render罢杉。 但是如果在 setState 在一個(gè)異步方法下結(jié)果可能就不一樣了。 你知道的贡歧,我們實(shí)際上獲取數(shù)據(jù)都是異步的滩租,所以并不會(huì)阻礙組件渲染。而且我們往往都會(huì)在 ajax 請(qǐng)求成功后再 setState 來(lái)更新?tīng)顟B(tài)利朵。此時(shí)的 setState 會(huì)放入隊(duì)列中律想,等待組件掛載完成后,再更新組件绍弟。例如 將 setState 放入 setTimeout 或者 請(qǐng)求成功后的 fetch 或者 axios 中都是這種情況技即。

所以代碼二實(shí)際上就模擬了一次 在 componentWillMount 發(fā)送 ajax 請(qǐng)求。它的執(zhí)行效果或者說(shuō)效率從上面代碼看上來(lái)和代碼四是一樣的(在 componentDidMount 發(fā)送 ajax)樟遣。所以 componentWillMount 和 componentDidMount 請(qǐng)求其實(shí)都是可以的而叼!

但是!1葵陵!為什么官網(wǎng)沒(méi)這么說(shuō)呢?文檔只推薦了 componentDidMount 瞻佛。

React 下一代調(diào)和算法 Fiber 會(huì)通過(guò)開(kāi)始或停止渲染的方式優(yōu)化應(yīng)用性能脱篙,其會(huì)影響到 componentWillMount 的觸發(fā)次數(shù)。對(duì)于 componentWillMount 調(diào)用次數(shù)變得不可確定伤柄。 react 可能會(huì)多次頻繁調(diào)用 componentWillMount 绊困。ajax 放入這個(gè)生命周期顯然不是最好的選擇。

所以呢适刀。我還是比較推薦在 componentDidMount 中調(diào)用ajax 秤朗。

更多...

當(dāng)然面試中可能還會(huì)有更深層次更開(kāi)發(fā)性的問(wèn)題。

  • 如果你能夠改進(jìn)React的一樣功能蔗彤,那會(huì)是哪一個(gè)功能川梅?(react 的缺點(diǎn))
  • immutable.js 原理是什么? Immutable 詳解及 React 中實(shí)踐
  • react 性能優(yōu)化有哪些然遏?
  • react diff算法
  • react 虛擬dom原理
  • react 是什么
  • react和vue的區(qū)別
  • ...

對(duì)于react技術(shù)棧 react-router贫途、redux 當(dāng)然也有很多。

  • redux react-redux 分別負(fù)責(zé)哪些功能
  • provider connect的用法
  • store數(shù)據(jù)流向
  • redux的三個(gè)原則
  • ...

Reference

https://reactjs.org/
https://github.com/chemdemo/chemdemo.github.io/issues/14
http://www.infoq.com/cn/articles/react-jsx-and-component
https://segmentfault.com/a/1190000009001924
http://www.oschina.net/translate/functional-setstate-is-the-future-of-react
https://segmentfault.com/a/1190000007454080
http://www.reibang.com/p/fb915d9c99c4

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末待侵,一起剝皮案震驚了整個(gè)濱河市丢早,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖怨酝,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件傀缩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡农猬,警方通過(guò)查閱死者的電腦和手機(jī)赡艰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)斤葱,“玉大人慷垮,你說(shuō)我怎么就攤上這事∽岫椋” “怎么了料身?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)衩茸。 經(jīng)常有香客問(wèn)我芹血,道長(zhǎng),這世上最難降的妖魔是什么楞慈? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任幔烛,我火速辦了婚禮,結(jié)果婚禮上抖部,老公的妹妹穿的比我還像新娘说贝。我一直安慰自己,他們只是感情好慎颗,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布乡恕。 她就那樣靜靜地躺著,像睡著了一般俯萎。 火紅的嫁衣襯著肌膚如雪傲宜。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天夫啊,我揣著相機(jī)與錄音函卒,去河邊找鬼。 笑死撇眯,一個(gè)胖子當(dāng)著我的面吹牛报嵌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播熊榛,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼锚国,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了玄坦?” 一聲冷哼從身側(cè)響起血筑,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绘沉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后豺总,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體车伞,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年喻喳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了另玖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沸枯,死狀恐怖日矫,靈堂內(nèi)的尸體忽然破棺而出赂弓,到底是詐尸還是另有隱情绑榴,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布盈魁,位于F島的核電站翔怎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏杨耙。R本人自食惡果不足惜赤套,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望珊膜。 院中可真熱鬧容握,春花似錦、人聲如沸车柠。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)竹祷。三九已至谈跛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間塑陵,已是汗流浹背感憾。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留令花,地道東北人阻桅。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像兼都,于是被迫代替她去往敵國(guó)和親嫂沉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345