react hooks 的簡單使用

前端之神發表於2020-12-07

先了解一下類元件和函式元件

react 的特點就是:一切皆為元件。其中,元件種類有很多,不同種類的元件有不同的功能。

我們熟知的元件種類:函式元件、類元件、受控元件、非受控元件、ui元件、容器元件、高階元件等。

我們先介紹一下類元件和函式元件,讓我們清楚為什麼會有 hooks

  • 類元件

    其中,我們最熟悉的類元件,也就是有狀態元件,是這個樣子的:

    import React, { Component } from 'react'
    
    export default class MyComponent extends Component {
        constructor(){
            super();
            this.state = {
                count:0
            }
        }
        render() {
            return (
                <div>
                    類元件
                </div>
            )
        }
    }
    

    類元件的特點就是功能強大。不僅有自己的狀態 state ,還擁有自己的例項和一套完整的生命週期。在類元件裡,你可以:

    1. 使用狀態 state
    2. 使用完整的生命週期
    3. 訪問 this

    正是因為它太強大,所以也迎來了一個弊端:渲染速度慢

  • 函式元件

    顧名思義,函式元件就是一個 Function :

    function FnComponent(){
        return (
        	<div>
            	函式元件
            </div>
        )
    }
    

    就那麼簡單,所以函式元件的渲染速度更快。考慮到效能問題,我們在開發的時候更推薦使用函式元件。但是也有一些問題:函式元件侷限性太多,身上沒有我們需要的 state 和 生命週期。

    那怎麼辦呢?

它來了

react 16.8 版本中更新了強大的 hooks

【hooks :n. 鉤子;[機] 掛鉤(hook的複數)】——來自有道翻譯

簡而言之, hooks 可以讓函式元件擁有類元件的特點

下面將介紹一下幾個 hooks 的使用

useState

實現了在函式元件中建立並使用 state

語法:

  1. 定義狀態

const [變數名,修改變數函式] = useState(變數值)

  1. 取值

正常取值即可

  1. 賦值
  • 函式名(新值)

  • 函式名(回撥函式) :回撥函式的引數是當前值,返回值是新值

    注意:

    1. 如果定義的是一個物件的話,返回值需要是一個新的物件(克隆),因為物件是引用型別,所以只有物件的地址發生變化檢視才會更新。
    2. hooks 只能在函式元件的內部呼叫。
import React,{ useState } from 'react'

function App() {
    // useState 的使用
    const [count,setCount] = useState(0);
    return (
    	<div>
            {/* 直接變數名取值 */}
        	<h2>{count}</h2>
            {/* 修改變數的值 */}
            <button onClick={()=>{setCount((val)=>(val+1))}}>點選+1</button>
            <button onClick={()=>{setCount(0)}}>點選歸零</button>
        </div>
    )
}

useEffect

讓函式元件擁有特定的生命週期。

語法:

useEffect(引數1,引數2)

  • 引數1:回撥函式,就是在當前生命週期內需要做的事情

    如果在當前函式 return 了一個函式,那麼返回的這個函式就是 componentWillUnmount —— 銷燬時執行的函式。

  • 引數2:對比值,根據引數2的不同來決定 useEffect 執行的是哪個生命週期。

    1. 引數2為 []:模擬 componentDidMount ——掛載成功
    2. 引數2為空:模擬 componentDidUpdate ——更新成功
  • componentDidMount 掛載成功

    import { useEffect } from 'react'
    
    // ...
    useEffect(()=>{
        console.log('掛載成功')
    },[])
    // ...
    
  • componentDidUpdate 更新成功

    import { useEffect } from 'react'
    
    // ...
    useEffect(()=>{
        console.log('更新成功')
    })
    // ...
    
  • componentWillUnmount 銷燬時

    import { useEffect } from 'react'
    
    // ...
    useEffect(()=>{
        // ...
        return ()=>{
            console.log('銷燬時')
        }
    })
    // ...
    

useRef

在函式元件中獲取到真實的dom結構

語法:

  1. 定義一個儲存ref的變數

    let dom = useRef

  2. 在想要獲取的標籤的屬性上定義ref屬性

    <h2 ref={dom}>你好</h2>

  3. 獲取dom

    console.log(dom.current) --> <h2>你好</h2>

import React,{ useRef,useEffect } from 'react'

export default function App() {
    let dom = useRef();
    useEffect(()=>{
        console.log('掛載成功');
        console.log(dom.current); // <h2>你好</h2>
    },[])
    return (
    	<div>
        	<h2 ref={dom}>你好</h2>
        </div>
    )
}

useReducer

它是函式元件中的狀態管理方案,一般在簡單的情況下用 useState 就足夠了,在一些複雜的情況下適合使用 useReducer ,因為它可以在函式元件中操作action

操作方法和 Redux 中的狀態管理相似

語法:

let [state,dispatch] = useReducer(reducer,myState)

引數:

  1. 回撥函式——reducer
  2. 狀態——state

返回值:

  1. state
  2. dispatch
import React,{ useReducer } from 'react'

// 定義 reducer 和 state
function reducer(state,action){
    switch(action.type){
        case "ADD": return {count:++state.count}
        case "REDUCE": return {count:--state.count}
    }
}
let myState = {
    count:1
}

function App() {
    // 使用 useReducer 
    let [state,dispatch] = useReducer(reducer,myState)

    return (
    	<div>
            <h2>{state.count}</h2>
            <button onClick={addHandler}>+</button>
            <button onClick={reduceHandler}>-</button>
        </div>
    )
    
    function addHandler(){
        let action = {type:"ADD"};
        dispatch(action)
    }
    function reduceHandler(){
        let action = {type:"REDUCE"};
        dispatch(action)
    }
}

export default App;

相關文章