React16.8中Hooks詳解

1、React Hooks(鉤子)是什麼

Introducing Hookshtml

React哲學:一切皆組件react

類組件ajax

class Counter extends Component {
    render () {
        return "Hello World"
    }
}
複製代碼

函數組件編程

const Counter = () => {
    return "Hello World"
}
複製代碼

爲何說函數式組件更優?數組

  1. 簡單易懂
  2. 更符合React哲學,能夠理解爲React就是一個畫UI的工具,符合UI=f(state)的原則
  3. 函數式編程

有hooks以前,爲何React須要類組件?性能優化

  1. 須要狀態(state)
class Counter extends Component {
    state = {
        count: 0
    }
}
複製代碼
  1. 須要生命週期函數
shouldComponentUpdate () { // 減小render渲染
    return true
}
複製代碼
  1. 須要反作用操做(非純函數)

反作用:調用ajax等bash

純函數:每次輸入的參數同樣,那麼每次返回的結果都相同。不要改全局變量,不要作ajax請求,不要去作異步操做等dom

componentDidMount () {
    fetchAPI().then(res => {
        this.setState({count: res})
    })
}
複製代碼

可否讓函數組件擁有這些功能?異步

const Counter = () => {
    return `
    想擁有,但是我沒辦法擁有狀態,也沒有生命週期函數,更不要說反作用操做了
    `
}
複製代碼

Hooks擁有了這些功能函數式編程

useState 狀態管理
useEffect 生命週期函數
useContext 
等等...
複製代碼

2、React Hooks帶來哪些好處

useState: 在函數中管理狀態

const Counter = () => {
    const [count, setCount] = useState(0) // 解構  初始值0
    const increment = () => setCount( count + 1 )
    return (
      <>
        <h1>{count}</h1>
        <button onClick={increment}>+</button>
      </>
    )
}
複製代碼

useState的返回值是什麼?

const [count, setCount] = useState(0)
能夠改成下面的寫法:
const state = useState(0)
const count = state[0]
const setCount = state[1]
複製代碼

3、經常使用 Hooks 使用技巧

HoC : Higher order Component(With開頭)

有了useState這個hook以後,就能夠在組件裏管理狀態了

useState 通常寫在函數的最上面
useState:返回結果能夠任意取名
const [count, setCount] = useState(0)
也可寫成
const  [count, updateCount] = useState(0)

useState是怎麼作到的?
想象一下React爲每一次useState調用分配一個「空間」
React經過useState調用順序辨別各個「空間」,很簡單,就是經過調用順序來區分的!
複製代碼

useState執行順序必須一致!

不能寫在if判斷裏,以下

const Counter = () => {
    const [count, setCount] = useState(0)
    if (count % 2 === 0) {
        const [bar, setBar] = useState(null) // 不能這麼寫
    }
    const [foo, setFoo] = useState("foo")
}


const [count, setCount] = useState(0) // 兩個useState 根據調用順序區分
const [name, setName] = useState("Fruit Bro") // 兩個useState 根據調用順序區分

setCount(count + 1)
setCount也是異步的,是setState的變種!
複製代碼

useEffect:有機會作反作用操做

componentDidMount 用於在mount過程結束時的反作用
componentDidUpdate 用於在update過程結束時的反作用

useEffect = componentDidMount + componentDidUpdate
複製代碼

useEffect模擬componentDidMount

useEffect(() => {
    // 每次mount或update都會調用到這裏
})

useEffect(() => {
    // 只有mount時調用這裏
},[]) // []表明依賴的數據
複製代碼

useEffect模擬componentDidUnmount

useEffect(() => {
    // 只有mount時調用這裏
    return () => {
        // 只有unmount時調用這裏
    }
},[])
複製代碼

hooks特有而類組件沒有的是componentDidUnupdate,相似componentDidUnmount

useEffect模擬componentDidUpdate

const mounted = useRef() // useRef()無論調用多少次,返回的結果徹底是同樣的
useEffect(() => {
  if (!mounted.current) { 
  // 初次mounted,其實有用的就是current
      mounted.current = true
  } else {
      // do componentDidUpdate logic
  }
})
複製代碼

ref能夠訪問真正的dom,但在React中,是很是介意直接操做真實DOM的,所以用vitural dom

注意:每一次渲染都有獨立的props和state,每一次渲染使用hooks,函數組件的每一次渲染,不管是mount仍是update,無論是第幾回update,它都有獨立的props和state

const Counter = () => {
    const [count, setCount] = useState(0)
    const onClick = () => {
        setCount(count + 1)
        setTimeout(() => {
        // 返回0的緣由,初次爲0,只有再次渲染的時候count纔會爲1,而每次渲染都有獨立的props和state,所以新的渲染不會影響上一次的值
            alert(count) // 0 每一次新的執行就是一次新的開始
        }, 1000)
    }
    return (
      <>
        <h1>{count}</h1>
        <button onClick={onClick}>+</button>
      </>
    )
}
複製代碼

useContext: 簡化Context的使用

Hooks以前
<Context.Consumer>
  {contextValue => <h1>{contextValue}</h1>}
</Context.Consumer>

Hooks以後
const contextValue = useContext(Context)

<h1>{contextValue}</h1>
複製代碼

4、React Hooks有哪些好處

Hooks的好處

  1. 下降了組件的複雜性

    1.1 徹底使用函數組件

    1.2 無需生命週期函數

    1.3 更好的狀態管理

  2. 更好的代碼重用性

    2.1 傳統的代碼重用方式 組件、高階組件(HoC)、render props模式

    2.2 Hooks下的代碼重用方式:函數

定製Hooks: 函數形式的代碼重用
// Beacon 計數
const useBeacon = () => {
    const [renderCount, setRenderCount] = useState(0)
    
    useEffect(() => {
        sendBeacon()
    })
}
// 重用
const Foo = () => {
    useBeacon();
    ...
}

const Bar = () => {
    useBeacon();
    ...
}
複製代碼

5、如何遷移到Hooks

React v16.8.0開始正式支持Hooks

原有類組件功能依然支持

業界趨勢將是向函數組件傾斜

遷移策略

瞭解Hooks

對新組建使用Hooks

逐步替換原有類組件

hooks如何處理類組件的shouldComponentUpdate來作性能優化 memo

若有錯誤,歡迎指正!謝謝!

相關文章
相關標籤/搜索