Как я могу открыть модальное диалоговое окно rect-bootstrap из другого компонента

#javascript #reactjs #modal-dialog #react-bootstrap

#javascript #reactjs #modal-dialog #реакция-bootstrap

Вопрос:

Я изучаю react и имею этот модальный диалог react-bootstrap.

Интересно, как я могу использовать его в другом компоненте.
Вот пример с этой страницы, и это прямо, что компонент позаботится о своем диалоге самостоятельного открытия / закрытия:

 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 подобное отображение / скрытие, подобное этому:
(или это плохой подход?)

 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) , я думаю, что это тот же реквизит, что и что-то

Причина этого в том, что диалоговое окно должно быть открыто из двух разных мест, поэтому я должен сделать так.

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;
    amp;: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;
    amp;:hover {
        background: var(--button-hover-background);
    }
    @media (max-width: 768px) {
        display: none;
    }
`;
export default SignedInButton;
 

Комментарии:

1. в каком компоненте вы хотите открыть / закрыть модальный компонент из примера?

2. Я обновился с помощью кода

3. является ли SignedInButton дочерним или родительским компонентом компонента Example ? потому что в противном случае вам придется создать глобальное хранилище вашего приложения с такими библиотеками, как Redux…

4. да SignedInButton , это родительский элемент, который открывает Dashboard мой диалог. Также я открываю Dashboard из другого компонента, как это делается import Dashboard from './Dashboard'; в обоих компонентах. Это плохо? Я также использую React Redux и могу mapStateToProps открыть диалоговое окно!

Ответ №1:

Насколько я понимаю, вы хотите разделить состояние show между Dashboard и SignInButton , поскольку в данный момент в приложении может быть открыт только один модал.

Вы должны обрабатывать 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>
    );
};
 

Комментарии:

1. Спасибо, но я думаю, что я должен переосмыслить, потому что я получаю два Dashboard компонента, и я думаю, что я мог бы заставить его работать так, чтобы был только один правильный? Я делаю это <Dashboard show={show} onClose={handleClose}/> из двух компонентов! Я использую React-Sight и вижу, что есть два

2. думаете, Redux лучше??

3. Да, он создает два компонента , которые нужно изучить с помощью React-Sight

4. @Kid Также можно использовать redux / react-redux. В этом случае вам необходимо сохранить show логическое значение в хранилище redux и изменить функцию для отправки ДЕЙСТВИЯ.

5. Хотя для этого варианта использования я бы не рекомендовал этого делать. Imo, Redux следует использовать как можно меньше, поскольку это добавляет много сложности при небольшом выигрыше. Обычно он должен быть зарезервирован для переменных аутентификации и других глобальных переменных. Эмпирическое правило заключается в том, что если вы не уверены, нужно ли вам это, вы этого не делаете: redux.js.org/faq/general#when-should-i-use-redux . Однако, если целью является практика, то, безусловно, действуйте