我想将一个组件作为道具传递给另一个组件 我的想法是,我可以传递组件来包装模态的内容(来自材料ui),
这是我尝试过的
import React, { Component } from 'react';
import withWidth, { isWidthDown } from '@material-ui/core/withWidth';
import Button from '@material-ui/core/Button';
import MuiDialog from '@material-ui/core/Dialog';
import { Breakpoint } from "@material-ui/core/styles/createBreakpoints";
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import ButtonSpinner from './ButtonSpinner';
interface OwnProps {
title: string
open: boolean
content: React.ReactNode
isRunning: boolean
confirmText: string
declineText: string
innerWrapper?: React.ReactNode
innerWrapperProps?: any
contentWrapper?: React.ReactNode
onClose(): void
onConfirm(): void
onDecline(): void
width: Breakpoint;
}
const InnerWrapperDefault: React.ReactNode = (p: any) => (
<React.Fragment {...p} />
);
const ContentWrapperDefault: React.ReactNode = (p: any) => (
<DialogContent {...p} />
);
class Dialog extends Component<OwnProps> {
renderContent = () => {
const { content } = this.props;
switch (typeof content) {
case 'string':
return <DialogContentText>{content}</DialogContentText>;
case 'function':
return content();
default:
return content;
}
}
render() {
const {
title,
content,
children,
onClose,
onConfirm = null,
onDecline = null,
confirmText = 'Enig',
declineText = 'Uenig',
isRunning = false,
width,
innerWrapper: InnerWrapper = InnerWrapperDefault,
innerWrapperProps = null,
contentWrapper: ContentWrapper = ContentWrapperDefault,
...rest
} = this.props;
return (
<MuiDialog
fullScreen={isWidthDown('xs', width) ? true : undefined}
onClose={onClose}
disableBackdropClick={isRunning}
disableEscapeKeyDown={isRunning}
aria-labelledby="responsive-dialog-title"
{...rest}
>
<InnerWrapper {...innerWrapperProps}>
<DialogTitle id="responsive-dialog-title">{title}</DialogTitle>
<ContentWrapper>
{content && this.renderContent()}
{children}
</ContentWrapper>
<DialogActions>
<Button onClick={onDecline || onClose} color="primary" disabled={isRunning}>
{declineText}
</Button>
{onConfirm &&
<ButtonSpinner isRunning={isRunning}>
<Button onClick={onConfirm} color="primary" autoFocus disabled={isRunning}>
{confirmText}
</Button>
</ButtonSpinner>
}
</DialogActions>
</InnerWrapper>
</MuiDialog>
);
}
}
export default withWidth()(Dialog);
当我尝试使用此Typescript时,InnerWrapper和ContentWrapper会引发错误
JSX元素类型'...'没有任何构造或调用签名。
有什么建议可以使我工作吗?
编辑:添加了通话示例 可以用这样的东西来调用
return (
<Dialog
confirmText="Yes"
declineText="No"
title="Dialog title"
content="Dialog content"
innerWrapper: (p: any) => <React.Fragment {...p} />,
/>
)
答案 0 :(得分:0)
我认为您的问题是,您正在尝试使用不存在的类型。
在分解道具时,您尝试分配innerWrapper
和contentWrapper
的类型InnerWrapper
和ContentWrapper
:
const {
...
innerWrapper: InnerWrapper = DefaultInnerWrapper,
contentWrapper: ContentWrapper = DefaultContentWrapper
...
} = this.props;
但是这些类型没有定义(例如,作为接口或从模块导入)。
如果您只是删除它们并解构道具,就可以了:
const {
...
innerWrapper = DefaultInnerWrapper,
contentWrapper = DefaultContentWrapper
...
} = this.props;
然后另一个问题是,您试图将它们呈现为组件:
<InnerWrapper {...innerWrapperProps}/>
...
<ContentWrapper/>
意味着您尝试从非引用对象创建JSX元素。如果要渲染它们,则应为它们创建组件/功能。我认为您可以在道具中将 innerWrapper
重命名为InnerWrapper
,将contentWrapper
重命名为ContentWrapper
,以将其用作组件。
编辑:因此,我了解了使用ES6销毁时的重命名。
但是要为您提供帮助:如已here所述,您应该使用React.ComponentType
而不是React.ReactNode
作为包装类型,以解决错误消息。