尝试在react / TS应用程序中使用react-toastr。但是提供的示例(https://tomchentw.github.io/react-toastr/)不起作用。
我像这样导入:
import { ToastContainer, ToastMessageAnimated } from "react-toastr";
并像这样使用:
class RegistrationSelectionPage extends React.Component<{}, {}> {
public render() {
let container: ToastContainer | null;
return (
<section className="RegistrationSelectionPage">
<ToastContainer
ref={ref => container = ref}
className="toast-top-right"
toastMessageFactory={ToastMessageAnimated}
/>
<button onClick={() => container && container.warning('No connection', 'Error!')}>Click me</button>
...
我收到此错误:
Uncaught TypeError: Cannot call a class as a function
at ./node_modules/babel-runtime/helpers/classCallCheck.js.exports.default
...
我应该在ToastMessageAnimated
上调用哪个函数?
请提供完整的工作示例,谢谢:)
答案 0 :(得分:1)
@types不正确,看起来他们允许any
toastMessageFactory
道具来解决对正确类型的误解,导致各种混淆
从文档中可以看出React工厂函数https://tomchentw.github.io/react-toastr/#toastmessage
默认值为React.createFactory(ToastMessageAnimated)
,它是从lib中定义的Component类创建的工厂函数。这确实可以满足您当前的目的,但是当前的def会强制您指定它,并接受any
,这完全违背了这一点,所以让我们看看修复defs
从默认值我们可以推导出toastMessageFactory
应该是React.Factory<ToastMessageProps>
的类型,它是来自具有基本ToastMessageProps
的lib的一个组件类的工厂
查看源代码中的道具和组件(很高兴用Flow编写,这样就变得容易了)我们可以将@type/react-toastr
defs改进为......
import { Component, ReactHTML, Factory, ReactNode } from 'react'
export interface ToastContainerProps {
toastType?: IconClassNames
id?: string
preventDuplicates?: boolean
toastMessageFactory?: Factory<ToastMessageProps>
newestOnTop?: boolean
onClick?: Function
}
export class ToastContainer extends Component<ToastContainerProps> {
error: <P extends ToastMessageProps>(message: ReactNode, title: ReactNode, optionsOverride?: Partial<P>) => void
info: <P extends ToastMessageProps>(message: ReactNode, title: ReactNode, optionsOverride?: Partial<P>) => void
success: <P extends ToastMessageProps>(message: ReactNode, title: ReactNode, optionsOverride?: Partial<P>) => void
warning: <P extends ToastMessageProps>(message: ReactNode, title: ReactNode, optionsOverride?: Partial<P>) => void
clear: () => void
}
export interface IconClassNames {
error: string
info: string
success: string
warning: string
}
export interface ToastMessageProps {
className?: string,
type: string,
iconClassNames?: IconClassNames,
iconClassName?: string,
closeButton?: boolean,
onCloseClick?: Function,
title?: any,
titleClassName?: string,
message?: any,
messageClassName?: string
}
export interface ToastMessageAnimatedProps extends ToastMessageProps {
className?: string,
showAnimation?: string,
hideAnimation?: string,
timeOut?: number,
extendedTimeOut?: number,
tapToDismiss?: boolean,
onRemove: Function,
onClick?: Function,
onCloseClick?: Function,
}
export interface ToastMessageQueryProps extends ToastMessageProps {
style?: object,
showMethod?: string,
showDuration?: number,
showEasing?: string,
hideMethod?: string,
hideDuration?: number,
hideEasing?: string,
timeOut?: number,
extendedTimeOut?: number,
tapToDismiss?: boolean,
onRemove: Function,
onClick?: Function,
onCloseClick?: Function,
}
export class ToastMessageAnimated extends Component<ToastMessageAnimatedProps> {}
export class ToastMessageQuery extends Component<ToastMessageQueryProps> {}
您现在可以在自己的组件中正确使用这些...
import {
ToastContainer,
ToastMessageAnimated,
ToastMessageAnimatedProps // import this too for stricter typing of factory
} from "react-toastr"
//... all exactly same as your example, except...
<ToastContainer ref={ref => container = ref}
toastMessageFactory={React.createFactory<ToastMessageAnimatedProps>(ToastMessageAnimated)}
/>
<button onClick={() => container && container.warning<ToastMessageAnimatedProps>('No connection', 'Error!', {className: 'toast-top-right'})}>Click me</button>
此处我们还严格键入警告选项,并在其中设置className
(这被设置为错误的容器道具,因此不会被应用)
现在,您还可以将JSX组件作为消息和标题传递
container.warning<ToastMessageAnimatedProps>(<div>No connection</div>, <h1>Error!</h1>, {className: 'toast-top-right'})