React 中高阶组件的默认值

Default values for higher order components in React

假设我有一个高阶组件:

interface MyHOCInterface { title: string }

export function wrapMyHoc<T extends MyHOCInterface>(
  Component: React.ComponentType<T>,) {
  return class extends React.Component<T> {
    state = {...this.props,}
    const {title} = {...(this.props as T)}
    render() {
      return(
        <>
          {title}
          <Component {...this.props as T} />
        </>
      )
    }
  }
}

然后是我这样定义的一些组件:

export const MyFirstComponent = wrapMyHoc(
  (props: MyHocInterface) => (<></>)
)

export const MySecondComponent = wrapMyHoc(
  (props: MyHocInterface) => (<></>)
)

自然地,这将允许我像下面这样渲染它们。我注意到这段代码(MySecondComponent 组件的所有实例始终具有相同的标题):

<>
  <MyFirstComponent title='my first title'/>
  <MySecondComponent title='my second title' />
  <MySecondComponent title='my second title' />
  <MySecondComponent title='my second title' />
</>

我将如何设置默认值,以便我可以编写以下内容并仍然使用 my second title 作为标题:

<> <MySecondComponent /> </>

根据您最后关于 MySecondComponent 使用另一个 HOC 的评论,我认为您可以这样做:

const doubeWrappedHOC = Component => {
  const HOC = wrapMyHoc(Component);
  return props =>
    props.title === undefined &&
    Component === MySecondComponent
      ? HOC({ ...props, title: defaultValue })
      : HOC(props);
};

它不在 TypeScript 中,MySecondComponent 必须在 scope/inported 中,但您的所有组件都可以使用此 HOC,而不是仅为 MyCompnent 使用另一个 HOC。如果你想用不同的 HOC 创建 MyCompnent,那么你可以省略 && Component === MySecondComponent。再次使用逻辑 wrapMyHoc 并为标题设置默认值。