react hooks初體驗

什麼是Hooks?
Hooks是react即將推出的功能,它容許您在不編寫類的狀況下使用狀態和其餘React功能。
個人理解就是能夠用寫無狀態組件的方式去編寫擁有狀態的組件。
遺憾的是,正式版16.7.0出了以後並無hooks,若是須要體驗還需下載next版本,目前是16.7.0-alpha.2前端

npm i react@next
此次與你們分享四個Hooks,我的以爲這幾個應該是以後工做中會常用到的。

 1. useState
 2. useEffect
 3. useReducer
 4. useMemo

1.useState
我的感受這個鉤子是重點,使用它便可作到用函數的編寫帶有狀態的組件。react

import React,{ useState,useEffect } from 'react'
const HookTest = () => {
    const [obj,setValue] = useState({key:'count',value:0});
    const handleChange = () => {
        const value = obj.value+1;
        //改變狀態
        setValue(Object.assign(obj,{value}));
    }
    return (
        <div>
             {obj.key}:{obj.value}
             <p>
                <button onClick={handleChange}>累加</button>
             </p>
        </div>
    )
}

很明顯,重點在於const [obj,setValue] = useState({key:'count',value:0})這一句,useState是個函數,接收一個狀默認值,返回一個數組,第一個元素爲狀態,初始值爲傳入函數的默認值,第二個元素爲方法,可以使用此方法改變狀態的值。git

2.useEffect
這個鉤子,官方所說是componentDidMount,componentDidUpdate和componentWillUnmount這三個生命週期的結合,由於組件掛載完成時會執行,更新時會執行,卸載時會執行,接上面的HookTest組件,往裏添加github

useEffect(()=>{
    console.log('obj->',obj);
    return ()=>{
        console.log('卸載時..');
    }
});

這就是一個基本用法,掛載、更新、卸載都會打印obj對象,return的函數,做爲組件更新或者卸載時執行,好比在使用setinterval,能夠在return的函數裏寫clearinterval。
若是隻想讓它執行一次的話,能夠往函數裏添加第二個參數。npm

useEffect(()=>{
    console.log('obj->',obj);
},false);

這樣只在掛載完成時執行一次,第二個參數能夠爲false、[]、{}、""
若是想讓他有條件的執行,能夠往第二個參數傳入具體的參數redux

useEffect(()=>{
    console.log('obj->',obj);
},{obj.value});

若是obj.value值變化時,就執行,沒變化時就不執行,對於性能優化很是友好。數組

3.useReducer性能優化

若是使用過redux的童鞋們不會默認,將須要的狀態保存到一個對象中,可供全部的組件使用。
先上代碼異步

import React, { useReducer,useMemo,useEffect,useState } from 'react';
//建立reducer,reducer可在外部建立而後再引入
function reducer(state = { count: 0 }, action) {
    switch (action.type) {
        case 'reset':
            return { count: 0 };
        case 'increment':
            return { count: state.count + 1 };
        case 'decrement':
            return { count: state.count <= 0 ? 0 : state.count - 1 };
        default:
            return state;
    }
}
//組件
const useReducerDemo = () => {
    const [state, dispatch] = useReducer(reducer, { count: 0 }, { type: 'increment' });
    //異步增長
    const asyncIncrement = () => {
        setTimeout(()=>{
            dispatch({ type: 'increment' })
        },2000);
    }
    return (
        <div>
            <p>
                <span>Count: {state.count}</span>
                <button onClick={() => dispatch({ type: 'reset' })}>還原</button>
                <button onClick={() => dispatch({ type: 'increment' })}>+</button>
                <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
                <button onClick={asyncIncrement}>async+</button>
            </p>
        </div>
    )
}

能夠看到,和useState很像,也是使用一個數組解構接受返回的值。
先說返回的值:
1.state
天然爲reducer的狀態
2.dispatch
這個是一個函數,有dispatch就意味着咱們能夠不用像使用redux時還須要本身下中間件(如redux-thunk)就能夠進行異步操做,具體看asyncIncrement函數,參數爲一個對象,指定須要執行的action
再說useReducer函數的參數:
第一個參數爲你引入的reducer,第二個參數爲state的默認值,第三個參數爲初始觸發的action,就是載入時默認就執行一個actionasync

4.useMemo
useMemo只有當其中一個輸入發生變化時,纔會從新計算記憶值。此優化有助於避免在每一個渲染上進行昂貴的計算。
此鉤子也是有助於性能優化,接入上面的useReducerDemo組件,往裏添加

const [tips,setTips] = useState(false);
//當爲0時提示不能再減了
useEffect(()=>{
    if(!state.count){
        setTips(true);
    }else{
        setTips(false);
    }
});
const memoizedValue = useMemo(() => {
    console.log('useMemo run');
    return tips
}, [tips]);

在return組件元素div裏添加

{
    memoizedValue && <p>不能爲負數哦</p>
}

以上新增的代碼時爲了實如今reducer裏的count小於等於0或從0變動爲其餘數字時更新true或false,以此達到p元素的顯示與否,不然一直爲上一次計算獲得值,咱們使用了console.log('useMemo run');記錄它更新的次數,當count從0一直+1,只會打印一次'useMemo run',由此說明,只在0變成1的時候執行了一次,日後memoizedValue的值一直爲0變成1時所return的值。
此例子並說明不了什麼,不過當有很龐大計算量的時候就能體現出useMemo的做用了。
useMemo一樣也是一個函數,接受兩個參數,第一個參數爲函數,第二個參數爲要比對的值,返回一個值。
第二個參數裏能夠傳入多個值,如[a,b,c,...],當傳入的這些值有變化時,就會去執行第一個傳入的函數,根據業務需求計算後返回最終結果。
同理,第二個參數傳入的值沒有更新時,不會執行。

結尾
花了一下午的時間體驗hook,其餘的鉤子也使用了個遍,感受這四個在我看來和在我公司業務裏可能會大量的使用到,因此發此文章分享,也爲記錄,本人新手前端一枚,第一次寫文章,有說的不對的地方還請請多多指教。
謝謝你們的閱讀。
以上代碼的github地址爲react-hooks初體驗

相關文章
相關標籤/搜索