React hooks能替代HOC和render props么?


最近開始學習React,記錄一下心得。

React hooks是16.8.0推出的,其目的是為了替換class,HOC,render props。那么本文將討論啥是hooks,HOC,render props,以及hooks究竟能不能替換掉HOC,render props。

Hooks替代HOC和render props。

首先是hooks(這里指custom hooks,下同),HOC,render props到底是做什么的?

對於新手,並不是很容易理解它們是做什么的,至少我沒有很容易理解。

我現在理解為它們是為了共享一些維護state的邏輯。

什么意思呢?首先它共享的是邏輯,但是共享邏輯你隨便封裝一個函數不就可以了么?問題就出在它是共享維護state的邏輯。普通的邏輯的和維護state的邏輯的區別就是,維護一個state的邏輯,當state發生變化時,用到這個state的組件是要重新渲染的,顯然用普通的函數做不了這個事情。

那么有哪些維護state的邏輯呢?我大體上把它們分為兩類:

第一類,一個狀態組件維護state的邏輯,第二類,一個非組件維護state的邏輯。

其實一個狀態組件本身就是在維護一個state,當用戶操作它所渲染的UI的時候,state發生響應的變化。組件的邏輯負責維護state的變化。

那么非組件指什么呢?

比如說我維護一個user的登錄狀態,這個登錄狀態需要發送請求給后台去拿。那么這個登錄狀態就會有3個值{fetching,online,offline},而且可能會從fetching到online,或者從fetching到offline,就是會變化的。

比如說我需要記錄用戶鼠標的位置(x,y坐標),這個是隨用戶移動鼠標而變化的。

比如說我做一個定時器,每隔一段時間切換一下我維護的一個state。

等等,我相信還有其他很多。

之所以分為這兩類,是因為我們不能用hooks來共享狀態組件。這是因為我們用hooks的時候是需要用它的返回值的,這個返回值通常是這個hooks所維護的state或者state的計算值,那么這個hooks就不可能返回一個dom元素了,也就是hooks不能包含組件。

然后我們建立一個簡單的模型分析下三者的結構。

我們假設有三個組件A,B,C需要共享一個維護state的邏輯S。那么:

hooks是什么呢?hooks就是把S封裝成useS,也就是一個custom hooks,然后在A,B,或者C里面使用useS

 

const useS = () => {
    const [state, setState] = useState('someValue')
    useEffect(() => {
        ...some code...
        setState('anotherValue')
    })
    return state;
}
const A = () => {
    const s = useS();
    return (
        <div>
            <div>{s}</div>
            <div>A</div>
        </div>
    )
}

 

Render props是什么呢?它是把S封裝成一個component,同時這個component留了一個props用來接收需要渲染的組件。我認為下面這兩種寫法都是render props,因為他們的結構基本一樣,結果完全一樣。

第一種,就是官方文檔的寫法:

 

const S = ({render}) => {
    const [state, setState] = useState('someValue')
    useEffect(() => {
        ...some code...
        setState('anotherValue')
    })
    return render(state)
}

const A = ({s}) => {
    return (
        <div>
            <div>{s}</div>
            <div>A</div>
        </div>
    )
}

const App = () => {
    return <S render = {(s) => <A s={s} />} />
}

 

 第二種,也是可用的寫法。

const S = ({render}) => {
    const [state, setState] = useState('someValue')
    useEffect(() => {
        ...some code...
        setState('anotherValue')
    })
    const Render = render;
    return <Render s={state} />
}

const A = ({s}) => {
    return (
        <div>
            <div>{s}</div>
            <div>A</div>
        </div>
    )
}

const App = () => {
    return <S render = {A} />
}

 

 可以看到render props相對於hooks有明顯的區別,它在被調用的時候需要知道兩個component。Render props的兩種寫法的區別就是第一種是調用的時候render設置為一個函數,返回值為component實例。第二種是render設置為component本身。

HOC是什么呢?HOC就是把S封裝成一個函數withS,這個函數返回一個新的component。

 

const withS =(WrappedComponent) => {
    return () => {
        const [state, setState] = useState('someValue')
        useEffect(() => {
            ...some code...
            setState('anotherValue')
        })
        return <WrappedComponent s={state} />
    }
}
const A = ({s}) => {
    return (
        <div>
            <div>{s}</div>
            <div>A</div>
        </div>
    )
}
const AWithS = withS(A);
const App = () => { return <AWithS />; }

 

 對比一下HOC和render props,你會發現其實HOC返回的component使用的技術和render props很相似哦!只不過render props的例子中需要render的component來自props,而HOC中需要render的component來自HOC的參數。

當然在react的官方文檔中你會發現另一種寫法,HOC的返回值調用了用render props技術實現的S。這種寫法往往是為了提供API給其他開發者,讓喜歡用HOC的去使用HOC,喜歡用render props的去使用render props。

 

const S = ({render}) => {
    const [state, setState] = useState('someValue')
    useEffect(() => {
        ...some code...
        setState('anotherValue')
    })
    const Render = render;
    return <Render s={state} />
}

const withS = (WrappedComponent) => {
    return () => { return <S render = {(s) => <WrappedComponent s={s} />} /> }
}

const A = ({s}) => {
    return (
        <div>
            <div>{s}</div>
            <div>A</div>
        </div>
    )
}
const AWithS = withS(A);
const App = () => {
    return <AWithS />;
}
const AnotherApp = () => {
    return <S render = {(s) => <A s={s} />} />
}

 

 

HOC和hooks一樣,在調用的時候只需要知道一個component,上面例子中的AwithS,實際情況是我們命名AwithS為A,而真正的A不被暴露(export)出去,這是很好的行為。

HOC不光是有共享維護state的邏輯的能力,還可以做一切封裝能做的事情,比如說偷偷改下上層component傳過來的props的值。

Hooks能替代HOC,render props么?

hooks是無法實現共享狀態組件邏輯的,當然就無法在這方面代替HOC和render props。而共享非組件邏輯的功能,基本都可以用hooks來替代,而且最好用hooks來實現,因為我們看到了,hooks的邏輯最直接,最容易理解。當然第一原則仍然是根據業務實事求是,就是概念上該是什么就是什么,如果概念上就是HOC,那么就用HOC。實事求是是為了代碼的更好維護。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM