#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 . Однако, если целью является практика, то, безусловно, действуйте