Предотвратить открытие Semanti c -ui React модал - PullRequest
0 голосов
/ 28 января 2020

В приведенном ниже примере при открытии модального окна запускается вызов API для загрузки данных адреса, которые затем отображаются внутри модального окна. Если вызов API не удается (или ничего не возвращает), я хочу предотвратить фактическое открытие модального режима. Как мне этого добиться? Пока что у меня есть:

import React from 'react';
import { Button, Modal } from 'semantic-ui-react';

export default class ModalExample extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            address :[{
                house_name: "",
                house_number: "",
                street_line_1: "",
                street_line_2: "",
                town: "",
                postcode: "",
                country_name: "",
            }],
        }
    }

    fetchAddress () {
        fetch('exampleurl', {crossDomain:true, method:'GET',})
        .then(response => response.json())
        .then(address => {
            if (address.length > 0) {
                this.setState({address})
            } else {  //empty server response
                throw new Error("The sever returned no data.")
            }})
        .catch(error => {
            this.setState({open: false})
            // find a way to stop rendering of the component
        })
    }

    render () {
        const address = this.state.address[0]

        return (
            <Modal trigger={<Button>More Details...</Button>} onOpen={() => this.fetchAddress()} closeIcon>
                <Modal.Header>Heading</Modal.Header>
                <Modal.Content>
                    <Modal.Description>
                    ...
                    </Modal.Description>
                </Modal.Content>
            </Modal>
        );
    }
}

Как вы можете видеть из вышесказанного, я пытался предотвратить открытие модала, обнаружив ошибку

.catch(error => {
            this.setState({open: false})
            // find a way to stop rendering of the component
        })

К сожалению, этого не происходит на самом деле работает, модал все еще открывается. В идеале я хочу, чтобы, когда модальное окно было открыто, но вызов API завершился неудачей, оно просто перестало отображать дочерние элементы (т. Е. Модальное устройство остается закрытым). Как я могу это сделать? Спасибо!

Обновление 28 января 2020 г.

Я нашел проблему. setState устанавливает значение false для ModalExample вместо Modal. Как я могу установить его вместо модального? Если я продублирую свойство open на уровне ModalExample и передам его в Modal, например,

<Modal [...] open={this.state.open}>

, тогда мне также придется дублировать все логи обработки открытия / закрытия c который уже существует в Modal. Похоже, неправильный подход.

1 Ответ

0 голосов
/ 01 февраля 2020

Как упоминалось в обновлении, проблема заключалась в том, что я контролировал только открытую подпорку в родительском компоненте, но он не был связан с дочерним компонентом (действительный мод semanti c -ui-реагировать). Я решил это следующим образом:

  • добавить open в состояние родительского компонента
  • передать open реквизит для дочернего компонента (модальный)
  • добавьте метод для изменения родительского элемента open prop каждый раз, когда пользователь пытается закрыть модальное

Возможно, это не лучшее решение, но оно сработало для меня.

Пример выше теперь выглядит так:

import React from 'react';
import { Button, Modal } from 'semantic-ui-react';

export default class ModalExample extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            address :[{
                house_name: "",
                house_number: "",
                street_line_1: "",
                street_line_2: "",
                town: "",
                postcode: "",
                country_name: "",
            }],
            open: false,
        }
    }

    fetchAddress () {
        fetch('exampleurl', {crossDomain:true, method:'GET',})
        .then(response => response.json())
        .then(address => {
            if (address.length > 0) {
                this.setState({address})
            } else {  //empty server response
                throw new Error("The sever returned no data.")
            }})
        .catch(error => {
            this.setState({open: false})
            // find a way to stop rendering of the component
        })
    }

    closeModal () {
        this.setState({open:false})  // If modal was closed inside the modal, update the parent state
    }

    render () {
        const address = this.state.address[0]

        return (
            <Modal trigger={<Button>More Details...</Button>} 
                   onOpen={() => this.fetchAddress()}
                   onClose={() => this.closeModal()}
                   closeIcon
                   open={this.state.open}>
                <Modal.Header>Heading</Modal.Header>
                <Modal.Content>
                    <Modal.Description>
                    ...
                    </Modal.Description>
                </Modal.Content>
            </Modal>
        );
    }
}
...