HOC 并不是一个很具体的组件, 它仅仅是一个在 React 对组件进行重用的设计方法, 这种设计方法是由 React 自身的设计思想而必然会产生. 具体而言, 高阶组件就是一个函数, 它接收一个组件做为参数, 并返回一个组件, 这种设计方法的利用, 我们可以在很多开源库中看到, 如: redux connect , 它们都做为一个高阶组件而存在.
那么在 TypeScript 的世界中, 我们改如何去写一个高阶组件呢?
举一个例子:
我们设计一个高阶组件, 它来接收一个 styles 对象, 并且传递给你传入的组件, 这个 styles 对象定义了高宽背景颜色. 首先, 我们写一个 withStyle 函数, 它接收一个 StyleRules 类型, 并且返回一个范型函数, 这个范型函数可以接收任意一个 React 组件.
定义 StyleRules:
- interface IStyleRules {
- width?: string;
- height?: string;
- backgroundColor?: string;
- }
- export type StyleRules = IStyleRules;
然后我们定义一个 AnyComponent:
- type AnyComponent < P = any > =|(new(props: P) = >React.Component) | ((props: P & {
- children ? :React.ReactNode
- }) = >React.ReactElement < any > |null);
这个 AnyComponent 用于范型函数接收参数的类型.
最后, 我们定义一个 WithStyle 的函数别名:
type WithStyle = (styles: IStyleRules) => <P extends IStylesProps> (Component: AnyComponent<P>) => AnyComponent<P>;
当然, 这里我也定义了一个 IStylesProps 用于简单的范型继承, 因为我们会将 styles 当 props 传入给传入的组件:
- export const withStyle: WithStyle = (styles: IStyleRules) => (Component: AnyComponent) => {
- class HOC extends React.Component<{}> {
- public styles: IStyleRules;
- constructor(props: {}) {
- super(props);
- this.styles = styles;
- }
- public render() {
- return <Component styles={this.styles} />;
- }
- }
- return HOC;
- };
最后, 我们该如何使用 withStyle 函数呢?
- import * as React from "react";
- import { withStyle, StyleRules, IStylesProps } from "./hoc";
- const s: StyleRules = {
- width: "100px",
- height: "200px",
- backgroundColor: "#980987",
- };
- type IHOCProps = IStylesProps;
- class HOCComponent extends React.Component<IHOCProps> {
- constructor(props: IHOCProps) {
- super(props);
- }
- public render() {
- // console.log(this.props);
- return (
- <div style={this.props.styles}>...</div>
- );
- }
- }
- export default withStyle(s)(HOCComponent);
当然我们的这个案例中是一个非常简单的高阶组件, 正常情况下, 你应该要处理好容器组件中的生命周期, 这些会有一些额外的事情. 这个案例很好的利用了高阶组件这样的设计方法, 完成了它想要的结果.
来源: https://juejin.im/entry/5ba33e12e51d450e4369456a