ReactJS 中模态的可重用性
Reusability of a modal in ReactJS
在没有太多代码重复的情况下制作动态模态。我该怎么做?
我使用渲染道具将状态与布局分开。
interface State {
open: boolean;
}
interface InjectedModalProps {
onCloseModal: () => void;
onOpenModal: () => void;
open: boolean;
}
interface ModalProps {
children(props: InjectedModalProps): ReactNode;
}
class ModalProvider extends Component<ModalProps, State> {
state: State = {
open: false
};
onOpenModal = () => {
this.setState({ open: true });
};
onCloseModal = () => {
this.setState({ open: false });
};
render() {
const { open } = this.state;
const { children } = this.props;
return (
<Fragment>
{children({
onCloseModal: this.onCloseModal,
onOpenModal: this.onOpenModal,
open
})}
</Fragment>
);
}
}
const BathroomModal: FunctionComponent<Props> = ({ edit }) => (
<ModalProvider>
{({ onCloseModal, open, onOpenModal }) => {
return (
<Fragment>
<Modal open={open} center onClose={onCloseModal}>
<Container>
<h1>Badkamer toevoegen</h1>
{edit && <DeleteButton>Verwijderen</DeleteButton>}
<Divider />
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Est dolores incidunt ipsa,
earum nobis beatae facilis, dolore harum vitae nihil molestias repudiandae non quisquam
ab. Omnis unde atque voluptate ipsa!
</p>
<ContentBlock>
<h4>Type</h4>
<BathroomInputTypes />
<h4>Toilet</h4>
<Field name="toilet" options={[0, 1, 2, 3, 4, 5]} component={InputWithToggle} />
<h4>Douche</h4>
<Field name="shower" options={[0, 1, 2, 3, 4, 5]} component={InputWithToggle} />
<h4>Bad</h4>
<Field name="bath" options={[0, 1, 2, 3, 4, 5]} component={InputWithToggle} />
</ContentBlock>
<Divider />
<PrimaryButton onClick={onCloseModal} type="button">
{!edit ? 'Badkamer toevoegen' : 'Wijzigingen opslaan'}
</PrimaryButton>
</Container>
</Modal>
<SecondaryButton onClick={onOpenModal} type="button">
Badkamer toevoegen
</SecondaryButton>
</Fragment>
);
}}
</ModalProvider>
);
这就是我的想法。但我认为通过将 Modal 组件提取到 ModalProvider 中可以提高可重用性。我也可以把触发按钮也放在那里。但是,我也希望触发按钮是动态的,这样我就可以使用图标而不是按钮来打开模式。
我认为这是一个好的开始。我建议您考虑模态通常具有的所有东西(在相同的位置)并将它们放入 ModalProvider 中。正如您所建议的,如果您需要带有操作按钮的对话框样式模式,我会在右下角添加关闭按钮以及条件 "OK" 按钮或类似按钮。
这些按钮的文本可以通过道具改变,但它们应该始终是按钮。即使它是一个图标,它也应该在按钮组件中以保持语义 HTML。您可以像这样将关闭按钮值作为道具传递给模态提供程序:
<ModalProvider buttonText={<Icon type='close' {...props} />}>
{... modal contents ...}
</ModalProvider>
在没有太多代码重复的情况下制作动态模态。我该怎么做?
我使用渲染道具将状态与布局分开。
interface State {
open: boolean;
}
interface InjectedModalProps {
onCloseModal: () => void;
onOpenModal: () => void;
open: boolean;
}
interface ModalProps {
children(props: InjectedModalProps): ReactNode;
}
class ModalProvider extends Component<ModalProps, State> {
state: State = {
open: false
};
onOpenModal = () => {
this.setState({ open: true });
};
onCloseModal = () => {
this.setState({ open: false });
};
render() {
const { open } = this.state;
const { children } = this.props;
return (
<Fragment>
{children({
onCloseModal: this.onCloseModal,
onOpenModal: this.onOpenModal,
open
})}
</Fragment>
);
}
}
const BathroomModal: FunctionComponent<Props> = ({ edit }) => (
<ModalProvider>
{({ onCloseModal, open, onOpenModal }) => {
return (
<Fragment>
<Modal open={open} center onClose={onCloseModal}>
<Container>
<h1>Badkamer toevoegen</h1>
{edit && <DeleteButton>Verwijderen</DeleteButton>}
<Divider />
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Est dolores incidunt ipsa,
earum nobis beatae facilis, dolore harum vitae nihil molestias repudiandae non quisquam
ab. Omnis unde atque voluptate ipsa!
</p>
<ContentBlock>
<h4>Type</h4>
<BathroomInputTypes />
<h4>Toilet</h4>
<Field name="toilet" options={[0, 1, 2, 3, 4, 5]} component={InputWithToggle} />
<h4>Douche</h4>
<Field name="shower" options={[0, 1, 2, 3, 4, 5]} component={InputWithToggle} />
<h4>Bad</h4>
<Field name="bath" options={[0, 1, 2, 3, 4, 5]} component={InputWithToggle} />
</ContentBlock>
<Divider />
<PrimaryButton onClick={onCloseModal} type="button">
{!edit ? 'Badkamer toevoegen' : 'Wijzigingen opslaan'}
</PrimaryButton>
</Container>
</Modal>
<SecondaryButton onClick={onOpenModal} type="button">
Badkamer toevoegen
</SecondaryButton>
</Fragment>
);
}}
</ModalProvider>
);
这就是我的想法。但我认为通过将 Modal 组件提取到 ModalProvider 中可以提高可重用性。我也可以把触发按钮也放在那里。但是,我也希望触发按钮是动态的,这样我就可以使用图标而不是按钮来打开模式。
我认为这是一个好的开始。我建议您考虑模态通常具有的所有东西(在相同的位置)并将它们放入 ModalProvider 中。正如您所建议的,如果您需要带有操作按钮的对话框样式模式,我会在右下角添加关闭按钮以及条件 "OK" 按钮或类似按钮。
这些按钮的文本可以通过道具改变,但它们应该始终是按钮。即使它是一个图标,它也应该在按钮组件中以保持语义 HTML。您可以像这样将关闭按钮值作为道具传递给模态提供程序:
<ModalProvider buttonText={<Icon type='close' {...props} />}>
{... modal contents ...}
</ModalProvider>