如何在 Bootstrap 弹出窗口中渲染 React 组件
介绍
有时,您会发现自己想要的功能比您使用的库所能提供的更多。例如,假设您想在引导弹出框内渲染 React 组件。听起来很简单,对吧?但事实并非如此简单。本指南将进一步探讨这种情况,并提供两种在引导弹出框内渲染组件的方法。
常规静态项目
假设您有一个没有模块器或转译器的标准静态项目,只有跨多个页面引导链接的非常基本的 HTML 文件。
您将在头部看到 Bootstrap CSS 链接,并在正文结束前看到 jQuery、Popper.js 和 Bootstrap 脚本。基本 HTML 模板如下所示。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Static Template</title>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
crossorigin="anonymous"
/>
</head>
<body>
<!-- -->
<script
src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
crossorigin="anonymous"
></script>
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"
integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
crossorigin="anonymous"
></script>
</body>
</html>
添加弹出按钮
创建一个触发弹出窗口的按钮。赋予其id值popover。
<button type="button" class="btn btn-lg btn-primary" id="popover">
Click to toggle popover
</button>
在主体结束之前,编写一个<script>块并通过选择按钮的 id 来初始化弹出窗口。
<script>
$(document).ready(function() {
$("button#popover").popover();
});
</script>
根据需要,将一些选项传递到popover()中以在其中显示 HTML 内容。
// ..
$("button#popover").popover({
html: true,
content: `<div>Hello</div>`
});
// ..
单击按钮时,您可以看到弹出窗口的实际效果。
现在,您不再直接输入内容,而是添加一个 React 组件。
插入 React 组件
首先,将 React CDN 链接添加到 HTML 文件。
<script
crossorigin
src="https://unpkg.com/react@16/umd/react.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"
></script>
由于没有模块器或转译器,您必须使用React.createElement()函数来创建组件,而不是编写 JSX。
const Hello = props => React.createElement("div", null, `Hello ${props.to}!`);
现在,您要在哪里渲染此组件?哦,这很简单,您可以执行以下操作,对吗?
$(document).ready(function() {
$("button#popover").popover({
html: true,
content: `<div id='app'></div>`
});
const Hello = props => React.createElement("div", null, `Hello ${props.to}!`);
ReactDOM.render(
React.createElement(Hello, { to: "World" }, null),
document.getElementById("app")
);
});
不幸的是,这不会起作用,因为弹窗已经初始化,并且弹窗内的 HTML 内容是由 jQuery 添加的。因此,ReactDOM.render()方法将无法找到 DOM 节点。
为了解决这个问题,创建一个 DOM 元素,然后在弹出内容中访问其innerHTML属性。
$(document).ready(function() {
const a = document.createElement("div");
const Hello = props => React.createElement("div", null, `Hello ${props.to}!`);
ReactDOM.render(React.createElement(Hello, { to: "World" }, null), a);
$("button#popover").popover({
html: true,
content: a.innerHTML
});
});
如果您想显示静态组件,那么这将适合您。但如果您需要在弹出窗口内进行交互,那么 Bootstrap 目前无法做到这一点。Bootstrap 没有适当的钩子来促进交互行为。
但如果这是一个与转译器捆绑的项目,我们可以使用reactstrap库在 popover 组件内添加交互性。
使用 Reactstrap 库的项目
在你的依赖项中添加reactstrap、bootstrap和jquery。
npm i reactstrap bootstrap jquery
在主文件中,创建一个基本的弹出窗口。
// ...
import "bootstrap/dist/css/bootstrap.min.css";
import { Button, Popover, PopoverHeader, PopoverBody } from "reactstrap";
const App = props => {
const [popoverOpen, setPopoverOpen] = useState(false);
const toggle = () => setPopoverOpen(!popoverOpen);
return (
<div
className="d-flex align-items-center justify-content-center"
style={{ height: "100vh" }}
>
<Button id="Popover1" type="button" color="primary">
Launch Popover
</Button>
<Popover
placement="bottom"
isOpen={popoverOpen}
target="Popover1"
toggle={toggle}
>
<PopoverHeader>Popover Title</PopoverHeader>
<PopoverBody>This the Popover body</PopoverBody>
</Popover>
</div>
);
};
// ...
Reactstrap 的<Popover />组件允许您将 React 组件作为子组件。这意味着子组件可以拥有自己的状态并提供交互行为。
让我们添加一个<Counter />组件,其中将有一个<Button />组件来增加计数器。
// ...
const Counter = () => {
const [counter, setCounter] = useState(0);
return (
<div>
<Button onClick={() => setCounter(counter + 1)}>Click</Button>
<span className="ml-3">{counter}</span>
</div>
);
};
// ...
在<PopoverBody />组件内部,调用计数器。
<PopoverBody>This the Popover body</PopoverBody>
现在,当您单击弹出按钮时,它会显示其中嵌入了计数器的弹出组件。
把所有这些放在一起,您将获得如下组件。
import React, { useState } from "react";
import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";
import { Button, Popover, PopoverHeader, PopoverBody } from "reactstrap";
const Counter = () => {
const [counter, setCounter] = useState(0);
return (
<div>
<Button onClick={() => setCounter(counter + 1)}>Click</Button>
<span className="ml-3">{counter}</span>
</div>
);
};
const App = props => {
const [popoverOpen, setPopoverOpen] = useState(false);
const toggle = () => setPopoverOpen(!popoverOpen);
return (
<div
className="d-flex align-items-center justify-content-center"
style={{ height: "100vh" }}
>
<Button id="Popover1" type="button" color="primary">
Launch Popover
</Button>
<Popover
placement="bottom"
isOpen={popoverOpen}
target="Popover1"
toggle={toggle}
>
<PopoverHeader>Popover Title</PopoverHeader>
<PopoverBody>
<Counter />
</PopoverBody>
</Popover>
</div>
);
};
export default App;
结论
本指南向您展示了如何在 bootstrap 弹出框中添加静态 React 组件,以及如何使用更精致的库(如 reactstrap)为弹出框添加交互性。当您受到项目中使用的库的限制时,这些方法会派上用场。不过,请确保始终使用create-react-app等模板创建捆绑项目,以避免最终出现模糊黑客攻击。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~