React hooks(1)

1. 什么是hooks

A way to use state and other React features without writing a class.

React Hooks是React從v16.8引入的一種新的更簡單更方便的編寫組件的功能。hooks提供了一種可以不用寫class而直接使用state和其他React特性的能力,而且自定義hooks可以將公共邏輯抽離,使之可以在多個(gè)組件之間共享。

2. hooks的由來

hooks主要是為了解決以下3個(gè)React問題

  • 組件帶狀態(tài)變得難以復(fù)用

  • 復(fù)雜邏輯不用跟隨生命周期

  • 解決難以理解的class

    js中的this取值跟其他面向?qū)ο笳Z言都不同,是在運(yùn)行時(shí)決定的。為了解決這一痛點(diǎn),才有了箭頭函數(shù)的this綁定特性。另外何時(shí)使用class component 和 function component也是一件容易糾結(jié)的事,對于優(yōu)化方面來說,class component在預(yù)編譯和壓縮方面也比普通函數(shù)困難得多,還容易出錯(cuò)。

3. 使用
  • state hook

    import { useState } from 'react'
    
    function Demo() {
      const [count, setCount] = useState(0)
      return (
          <div>
          <p>count: { count }</p>
              <button onClick={() => { setCount(count + 1) }}>點(diǎn)擊</button>
        </div>
      )
    }
    

    useState只有一個(gè)參數(shù),即count的初始值,可以是任意類型。如果count是對象,useState不會像setState自動合并原state,可以:

    setState(preV => {
      return { ...preV, ...updateV }
      // Object.assign(preV, updateV)  
    })
    

    多個(gè)state變量只需要多次調(diào)用useState即可

    ...
    function Demo2() {
     const [count, setCount] = useState(0)
     const [fruit, setFruit] = useState('apple')
     ...
    }
     
    
  • Effect hook

    我們希望組件在DOM掛載和更新后執(zhí)行相同的操作,使用React Effect hooks寫法:

    import React, { useEffect } from 'react'
    
    function Demo3() {
      const [count, setCount] = useState(0)
      
      useEffect(() => {
        document.title = `clicked ${count} times`
      })
    }
    

    傳統(tǒng)class component寫法:

    import React from 'react'
    
    class Demo3 extends React.Component{
      constrctor(props) {
        super(props)
        this.state = {
          count: 0
        }
      }
      
      componentDidMount () {
        document.title = `clicked ${this.state.count} times`
      }
      compoenntDidUpdate () {
        document.title = `clicked ${this.state.count} times`
      }
      ...
    }
    

    傳統(tǒng)class component,我們需要在兩個(gè)生命周期中調(diào)用相同的函數(shù),使用Effect特性React會保存?zhèn)鬟f的函數(shù),并在DOM渲染后調(diào)用該函數(shù)。useEffect同時(shí)擁有componentDidMount,componentDidUpdate,componentWillUnmount三個(gè)生命周期的執(zhí)行時(shí)機(jī)。但Effct并不會阻塞瀏覽的渲染,使應(yīng)用看起來更加流暢。

    有時(shí)候我們?yōu)榱朔乐箖?nèi)存泄漏需要清除的Effct,class component中需要在componentDIdMount中注冊并在componentWillUnmount中銷毀,使用hooks只需要在useEffct中返回一個(gè)函數(shù)即可

    function Demo4() {
      useEffct(() => {
        let timer = setInterval(() => {
          console.log(1)
        })
        return () => {
          clearInterval(timer)
        }
      })
    }
    

    當(dāng)useEffct返回一個(gè)函數(shù)的時(shí)候,React會在下一次執(zhí)行副作用之前調(diào)用一次清理函數(shù)。

    組件掛載 —> 執(zhí)行副作用 —>組件更新 —>執(zhí)行清理函數(shù)—>執(zhí)行副作用—>組件更新—>執(zhí)行清理函數(shù)—>組件卸載

    所以每次state更新我們都會重新渲染一次,如果state值沒有改變的情況下(原來count是5改變后還是5),我們不想調(diào)用Effct,只需要在useEffct函數(shù)中傳入第二個(gè)參數(shù)[count]即可。React會對前一次渲染的[5]和后一次渲染的[5]對比,數(shù)組內(nèi)元素全部相等,React就會跳過這個(gè)Effct,同時(shí)實(shí)現(xiàn)了性能的優(yōu)化。該參數(shù)為數(shù)組,可以傳多個(gè)數(shù)組,一般會將Effct用到的propsstate都傳進(jìn)去。清除函數(shù)同理。

    如果useEffct傳入的第二個(gè)參數(shù)是一個(gè)[],等效于componentDidMountcomponentWillUnmount

4. hooks規(guī)則
  • 只能在React 函數(shù)式組件中調(diào)用Hook

  • 只能在函數(shù)最外層調(diào)用Hook

  • 只能用在函數(shù)最頂層

  • 不能用在循環(huán)條件判斷語句,嵌套函數(shù)

  • ESLint插件eslint-plugin-react-hooks格式規(guī)范

...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容