Возможность повторного использования модала в ReactJS - PullRequest
0 голосов
/ 02 января 2019

Создание модальной динамики без слишком большого дублирования кода. Как мне это сделать?

Я использовал реквизит рендера, чтобы отделить состояние от макета.

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>
);

Итак, это то, что я придумал. Но я думаю, что его можно использовать повторно, извлекая модальный компонент в ModalProvider. Я мог бы также поставить кнопку триггера там. Однако я также хочу, чтобы кнопка триггера была динамичной, поэтому я могу, например, использовать значок вместо кнопки, чтобы открыть модал.

1 Ответ

0 голосов
/ 02 января 2019

Я думаю, что это хорошее начало.Я бы посоветовал вам подумать обо всех вещах, которые модал обычно имеет (в тех же местах), и поместить их в ModalProvider.Как вы предложили, я бы добавил кнопку закрытия, а также условную кнопку «ОК» или что-то подобное в правом нижнем углу, если вам нужен модальный стиль диалога с кнопкой действия.

Текст для этихкнопки, могут быть изменены с помощью реквизита, но они всегда должны быть кнопками.Даже если это значок, он, вероятно, должен быть в компоненте кнопки для поддержки семантического HTML.Вы можете передать значение кнопки закрытия как реквизит модальному провайдеру примерно так:

<ModalProvider buttonText={<Icon type='close' {...props} />}>
  {... modal contents ...}
</ModalProvider>     
...