我对 React 中的模态概念有疑问。当使用带有 jQuery 的服务器端呈现模板时,我习惯于有一个始终可用的空全局模态模板(包含在始终扩展的基本模板中)。然后在进行 AJAX 调用时,我只是填充了模态……像这样:
$('.modal-global-content').html(content);
$('.modal-global').show();
那么我如何在 React 中实现这个概念呢?
我对 React 中的模态概念有疑问。当使用带有 jQuery 的服务器端呈现模板时,我习惯于有一个始终可用的空全局模态模板(包含在始终扩展的基本模板中)。然后在进行 AJAX 调用时,我只是填充了模态……像这样:
$('.modal-global-content').html(content);
$('.modal-global').show();
那么我如何在 React 中实现这个概念呢?
有几种方法可以做到这一点。第一个涉及从父组件传入模态状态。以下是如何执行此操作 - 首先使用父App.js
组件:
// App.js
import React from "react";
import Modal from "./Modal";
const App = () => {
const [showModal, updateShowModal] = React.useState(false);
const toggleModal = () => updateShowModal(state => !state);
return (
<div>
<h1>Not a modal</h1>
<button onClick={toggleModal}>Show Modal</button>
<Modal canShow={showModal} updateModalState={toggleModal} />
</div>
);
}
export default App;
这Modal.js
是将呈现模态的子组件:
// Modal.js
import React from "react";
const modalStyles = {
position: "fixed",
top: 0,
left: 0,
width: "100vw",
height: "100vh",
background: "blue"
};
const Modal = ({ canShow, updateModalState }) => {
if (canShow) {
return (
<div style={modalStyles}>
<h1>I'm a Modal!</h1>
<button onClick={updateModalState}>Hide Me</button>
</div>
);
}
return null;
};
export default Modal;
这种方式非常好,但如果您在整个应用程序的许多地方重复使用模态,它可能会有点重复。因此,我建议使用上下文 API。
为你的模态状态定义一个上下文对象,在你的应用程序顶部附近创建一个提供者,然后每当你有一个需要渲染模态的子组件时,你就可以渲染模态上下文的使用者。通过这种方式,您可以轻松地在组件树中更深地嵌套您的模态,而无需一直向下传递回调。以下是如何执行此操作 - 首先创建一个context.js
文件:
// context.js
import React from "react";
export const ModalContext = React.createContext();
现在更新的App.js
文件:
// App.js
import React from "react";
import { ModalContext } from "./context";
import Modal from "./Modal";
const App = () => {
const [showModal, updateShowModal] = React.useState(false);
const toggleModal = () => updateShowModal(state => !state);
return (
<ModalContext.Provider value={{ showModal, toggleModal }}>
<div>
<h1>Not a modal</h1>
<button onClick={toggleModal}>Show Modal</button>
<Modal canShow={showModal} updateModalState={toggleModal} />
</div>
</ModalContext.Provider>
);
}
export default App;
最后是更新的Modal.js
文件:
// Modal.js
import React from "react";
import { ModalContext } from "./context";
const modalStyles = {
position: "fixed",
top: 0,
left: 0,
width: "100vw",
height: "100vh",
background: "blue"
};
const Modal = () => {
return (
<ModalContext.Consumer>
{context => {
if (context.showModal) {
return (
<div style={modalStyles}>
<h1>I'm a Modal!</h1>
<button onClick={context.toggleModal}>Hide Me</button>
</div>
);
}
return null;
}}
</ModalContext.Consumer>
);
};
export default Modal;
这是使用上下文的工作版本的Codesandbox链接。我希望这有帮助!
您可以通过使用 css 和 JSX 来解决此问题的一种方法。
这是应用程序,我可以有任何东西,比如一个按钮,一个链接,任何东西让我们假设我们有一个链接(react-router-dom)
,可以将我们重定向到DeletePage
删除页面呈现一个Modal
你将提供的title
和actions
模态的作为props
const App = () => {
return(
<Link to="/something/someid">SomeAction</Link>
)
}
const DeletePage = () => {
return(
<Modal
title="Are you sure you want to delete this"
dismiss={() => history.replace("/")}
action={() => console.log("deleted") }
/>
)
}
const Modal = (props) => {
return(
<div>
<div className="background" onClick={props.dismiss}/>
<h1>{props.title}</h1>
<button onClick={props.dismiss}>Cancel</button>
<button onClick={props.action}>Delete</button>
</div>
)
}
z-index
模态的设置为高数position: fixed
模态组件的cancel button
也有相同的 onClick 功能,即解除Delete button
有action
通过 props 传递的函数由于 css,这个方法有一个缺陷,因为如果你的父组件有一个 position 属性,relative
那么这将中断。
无论 z-index 有多高,模态都将保留在父级内
React 门户以自己的方式创建了一个“门户”
您可能拥有的React
代码将在内部呈现DOM
id 为#root
(在大多数情况下)
因此为了呈现我们Modal
的最顶层,我们在公共文件中
创建另一个
DOM element
例如<div id="modal"></div>
index.html
所述Modal
react组件代码将略有改变
const Modal = (props) => {
return ReactDOM.createPortal(
<div>
<div className="background" onClick={props.dismiss}/>
<h1>{props.title}</h1>
<button onClick={props.dismiss}>Cancel</button>
<button onClick={props.action}>Delete</button>
</div>
),document.querySelector("#modal")
}
休息都是一样的