简体   繁体   中英

How can I open a rect-bootstrap modal dialog from another Component

I learn react and have this react-bootstrap Modal dialog.

I wonder how can I use it in another Component.
Here is the example from that page and it's straight forward the Component take care of it's self open/close dialog:

function Example() {
  const [show, setShow] = useState(false);

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  return (
    <>
      <Button variant="primary" onClick={handleShow}>
        Launch demo modal
      </Button>

      <Modal show={show} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Modal heading</Modal.Title>
        </Modal.Header>
        <Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={handleClose}>
            Close
          </Button>
          <Button variant="primary" onClick={handleClose}>
            Save Changes
          </Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

render(<Example />);

But what if the Button that open the dialog is in another Component and I want to send in a props like show/hide like this:
(or is this a bad approche?)

function Example(props) {
  const{ show } = props;

  const [show, setShow] = useState(false);

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  return (
    <>
      <Modal show={show} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Modal heading</Modal.Title>
        </Modal.Header>
        <Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
        <Modal.Footer>
          <Button variant="secondary" onClick={handleClose}>
            Close
          </Button>
          <Button variant="primary" onClick={handleClose}>
            Save Changes
          </Button>
        </Modal.Footer>
      </Modal>
    </>
  );
}

render(<Example />);

As you see this will not work the show is already defined...
I have tried a number of way to understand the logic like this for example:

function Example(props) {
    let { show } = props;
    const [showing, setShow] = useState(false);
    const handleClose = () => {
        show = false;
        setShow(false);
    };
    return (
        <div>
            <Modal show={show || showing} onHide={handleClose} centered>

I open but it does not render on setShow(false) I think it's the same prop's something

The reason for this is that the dialog must be opened from two different locations so I must do like this.

Please advice here is full code in where I want to open the dialog:
(this Component can be opened individually from two locations)

import React, { useState } from 'react';
import { Modal } from 'react-bootstrap';
import { Offline } from 'react-detect-offline';
import styled from 'styled-components';
import ProfilePageAuthenticated from './ProfilePageAuthenticated';
import ProfilePageAnonymous from './ProfilePageAnonymous';
import LinkAccounts from './LinkAccounts';
import SummaryPage from './SummaryPage';
import ContributePage from './ContributePage';

const Dashboard = props => {
    const { show } = props;
    const [showing, setShow] = useState(false);
    const handleClose = () => setShow(false);

    return (
        <div>
            <Modal show={show} onHide={handleClose} centered>
                <Modal.Header closeButton>
                    <Modal.Title>User Profile</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <ProfilePageAuthenticated />
                    <ProfilePageAnonymous />
                    <LinkAccounts />
                    <SummaryPage />
                    <ContributePage />
                    <Offline>
                        <div
                            style={{
                                marginTop: 40,
                                display: 'flex',
                                alignItems: 'center',
                                justifyContent: 'center',
                                color: 'red',
                            }}
                        >
                            It appears you don't have an active Internet connection!
                        </div>
                    </Offline>
                </Modal.Body>
                <Modal.Footer>
                    <Button variant="secondary" onClick={handleClose}>
                        Close
                    </Button>
                </Modal.Footer>
            </Modal>
        </div>
    );
};

const Button = styled.button`
    height: 68px;
    display: flex;
    align-items: center;
    margin-top: 0px;
    margin-bottom: 0px;
    margin-left: 5px;
    color: var(--button-text-color);
    padding: 0 1rem;
    justify-content: space-between;
    background: var(--button-background);
    border-radius: 6px;
    &:hover {
        background: var(--button-hover-background);
    }
    @media (max-width: 768px) {
        display: none;
    }
`;
export default Dashboard;

Here one location that open the dialog: and it hase the Button who open

import React, { useState } from 'react';
import styled from 'styled-components';
import Dashboard from './Dashboard';

function SignedInButton() {
    const [show, setShow] = useState(false);
    const handleShow = () => setShow(true);

    return (
        <div>
            <Button className="button is-large" onClick={handleShow}>
                <span className="icon is-medium">
                    <i className="fas fa-user" />
                </span>
            </Button>
            <Dashboard show={show} />
        </div>
    );
}

const Button = styled.button`
    height: 68px;
    display: flex;
    align-items: center;
    margin-top: 0px;
    margin-bottom: 0px;
    margin-left: 5px;
    color: var(--button-text-color);
    padding: 0 1rem;
    justify-content: space-between;
    background: var(--button-background);
    border-radius: 6px;
    &:hover {
        background: var(--button-hover-background);
    }
    @media (max-width: 768px) {
        display: none;
    }
`;
export default SignedInButton;

From what I understand, you want to share the state of show between the Dashboard and SignInButton , as only one modal can be open at the time in the application.

You should handle the show state, handleShow function and handleClose function in the top component, which, in this case, is SignedInButton . Then, you should pass show boolean and handleClose function as props down to the child component, in this case Dashboard .

SignedInButton

function SignedInButton() {
    const [show, setShow] = useState(false);
    const handleShow = () => setShow(true);
    const handleClose = () => setShow(false);

    return (
        <div>
            <Button className="button is-large" onClick={handleShow}>
                <span className="icon is-medium">
                    <i className="fas fa-user" />
                </span>
            </Button>
            <Dashboard show={show} onClose={handleClose}/>
        </div>
    );
}
// ...

Dashboard

const Dashboard = props => {
    const { show, onClose } = props;

    return (
        <div>
            <Modal show={show} onHide={onClose} centered>
                <Modal.Header closeButton>
                    <Modal.Title>User Profile</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <ProfilePageAuthenticated />
                    <ProfilePageAnonymous />
                    <LinkAccounts />
                    <SummaryPage />
                    <ContributePage />
                    <Offline>
                        <div
                            style={{
                                marginTop: 40,
                                display: 'flex',
                                alignItems: 'center',
                                justifyContent: 'center',
                                color: 'red',
                            }}
                        >
                            It appears you don't have an active Internet connection!
                        </div>
                    </Offline>
                </Modal.Body>
                <Modal.Footer>
                    <Button variant="secondary" onClick={onClose}>
                        Close
                    </Button>
                </Modal.Footer>
            </Modal>
        </div>
    );
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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