2

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

我最终得到的是这样的:

特设:

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;

ComponentHOC 文件在该行中的单词下方给了我一个红色下划线{value => <Component {...props} notificationContext={value} />}

错误如下:

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

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

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

4

2 回答 2

0

问题是通用的R。它默认为Omit<P, 'notificationContext'>,但可以显式设置为任何值。运行代码时您不会遇到任何问题,因为此默认值是您想要的值,但您不希望它是通用的。

您的 HOC 应该只有一个通用值。这里我使用泛型P来指代外部组件的 props。我们将需要的组件notificationContext和一些 propsP转换为只需要这些 props 的组件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>
        );
    };
}
于 2021-01-31T22:52:01.153 回答
0

我目前也没有一个可行的解决方案。但是现在我迟到了传递给Component这样的道具:

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

这仍然会为您提供 render 方法中的类型并消除错误。

于 2019-01-16T10:49:52.957 回答