React的組件發(fā)展

函數(shù)式組件

function HelloMessage() {
  let message = 'hello message'
  return (
    <div>
      <div>{messgae}</div>
      <button onClick={() => { message = 'hello react' }}>修改文本</button>
    </div>
  )
}

函數(shù)式組件的缺陷:

  1. 組件不會(huì)重新渲染:修改message之后叶洞,組件不知道自己要重新渲染
  2. 如果組件可以重新渲染,函數(shù)會(huì)被重新執(zhí)行,第二次執(zhí)行時(shí)message又會(huì)被初始化為"hello message"
  3. 沒(méi)有生命周期的回調(diào)

類組件

function HelloWorld (props) {
  const imitateRequest = () => {
    setTimeout(() => {
      console.log('模擬函數(shù)式組件發(fā)送請(qǐng)求')
    }, 1000)
  }
  imitateRequest()
  return (
    <div>
      <h2>Hello World: {props.counter}</h2>
    </div>
  )
}

class App extends PureComponent {
  constructor (props) {
    super(props)
    this.state = {
      counter: 1
    }
  }
  increment () {
    this.setState({
      counter: this.state.counter + 1
    })
  }
  render() {
    let { counter } = this.state
    return (
      <div>
        <h1>App:{counter}</h1>
        <button onClick={this.increment}>修改counter</button>
        <HelloWorld counter={counter}/>
      </div>
    )
  }
}

class組件相對(duì)于函數(shù)式組件有什么優(yōu)勢(shì)?比較常見(jiàn)的是下面的優(yōu)勢(shì):

  • class可以定義自己的state要出,用來(lái)保存組件內(nèi)部的狀態(tài)

    • 而函數(shù)式組件不可以,因?yàn)楹瘮?shù)每次調(diào)用农渊,都會(huì)產(chǎn)生新的臨時(shí)變量
  • class有自己的生命周期厨幻,我們可以在對(duì)應(yīng)的生命周期中編寫(xiě)自己的邏輯

    • 比如在componentDidMount中發(fā)送網(wǎng)絡(luò)請(qǐng)求,這個(gè)生命周期只會(huì)執(zhí)行一次
    • 函數(shù)式組件腿时,如果在函數(shù)中發(fā)送網(wǎng)絡(luò)請(qǐng)求况脆,每次重新渲染都會(huì)重新發(fā)送一次網(wǎng)絡(luò)請(qǐng)求
  • class組件在狀態(tài)發(fā)生變化時(shí),只會(huì)重新執(zhí)行render函數(shù)和componentDidupdate等

    • 函數(shù)式組件在重新渲染時(shí)批糟,整個(gè)函數(shù)都會(huì)被執(zhí)行

class組件的缺點(diǎn):

  • 復(fù)雜組件變得難以理解:

  • 對(duì)于邏輯復(fù)雜的組件格了,代碼會(huì)比較混亂,比如componentDidMount中徽鼎,就可能包含大量的邏輯代碼盛末,比如網(wǎng)絡(luò)請(qǐng)求,事件監(jiān)聽(tīng)等否淤。如果想要抽取通用的邏輯悄但,比如高階組件(HOC),又增加代碼的復(fù)雜度石抡。

  • 難以理解的class: 要學(xué)習(xí)class,還必須搞清楚this的指向

  • 組件復(fù)用狀態(tài)很難:

    • 通過(guò)高階組件復(fù)用狀態(tài)
    • Provider和Consumer來(lái)共享狀態(tài)檐嚣,但是多次使用Consumer時(shí),代碼就會(huì)存在很多嵌套
    • 這些代碼不管是編寫(xiě)和設(shè)計(jì)啰扛,都比較困難

Hooks的出現(xiàn)

hooks的出現(xiàn)解決函數(shù)式組件的問(wèn)題嚎京,可以讓我們?cè)诤瘮?shù)式組件中使用state以及react的其他特性。

const Home = () => {
  const [name, setName] = useState('hello title')
  const handleName = ({ target: {value}}) => {
    setName(value)
  }
  useEffect(() => {
    document.title = name
  }, [name])

  const [width, setWidth] = useState(window.innerWidth)
  useEffect(() => {
    let handleResize = () => setWidth(window.innerWidth)
    window.addEventListener('resize', handleResize)
    return () => {
      window.removeEventListener('resize', handleResize)
    }
  }, [])

  return (
    <div>
      <input value={name} onChange={handleName}/>
      <span>{width}</span>
    </div>
  )
}

