摘要:原文鏈接高階組件在中是組件復(fù)用的一個(gè)強(qiáng)大工具。在本文中,高階組件將會被分為兩種基本模式,我們將其命名為和用附加的功能來包裹組件。這里我們使用泛型表示傳遞到的組件的。在這里,我們定義從返回的組件,并指定該組件將包括傳入組件的和的。
原文鏈接:https://medium.com/@jrwebdev/...
高階組件(HOCs)在React中是組件復(fù)用的一個(gè)強(qiáng)大工具。但是,經(jīng)常有開發(fā)者在結(jié)合TypeScript使用中抱怨道很難去為其設(shè)置types。
這邊文章將會假設(shè)你已經(jīng)具備了HOCs的基本知識,并會根據(jù)由淺入深的例子來向你展示如何去為其設(shè)置types。在本文中,高階組件將會被分為兩種基本模式,我們將其命名為enhancers和injectors:
enhancers:用附加的功能/props來包裹組件。
injectors:向組件注入props。
請注意,本文中的示例并不是最佳實(shí)踐,本文主要只是展示如何在HOCs中設(shè)置types。
Enhancers我們將從enhancers開始,因?yàn)樗菀兹ピO(shè)置types。此模式的一個(gè)基本示例是一個(gè)向組件添加loading props的HOC,并且將其設(shè)置為true的時(shí)候展示loading圖。下面是一個(gè)沒有types的示例:
const withLoading = Component => class WithLoading extends React.Component { render() { const { loading, ...props } = this.props; return loading ?: ; } };
然后是加上types
interface WithLoadingProps { loading: boolean; } const withLoading =(Component: React.ComponentType
) => class WithLoading extends React.Component
{ render() { const { loading, ...props } = this.props; return loading ?
: ; } };
這里發(fā)生了一些事情,所以我們將把它分解:
interface WithLoadingProps { loading: boolean; }
在這里,聲明一個(gè)props的interface,將會被添加到被包裹的組件上。
(Component: React.ComponentType
)
這里我們使用泛型:P表示傳遞到HOC的組件的props。React.ComponentType
是 React.FunctionComponent
| React.ClassComponent
的別名,表示傳遞到HOC的組件可以是類組件或者是函數(shù)組件。
class WithLoading extends React.Component
在這里,我們定義從HOC返回的組件,并指定該組件將包括傳入組件的props(P)和HOC的props(WithLoadingProps)。它們通過 & 組合在一起。
const { loading, ...props } = this.props;
最后,我們使用loading props有條件地顯示加loading圖或傳遞了自己props的組件:
return loading ?: ;
注意:由于typescript中可能存在的bug,因此從typescript v3.2開始,這里需要類型轉(zhuǎn)換(props as p)。
我們的withloading HOC也可以重寫以返回函數(shù)組件而不是類:
const withLoading =( Component: React.ComponentType
): React.FC
=> ({ loading, ...props }: WithLoadingProps) => loading ?
: ;
這里,我們對對象rest/spread也有同樣的問題,因此通過設(shè)置顯式的返回類型React.FC
來解決這個(gè)問題,但只能在無狀態(tài)功能組件中使用WithLoadingProps。
注意:React.FC是React.FunctionComponent的縮寫。在早期版本的@types/react中,是React.SFC或React.StatelessFunctionalComponent。Injectors
injectors是更常見的HOC形式,但更難為其設(shè)置類型。除了向組件中注入props外,在大多數(shù)情況下,當(dāng)包裹好后,它們也會移除注入的props,這樣它們就不能再從外部設(shè)置了。react redux的connect就是是injector HOC的一個(gè)例子,但是在本文中,我們將使用一個(gè)更簡單的例子,它注入一個(gè)計(jì)數(shù)器值并回調(diào)以增加和減少該值:
import { Subtract } from "utility-types"; export interface InjectedCounterProps { value: number; onIncrement(): void; onDecrement(): void; } interface MakeCounterState { value: number; } const makeCounter =( Component: React.ComponentType
) => class MakeCounter extends React.Component< Subtract
, MakeCounterState > { state: MakeCounterState = { value: 0, }; increment = () => { this.setState(prevState => ({ value: prevState.value + 1, })); }; decrement = () => { this.setState(prevState => ({ value: prevState.value - 1, })); }; render() { return (
); } };
這里有幾個(gè)關(guān)鍵區(qū)別:
export interface InjectedCounterProps { value: number; onIncrement(): void; onDecrement(): void; }
我們給將要注入到組件的props聲明一個(gè)interface,該接口將被導(dǎo)出,以便這些props可由被HOC包裹的組件使用:
import makeCounter, { InjectedCounterProps } from "./makeCounter"; interface CounterProps extends InjectedCounterProps { style?: React.CSSProperties; } const Counter = (props: CounterProps) => ({props.value}); export default makeCounter(Counter);
(Component: React.ComponentType
)
我們再次使用泛型,但是這次,你要確保傳入到HOC的組件包含注入到其中的props,否則,你將收到一個(gè)編譯錯(cuò)誤。
class MakeCounter extends React.Component< Subtract, MakeCounterState >
HOC返回的組件使用Piotrek Witek’s的utility-types包中的subtract,它將從傳入組件的props中減去注入的props,這意味著如果它們設(shè)置在生成的包裹組件上,則會收到編譯錯(cuò)誤:
![TypeScript compilation error when attempting to set value on the wrapped component
](https://cdn-images-1.medium.c...*xTKe3DWJdC7nAVQnM4bvbg.png)
結(jié)合這兩種模式,我們將在計(jì)數(shù)器示例的基礎(chǔ)上,允許將最小和最大計(jì)數(shù)器值傳遞給HOC,而HOC又被它截取并使用,而不將它們傳遞給組件:
export interface InjectedCounterProps { value: number; onIncrement(): void; onDecrement(): void; } interface MakeCounterProps { minValue?: number; maxValue?: number; } interface MakeCounterState { value: number; } const makeCounter =( Component: React.ComponentType
) => class MakeCounter extends React.Component< Subtract
& MakeCounterProps, MakeCounterState > { state: MakeCounterState = { value: 0, }; increment = () => { this.setState(prevState => ({ value: prevState.value === this.props.maxValue ? prevState.value : prevState.value + 1, })); }; decrement = () => { this.setState(prevState => ({ value: prevState.value === this.props.minValue ? prevState.value : prevState.value - 1, })); }; render() { const { minValue, maxValue, ...props } = this.props; return (
); } };
這里,Subtract與types交集相結(jié)合,將組件自身的props與HOCs自身的props相結(jié)合,減去注入組件的props:
Subtract& MakeCounterProps
除此之外,與其他兩種模式相比,沒有真正的差異需要強(qiáng)調(diào),但是這個(gè)示例確實(shí)帶來了一些高階組件的問題。這些并不是真正特定于typescript的,但值得詳細(xì)說明,以便我們可以討論如何使用typescript來解決這些問題。
首先,MinValue和MaxValue被HOC攔截,而不是傳遞給組件。但是,你也許希望它們是這樣的,這樣你就可以基于這些值禁用遞增/遞減按鈕,或者向用戶顯示一條消息。如果用HOC,你也可以簡單地修改它來注入這些值,但是如果你沒有(例如,它來自一個(gè)NPM包),這就將會是一個(gè)問題。
其次,由HOC注入的prop有一個(gè)非常通用的名稱;如果要將其用于其他目的,或者如果要從多個(gè)HOC注入prop,則此名稱可能與其他注入的prop沖突。您可以將名稱更改為不太通用的解決方案,但就解決方案而言,這不是一個(gè)很好的解決方案!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/103632.html
原文鏈接: https://medium.com/@jrwebdev/... 和之前的文章一樣,本文也要求你對render props有一些知識背景,如果沒有官方文檔可能會對你有很大的幫助。本文將會使用函數(shù)作為children的render props模式以及結(jié)合React的context API來作為例子。如果你想使用類似于render這樣子的render props,那也只需要把下面例子的c...
摘要:正在暑假中的課多周刊第期我們的微信公眾號,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動(dòng)力。原理微信熱更新方案漲知識了,熱更新是以后的標(biāo)配。 正在暑假中的《課多周刊》(第1期) 我們的微信公眾號:fed-talk,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的動(dòng)力。 遠(yuǎn)上寒山石徑...
摘要:正在暑假中的課多周刊第期我們的微信公眾號,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動(dòng)力。原理微信熱更新方案漲知識了,熱更新是以后的標(biāo)配。 正在暑假中的《課多周刊》(第1期) 我們的微信公眾號:fed-talk,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的動(dòng)力。 遠(yuǎn)上寒山石徑...
摘要:前端日報(bào)精選我是如何實(shí)現(xiàn)的在線升級熱更新功能的張鑫旭鑫空間鑫生活翻譯表單的運(yùn)用第期晉升評審的套路異步編程的四種方式黃博客精選組件設(shè)計(jì)和分解思考掘金中文譯使登錄頁面變得正確掘金前端從強(qiáng)制開啟壓縮探究插件運(yùn)行機(jī)制掘金個(gè)常用的簡 2017-06-28 前端日報(bào) 精選 我是如何實(shí)現(xiàn)electron的在線升級熱更新功能的? ? 張鑫旭-鑫空間-鑫生活【翻譯】React 表單: Refs 的運(yùn)用【...
摘要:高階組件和高階函數(shù)高階組件是編程中的常見模式。您可以將上面例子中的高階函數(shù)用函數(shù)的方式來重新整理如你所見,這就像是一個(gè)高階函數(shù),這個(gè)函數(shù)接受一個(gè)函數(shù),返回一個(gè)新的元素。函數(shù)式編程范例旨在避免在應(yīng)用程序中使用狀態(tài)。 原文:The functional side of React作者:Andrea Chiarelli譯者:博軒 React 是現(xiàn)在最流行的 JavaScript 庫之一。使用...
閱讀 3543·2023-04-25 19:56
閱讀 1660·2021-11-12 10:36
閱讀 1781·2021-11-08 13:19
閱讀 1544·2019-08-30 14:06
閱讀 3032·2019-08-30 11:01
閱讀 1711·2019-08-29 13:23
閱讀 2731·2019-08-29 11:18
閱讀 3422·2019-08-26 13:35