網站首頁 編程語言 正文
高階組件
高階組件(HOC)是一個接受組件作為參數并返回一個新組件的函數,如果多個組件有相同的邏輯,將這些邏輯用函數封裝,使它們能跨組件共用,這種用法稱為高階組件。下面的代碼演示什么是高階組件:
export default function WithPrintLog(InnerComponent) { return class extends React.Component{ componentDidMount() { console.log('我被裝載了') } render() { return (<InnerComponent {...this.props}/>) } } }
上述 WithPrintLog 是高階組件,它不改變 InnerComponent 在界面上的顯示,而是等 InnerComponent 裝載之后在控制臺打印'我被裝載了'。
總體而言,高階組件可以被分為兩大類。
- 增強型:給組件增加額外的功能,比如前面舉例的 WithPrintLog。
- 注入型:給組件注入額外的 props,比如 Redux 的 connect。
接下來,結合 TypeScript 分別介紹增強型和注入型高階組件。
增強型高級組件
增強型高階組件還是以 WithPrintLog 為例,只是在前面的基礎上增加 loading 效果,代碼如下:
interface Props { loading?: boolean } export default function WithPrintLog<P extends {}>(InnerComponent: React.ComponentType<P>) { return class extends React.Component<P & Props, never> { componentDidMount() { console.log('我被裝載了') } render() { const {loading, ...props} = this.props return (loading ? <div>loading...</div> : <InnerComponent {...(props as P)}/>) } } }
React.ComponentType<P>
是 React.ComponentClass<P> | React.FunctionComponent<P>
的別稱,因此 WithPrintLog 的參數只能是類組件或函數組件。分析上述代碼中的類型注解,類型參數 P
注解 InnerComponent 的 props。P & Props
注解返回值的 props,所以使用返回值時,除了傳 InnerComponent 所需的 props 還要傳 loading 字段。
注入型高階組件
注入型高階組件比增加強高階組件更常見,類型定義也更復雜,下面定義的 WithSubmitLog 便是一個注入型高階組件,代碼如下:
export interface InjectedProps { submitLog: (data: string) => void } export function WithSubmitLog<P extends InjectedProps>(InnerComponent: React.ComponentType<P>) { return class extends React.Component<Omit<P, keyof InjectedProps >, never> { submitLog = (data: string) => { /**todo*/ } render() { const props = ({ ...this.props, submitLog: this.submitLog }) as P return <InnerComponent {...props}/> } } }
<P extends InjectedProps>(InnerComponent: React.ComponentType<P>)
使用了泛型約束,它約束類型參數P
必須包含 InjectedProps 接口中的字段,所以InnerComponent 組件的 props 中必須存在 submitLog 字段。Omit<P, keyof InjectedProps>
表示從類型P
中剝除 InjectedProps 接口中的字段,所以使用 WithSubmitLog 返回的組件時,不必傳 submitLog 字段。
高階組件 VS Render Props
高階組件和 Render Props 都是提高代碼復用的有效手段,高階組件屬于靜態組合,Render Props 屬于動態組合。下面使用 Render Props 去改造上面的注入型高階組件 WithSubmitLog,代碼如下:
interface Props { render: (submitLog: (data: string) => void) => React.ReactNode; } class SubmitLogFromRender extends React.Component<Props , never> { submitLog = (data: string): void => { /**todo*/ } render(): React.ReactNode { return this.props.render(this.submitLog) } }
與前面的 WithSubmitLog 相比,SubmitLogFromRender 簡單得多,一眼就能看出它能接受那些屬性,但是要明白高階組件返回的組件能接收哪些屬性就沒那么容易,另外由于 SubmitLogFromRender 組件的 render 屬性只是一個函數,所以它的值能來自第三方庫,CDN,甚至可以在程序運行時根據不同的情況動態加載不同的函數。
總結
高階組件能實現的效果 Render Props 都能實現,但反過來,Render Props 能實現的效果高階組件不一定能實現,這源于 Render Props 是動態組合,而高階組件是靜態組合。在日常開發中,我的最大感受是,分析高階組件能接受的屬性比分析運用 Render Props 技術組件的難度大得多。
原文鏈接:https://juejin.cn/post/7165661340453830670
相關推薦
- 2022-05-19 分享Python獲取本機IP地址的幾種方法_python
- 2022-04-12 C#實現六大設計原則之單一職責原則_C#教程
- 2022-10-31 C#?如何調用python腳本_C#教程
- 2022-05-25 ASP.NET?MVC+EF實現異步增刪改查_實用技巧
- 2023-01-03 C語言中的putchar函數示例_C 語言
- 2022-03-19 MongoDB數據庫授權認證的實現_MongoDB
- 2022-09-27 C#中的const和readonly關鍵字詳解_C#教程
- 2022-12-05 GPU狀態監測?nvidia-smi?命令的用法詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支