Hooks的好處:

  • 函數(shù)式組件結(jié)合hooks讓整個(gè)代碼變得非常簡(jiǎn)潔

    • 利用useEffect隐解,把業(yè)務(wù)邏輯分開(kāi)鞍帝,把之前放在不同生命周期里的相同功能的代碼,聚合在一起煞茫,把不同功能但是要在同一生命周期的代碼帕涌,隔離開(kāi),提高了代碼的可讀性和可維護(hù)性续徽。
  • 解決了和狀態(tài)相關(guān)的邏輯復(fù)用問(wèn)題:

    • 原來(lái)代碼復(fù)用使用的高階組件和渲染屬性都會(huì)增加組件樹(shù)層級(jí)蚓曼,使用起來(lái)也不方便,自定義hooks就可以解決這些問(wèn)題炸宵,而且使用更直觀方便辟躏;
  • 并且再也不用考慮this相關(guān)的問(wèn)題谷扣;

  • 更好的體現(xiàn)了react的開(kāi)發(fā)思想土全,從state->view的函數(shù)式映射

    • 可以把UI的展示看成一個(gè)函數(shù)執(zhí)行的過(guò)程捎琐,Model就相當(dāng)于輸入的參數(shù),UI就相當(dāng)于函數(shù)的執(zhí)行結(jié)果裹匙;react要保證的是每當(dāng)狀態(tài)發(fā)生變化時(shí)瑞凑,函數(shù)就會(huì)重新執(zhí)行,并且會(huì)生成新的dom樹(shù)概页,然后react會(huì)把新的dom樹(shù)籽御,以最優(yōu)的方式更新到瀏覽器上;

Hooks的注意事項(xiàng):

  • 只能在函數(shù)最外層調(diào)用hook惰匙,不能在循環(huán)技掏、條件判斷或者子函數(shù)中調(diào)用
  • 只能在React的函數(shù)組件或者自定義Hooks中調(diào)用Hook,不能在其他js函數(shù)中調(diào)用
  • 保證狀態(tài)最小化项鬼,需要渲染到UI里的保存在state里哑梳,不需要渲染的可以保存在useRef里;或者一些可以通過(guò)其他狀態(tài)計(jì)算得出的數(shù)據(jù)绘盟;
  • 不要用props去初始化state鸠真,可以在useEffect中通過(guò)監(jiān)聽(tīng)props的變化去設(shè)置state;

有了Hooks以后得函數(shù)式組件,依然存在一些問(wèn)題:

  • 事件處理函數(shù)會(huì)被重復(fù)定義龄毡,數(shù)據(jù)計(jì)算過(guò)程沒(méi)有緩存

    • 這些問(wèn)題就需要利用useCallback吠卷、useMemo、useRef這些Hook來(lái)做一些優(yōu)化
  • 對(duì)一些類組件的生命周期函數(shù)還不支持沦零,還不能實(shí)現(xiàn)getSnapShotBeforeUpdate和componentDidCatch這個(gè)生命周期祭隔;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市路操,隨后出現(xiàn)的幾起案子序攘,更是在濱河造成了極大的恐慌,老刑警劉巖寻拂,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件程奠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡祭钉,警方通過(guò)查閱死者的電腦和手機(jī)瞄沙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)慌核,“玉大人距境,你說(shuō)我怎么就攤上這事】遄浚” “怎么了垫桂?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)粟按。 經(jīng)常有香客問(wèn)我诬滩,道長(zhǎng)霹粥,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任疼鸟,我火速辦了婚禮后控,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘空镜。我一直安慰自己浩淘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布吴攒。 她就那樣靜靜地躺著张抄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪洼怔。 梳的紋絲不亂的頭發(fā)上欣鳖,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音茴厉,去河邊找鬼泽台。 笑死,一個(gè)胖子當(dāng)著我的面吹牛矾缓,可吹牛的內(nèi)容都是我干的怀酷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼嗜闻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蜕依!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起琉雳,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤样眠,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后翠肘,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體檐束,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年束倍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了被丧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绪妹,死狀恐怖甥桂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情邮旷,我是刑警寧澤黄选,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站婶肩,受9級(jí)特大地震影響办陷,放射性物質(zhì)發(fā)生泄漏貌夕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一懂诗、第九天 我趴在偏房一處隱蔽的房頂上張望蜂嗽。 院中可真熱鬧苗膝,春花似錦殃恒、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至问窃,卻和暖如春亥鬓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背域庇。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工嵌戈, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人听皿。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓熟呛,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親尉姨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子庵朝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一. 組件化開(kāi)發(fā) 組件化開(kāi)發(fā)的思想 1. 分而治之的思想 人面對(duì)復(fù)雜問(wèn)題的處理方式: 任何一個(gè)人處理信息的邏輯能力...
    JackLeeVip閱讀 644評(píng)論 2 3
  • Hook 是 React 16.8 的新增特性。它可以讓你在不編寫(xiě) class 的情況下使用 state 以及其他...
    虛擬J閱讀 1,658評(píng)論 0 1
  • 組件的生命周期 React中組件也有生命周期又厉,也就是說(shuō)也有很多鉤子函數(shù)供我們使用, 組件的生命周期九府,我們會(huì)分為四個(gè)...
    解勾股閱讀 742評(píng)論 0 0
  • React中組件也有生命周期,也就是說(shuō)也有很多鉤子函數(shù)供我們使用, 組件的生命周期覆致,我們會(huì)分為四個(gè)階段侄旬,初始化、運(yùn)...
    周南安閱讀 239評(píng)論 0 1
  • 組件化開(kāi)發(fā)一 目前煌妈,前端三大框架(Vue勾怒,React,Angular)都在使用組件化的我形式進(jìn)行開(kāi)發(fā)声旺。19年最火的...
    wpLishuai閱讀 324評(píng)論 0 0