Если у вас есть несколько модалов, и только один из них должен открываться одновременно, то вы должны использовать одно состояние, в котором хранится информация о том, какой модальный режим открыт, что-то вроде строки, имеющей идентификатор модального окна.Однако, если вы хотите открыть несколько модалов, вы должны хранить isOpen prop по-другому
. В первом случае вы должны написать свой код как
const App = () => {
const [openModal, toggleModal] = useState('');
return (
<div>
<button onClick={() => toggleModal('first')}>Open First Modal</button>
<button onClick={() => toggleModal('second')}>Open Second Modal</button>
<FirstModal
{...props}
show={openModal === 'first'}
toggleModal={toggleModal}
/>
<SecondModal
{...props}
show={secondModalOpen}
toggleModal={toggleModal}
/>
</div>
)
}
const FirstModal = (props) => {
const { toggleModal, ...rest } = props;
return (
<Modal
{ ...rest }
show={firstModalOpen}
onHide={() => props.toggleModal('first')}
>
First modal content...
</Modal>
)
}
const SecondModal = (props) => {
const { toggleModal, ...rest } = props;
return (
<Modal
{ ...rest }
show={secondModalOpen}
onHide={() => props.toggleModal('second')}
>
Second modal content...
</Modal>
)
}
Во втором случае это будет так, как выВы написали в своем примере, единственная оптимизация, которую вы можете сделать для второго случая, - это сохранить массив модальных объектов и динамически их визуализировать или позволить каждому модальному обрабатывать свои собственные состояния переключения и использовать useImperativeHandle
для предоставления методов, к которым родитель может обращатьсядочерние модалы типа
const App = () => {
const firstRef = useRef(null);
const secondRef = useRef(null);
return (
<div>
<button onClick={() => this.firstRef.current.toggleModal()}>Open First Modal</button>
<button onClick={() => this.secondRef.current.toggleModal()}>Open Second Modal</button>
<FirstModal
{...props}
ref={firstRef}
/>
<SecondModal
{...props}
ref={secondRef}
/>
</div>
)
}
const FirstModal = forwardRef((props, ref) => {
const { showModal, toggleModal } = useToggleModal(false, ref);
return (
<Modal
{ ...rest }
show={showModal}
onHide={toggleModal}
>
First modal content...
</Modal>
)
})
const SecondModal = forwardRef((props, ref) => {
const { showModal, toggleModal } = useToggleModal(false, ref);
return (
<Modal
{ ...props }
show={showModal}
onHide={toggleModal}
>
Second modal content...
</Modal>
)
})
// state hook attempt
const useToggleModal = (init, ref) => {
const [show, setToggleModal] = useState(init);
const toggleModal = () => setToggleModal(!show);
useImperativeHandle(ref, () => ({
toggleModal
}))
return { show, toggleModal };
};