我试图从不相关的组件调用Modal(不使用任何父子关系)。
为了做到这一点,我试图使用React Redux(作为我所见过的唯一可以在两个不相关的组件之间建立连接的方法)。CodeSandbox上的一个例子显示了我试图做的最少的事情。
我的问题是,我不想包括<Modal>
内<Button>
渲染功能。我希望能够简单地翻转Button.js
中的旗帜,<Modal>
就会出现。根据我的理解,这应该是Redux的优点之一。
它可能看起来不重要,但除了事实,我明白这是可以做到的,所以我想知道如何,这将是对我在一个不同的代码块,如果我包括<Modal>
在组件的渲染函数它会渲染模态多次(我渲染该组件在一个列表)。
编辑:
只是为了清楚(根据CodeSandbox上的例子),我使用React类而不是功能组件;所以没有像useDispatch
这样的钩子,而是像mapDispatchToProps
这样的函数是我想要的方式。
我将推荐使用React Portal,这将在给定的节点内注入它,我发现它是创建模态的最佳解决方案。我在dailylivedeals.com中使用了相同的POC
import ReactDOM from "react-dom";
render() {
return ReactDOM.createPortal(
this.props.children,
Document.body
);
}
这是使用React自己的特性最简单、最干净的。
优势:
- 更简洁
- 每个模态实例都可以有自己的模态
- 可以打开多个模态(甚至从一个模态内部)
- 模态目标可以是动态的(像模态中的模态)
- 多模式可以使用代码轻松控制。 更新:
modal
详细代码import React, {useEffect, useState} from "react";
import ReactDOM from "react-dom";
import {Link} from 'react-router-dom';
import "./modal.scss";
let Modal = ({visible, id, hideModal, children, ...props}) => {
let [show, setShow] = useState(false);
useEffect(() => {
setShow(visible);
console.log(visible);
}, [visible]);
let toggleVisibility = () => {
//hideModal();
setShow(!show);
}
useEffect(() => {
if (!show) {
hideModal();
}
}, [show]);
return <div className="modal-scratchpad">
{show ?
ReactDOM.createPortal(
<div id={`${id}-modal-wrapper`} className="sample-modal-wrapper">
<div id={`${id}-modal-backdrop`} className="sample-modal-backdrop">
</div>
<div id={`${id}-modal-container`} className="sample-modal-container">
<div id={`${id}-modal`} className="sample-modal">
{children}
<div onClick={toggleVisibility} className="sample-modal-cross-button">{'u2716'}</div>
</div>
<style type="text/css">
{"body {" +
"overflow:hidden" +
"}"}
</style>
</div>
</div>
, document.body)
: <></>
}
</div>
};
export default Modal;