我正在尝试编写一个 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;
Component
HOC 文件在该行中的单词下方给了我一个红色下划线{value => <Component {...props} notificationContext={value} />}
错误如下:
类型 'R & { notificationContext: INotificationContextState | 无效的; }' 不可分配给类型 'IntrinsicAttributes & P & { children?: ReactNode; }'。类型 'R & { notificationContext: INotificationContextState | 无效的; }' 不可分配给类型 'P'.ts(2322)
奇怪的是,这个错误并没有阻止我运行应用程序,而且包装器功能完全按照它应该的方式工作,并且被包装的组件能够将通知传递给 Notification 对象。
我的部分麻烦是不熟悉省略/选择语法,并试图在精神上准确地弄清楚“P”的类型定义在这种情况下是什么。我只是不知道它为什么会产生错误,但仍然有效。