【问题标题】:Typescript: React Context higher order component type errorTypescript:React Context 高阶组件类型错误
【发布时间】:2019-05-31 08:11:37
【问题描述】:

我正在尝试编写一个 React Context HOC 函数,以便我可以使用 Context 包装其他组件,从而允许我将所有通知发送到单个组件。我不得不从几个不同的指南中拼凑出一个可行的解决方案,主要是this one,因为它们都没有以原始形式完全发挥作用。

我最终得到的是这样的:

HOC:

import * as React from "react";
import { INotificationContextState, NotificationConsumer } from "./NotificationContext";

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

export default function withNotificationContext<
  P extends { notificationContext?: INotificationContextState },
  R = Omit<P, 'notificationContext'>
  >(
  Component: React.ComponentClass<P> | React.StatelessComponent<P>
  ): React.SFC<R> {
  return function BoundComponent(props: R) {
    return (
      <NotificationConsumer> 
        {value => <Component {...props} notificationContext={value} />} 
      </NotificationConsumer>
    );
  };
}

上下文:

 interface IMessage {
    message: string;
    key: number;
}

interface INotificationState {
    open: boolean;
    messageInfo: IMessage;
    timeOut: number;
}
interface INotificationContextState extends INotificationState {
    handleClick(message: string): void;
    handleClose(event: React.MouseEvent<HTMLElement>, reason: any): void;
    handleExited(): void;
}

const NotificationContext = React.createContext<INotificationContextState | null>(
    null
);

class NotificationProvider extends React.Component {
    public state: Readonly<INotificationState> = DEFAULT_STATE;
    private queue: IMessage[] = [];

    constructor(props: INotificationContextState) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
        this.handleClose = this.handleClose.bind(this);
    }
    // rest of the class methods...
}

export const NotificationConsumer = NotificationContext.Consumer;

HOC 文件在 {value =&gt; &lt;Component {...props} notificationContext={value} /&gt;} 行中的单词 Component 下给我一个红色下划线

错误内容如下:

类型 'R & { notificationContext: INotificationContextState |空值; }' 不可分配给类型 'IntrinsicAttributes & P & { children?: ReactNode; }'。 类型 'R & { notificationContext: INotificationContextState |空值; }' 不可分配给类型 'P'.ts(2322)

奇怪的是,这个错误并没有阻止我运行应用程序,而且包装器功能完全按照它应该的方式工作,并且被包装的组件能够将通知传递给 Notification 对象。

我的部分麻烦是不熟悉省略/选择语法,并试图在精神上准确地弄清楚“P”在这种情况下的类型定义是什么。我只是不知道它为什么会产生错误,但仍然有效。

【问题讨论】:

    标签: reactjs typescript react-context


    【解决方案1】:

    我目前也没有可行的解决方案。但是现在我迟到了传递给Component 的道具,如下所示:

    <Component {...props as any} notificationContext={value} />
    

    这仍然会给你在渲染方法中的类型,并且会消除错误。

    【讨论】:

      【解决方案2】:

      问题是通用的R。它默认为Omit&lt;P, 'notificationContext'&gt;,但它可以显式设置为任何值。运行代码时您没有任何问题,因为此默认值是您想要的值,但您不希望它是通用的。

      您的 HOC 应该只有一个通用值。这里我使用通用的P 来引用外部组件的props。我们将需要 notificationContext 和一些 props P 的组件转换为只需要 P 的组件。

      我必须将null 包含为notificationContext 属性的可能值之一,因为您的上下文值可能是null

      export default function withNotificationContext<P extends {}>(
          Component: React.ComponentType<P & { notificationContext: INotificationContextState | null }>
      ): React.ComponentType<P> {
          return function BoundComponent(props: P) {
              return (
                  <NotificationConsumer>
                      {value => <Component {...props} notificationContext={value} />}
                  </NotificationConsumer>
              );
          };
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-25
        • 2017-10-12
        • 1970-01-01
        • 1970-01-01
        • 2019-02-10
        • 2020-01-24
        • 1970-01-01
        相关资源
        最近更新 更多