简体   繁体   English

防止打开 Semantic-ui React 模态

[英]Prevent Semantic-ui React modal from opening

In the below example, opening the modal triggers an API call to load address data that then gets displayed inside the modal.在下面的示例中,打开模态会触发 API 调用以加载地址数据,然后这些数据会显示在模态中。 If the API call fails (or returns nothing) I want to prevent the modal from actually opening.如果 API 调用失败(或什么都不返回),我想阻止模态实际打开。 How can I achieve this?我怎样才能做到这一点? So far I've got:到目前为止,我有:

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

As you can see from the above I've tried to prevent the modal from opening by catching the error正如你从上面看到的,我试图通过捕捉错误来防止模式打开

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

Unfortunately this doesn't actually work, the modal still opens.不幸的是,这实际上不起作用,模态仍然打开。 Ideally I want that when the modal gets opened but the API call fails it just stops rendering the child elements (ie the modal stays closed).理想情况下,我希望当模式打开但 API 调用失败时,它只是停止呈现子元素(即模式保持关闭)。 How can I do this?我怎样才能做到这一点? Thank you!谢谢!

Update 28 Jan 2020 2020 年 1 月 28 日更新

I've found the issue.我找到了问题所在。 setState sets open to false for ModalExample instead of Modal . setState 将ModalExample open 设置为 false 而不是Modal How can I set it for Modal instead?我该如何为 Modal 设置它? If I duplicate the open property at the ModalExample level and pass it to Modal, eg如果我在 ModalExample 级别复制open属性并将其传递给 Modal,例如

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

then I also have to duplicate all the open/close handling logic that already exists in Modal .然后我还必须复制Modal中已经存在的所有打开/关闭处理逻辑。 Seems like the wrong approach.似乎是错误的方法。

As mentioned in the update, the problem was that I was only controlling the open prop in the parent component but it wasn't linked up to the child component (the actual semantic-ui-react modal).正如更新中提到的,问题是我只控制父组件中的 open 道具,但它没有链接到子组件(实际的语义 UI 反应模式)。 I've solved this in the following way:我已经通过以下方式解决了这个问题:

  • add open to parent component state添加open到父组件状态
  • pass open prop to the child component (modal)open prop 传递给子组件(模态)
  • add method to change the parent open prop whenever the user tries to close the modal添加方法以在用户尝试关闭模态时更改父open道具

This may not be the best solution but it worked for me.这可能不是最好的解决方案,但它对我有用。

The example above now looks like this:上面的例子现在看起来像这样:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM