#reactjs #redux #react-redux
Вопрос:
Я сделал модальное окно с React и Redux. Я хотел избежать локального состояния, поэтому использовал Redux, чтобы сохранить информацию о том, открыт модал или нет.
Modal.js
import React from 'react';
import './Modal.css';
import {useSelector, useDispatch} from 'react-redux';
import { isModalOpen } from '../actions/index';
const Modal = (props) => {
const dispatch = useDispatch();
const modalOpen = useSelector(state => state.isModalOpen);
const closeModal = () => {
dispatch(isModalOpen(false));
}
if(!modalOpen) return null;
return(
<div id="modal-container" onClick={closeModal}>
<div id="modal">
<span onClick={closeModal}>Close</span>
<h2>Modal</h2>
<p>description</p>
{props.children}
</div>
</div>
);
}
export default Modal;
App.js
import React from 'react';
import { useDispatch} from 'react-redux';
import Modal from './Modals/Modal';
import Contents1 from './Modals/Contents1';
import Contents2 from './Modals/Contents2';
import { isModalOpen } from './actions/index';
import './App.css';
const App = () => {
const dispatch = useDispatch();
const openModal1 = () => {
dispatch(isModalOpen(true));
};
const openModal2 = () => {
dispatch(isModalOpen(true));
};
return (
<div>
<button onClick={openModal1}>Open Modal 1</button>
<Modal>
<Contents1 />
</Modal>
<button onClick={openModal2}>Open Modal 2</button>
<Modal>
<Contents2 />
</Modal>
</div>
);
}
export default App;
Когда у меня есть одна кнопка, открывающая один модальный режим, все в порядке. Однако, если я хочу, чтобы другая кнопка открывала модальное окно с другим содержанием2, это не работает.
Как изменить код, чтобы первая кнопка открывала Модал с Содержанием1, а вторая кнопка открывала Модал с Содержанием2?
Большое спасибо.
Комментарии:
1. Что, если вы нажмете кнопку
Open Modal 2
и затемOpen Modal 1
? открывает ли он 2-й, а дозент открывает 1-й? Если это так, это может быть просто государственная вещь. Вы не сбрасываете состояние redux изtrue
tifalse
при закрытии модального режима. Следовательно, отправка одного и того же значения не вызывает повторной отрисовки. Если это так, вам нужно запустить отправку, чтобы установить состояниеfalse
на модальное закрытие. Простой тест:console.log(isModalOpen )
внутриopenModal1
иopenModal2
доdispatch
, чтобы проверить, является ли начальное состояниеfalse
или какое-то другое значение2. Оба режима открываются при нажатии любой из кнопок. Модальности перекрывают друг друга, и та, что с Содержанием2, находится сверху.
Ответ №1:
Почему вы избегали использования местного штата?? Поскольку оба модала используются внутри этого компонента, гораздо разумнее использовать локальное состояние, чем хранить его в глобальном состоянии. Это также делает код короче и чище IMO.
const App = () => {
const [currentModal, setCurrentModal] = useState(null);
return (
<div>
<button onClick={() => setCurrentModal('modal1')}>Open Modal 1</button>
<button onClick={() => setCurrentModal('modal2')}>Open Modal 2</button>
{currentModal ? (
<Modal handleModalClose={() => setCurrentModal(null)}>
{currentModal === "modal1" ? <Contents1 /> : <Contents2 />}
</Modal>
)}
</div>
);
}
export default App;
И тогда modal.js
файл также будет упрощен
const Modal = props => (
<div id="modal-container" onClick={props.handleModalClose}>
<div id="modal">
<span onClick={props.handleModalClose}>Close</span>
<h2>Modal</h2>
<p>description</p>
{props.children}
</div>
</div>
);
export default Modal;
Если вы все еще хотите использовать redux, вам следует сохранить имя модала вместо простого флага open и иметь сопоставление между именами модалов и компонентами
import modals from '../utils/modals'
const Modal = (props) => {
const dispatch = useDispatch();
const currentModal = useSelector(state => state.currentModal);
if(!currentModal) return null;
return(
<div id="modal-container" onClick={closeModal}>
<div id="modal">
<span onClick={closeModal}>Close</span>
<h2>Modal</h2>
<p>description</p>
{modals[currentModal}
</div>
</div>
);
}
export default Modal;
И modals.js
экспортировал бы такой объект, как этот
export default modals = {
modal1: <ModalContent1 />,
...
}
Ответ №2:
В состоянии Redux вам нужно будет обрабатывать несколько модалов с помощью некоторого уникального идентификатора, в противном случае вы указываете, что любой модал должен быть открыт. Затем передайте «идентификатор» в вашей функции отправки.
Комментарии:
1. Большое вам спасибо за вашу помощь, ребята. Я просто хотел иметь модальный фрейм «Модальный» и включать в него различное содержимое. И я хотел знать в каждый момент, открыт ли этот модал, установив флаг в магазине Redux. Похоже, он работает только с одним модальным для каждого компонента.