如何从另一个组件打开一个 rect-bootstrap 模态对话框

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

我学习了 React 并拥有这个 react-bootstrap 模态对话框。

我想知道如何在另一个组件中使用它。
这是该页面的示例,很简单,组件会自行处理 open/close 对话框:

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

但是如果打开对话框的 Button 在另一个 Component 中,我想发送一个 props 像 show/hide 这样的:
(或者这是一个糟糕的做法?)

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

如您所见,这将不起作用 show 已经定义...
我尝试了多种方法来理解这样的逻辑,例如:

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>

我打开了,但它没有在 setShow(false) 上呈现,我认为这是同一个道具的东西

原因是对话框必须从两个不同的位置打开,所以我必须这样做。

请在此处提供我要打开对话框的完整代码:
(此组件可以从两个位置单独打开)

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;

这是打开对话框的一个位置:它有 Button 打开

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;

据我了解,您想在 DashboardSignInButton 之间共享 show 的状态,因为应用程序中当时只能打开一个模式。

您应该在顶部组件中处理 show 状态、handleShow 函数和 handleClose 函数,在本例中,它是 SignedInButton。然后,您应该将 show 布尔值和 handleClose 函数作为道具传递给子组件,在本例中为 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>
    );
}
// ...

仪表板

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