如何在 React 应用程序中初始化 Bootstrap 4 弹出框?
Posted
技术标签:
【中文标题】如何在 React 应用程序中初始化 Bootstrap 4 弹出框?【英文标题】:How do I initialize the Bootstrap 4 popover in a React application? 【发布时间】:2018-03-28 17:36:56 【问题描述】:我不知道如何使弹出框工作,如:https://getbootstrap.com/docs/4.0/components/popovers/。
文档中提到 popover 支持是一个插件,并且也需要工具提示插件,所以我修改了我的 webpack.config.js
以添加这两个,现在看起来像这样:
...
new webpack.ProvidePlugin(
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default'],
Popover: 'exports-loader?Popover!bootstrap/js/dist/popover',
Tooltip: "exports-loader?Tooltip!bootstrap/js/dist/tooltip",
),
...
我没有找到任何关于 Bootstrap 插件概念的文档,所以上面两行 Popover
和 Tooltip
来自搜索,不确定它们是否正确。
文档说明:
出于性能原因,弹出框是可选的,因此您必须自己初始化它们。
但我不明白该怎么做。
文档显示了以下用于初始化弹出框的代码:
$(function ()
$('.example-popover').popover(
container: 'body'
)
)
但我不明白它应该做什么 - 我的元素上没有要调用的 popover()
函数 - 这是如何工作的?
这是我尝试使用弹出框的代码示例:
render()
...
<span>
Summary info
<button
type="button" className="btn btn-sm"
data-toggle="popover" title="Popover title"
data-content="The popover Content"
>
Show popover
</button>
</span>
...
如何使 Bootstrap V4 弹出框功能在 React 应用程序的上下文中工作?具体来说 - 我如何“初始化”弹出框?
我正在使用 Typescript 2.3、React 16、Bootstrap 4(没有 react-bootstrap 样式库)。
注意react-bootstrap只支持Bootstrap V3,而且reactstrap太不稳定我不想用了。
【问题讨论】:
【参考方案1】:当我最初试图让 Bootstrap 弹出框工作时,我(毫无疑问仍然有)很多缺失的上下文理解。
第一件事是:Bootstrap“Popover”插件实际上是一个JQuery plugin。我认为这就是所有 Bootstrap 插件的工作方式,但我找不到任何关于此的 Bootstrap 介绍性文档。这样就解释了popover()
方法及其来源。
下面,我概述了使弹出框在 React / Typescript / Webpack 堆栈的上下文中工作所需的内容。
在下面,我假设你已经按照the Bootstrap doco 配置了 Webpack。
您不需要原始问题中的“Popover”和“Tooltip”行,假设您是 webpack.config.js
符合 Bootstrap doco 并且您的代码库中有 import 'bootstrap';
。
您需要添加 JQuery 类型(如果尚未存在),以便您可以导入 $
并拥有正确的类型:
"devDependencies":
"@types/jquery": "3.2.15",
...
"dependencies":
"bootstrap": "4.0.0-beta",
"jquery": "3.2.1",
"popper.js": "1.11.0",
...
您必须按照this blog article by Netanel Basal 扩展 JQuery 的类型定义,以便它了解 Popover 插件。在typings.d.ts
(或项目中任何有意义的地方)中,添加以下内容:
// support for JQuery popover plugin from Bootstrap 4
interface JQuery
popover() : any;
请注意,定义是让弹出框以静态类型方式从代码中工作所需的最低限度。它需要扩展以支持传递参数,以便您可以自定义弹出行为。或者您可以使用data
属性来传递这些参数,如文档中的Live example。
在 React 组件本身中,从问题中声明弹出框的 JSX 似乎工作正常。
要“初始化”弹出框,根据问题,您需要导入 JQuery 标识符,然后调用弹出框方法:
...
const $ = require('jquery');
...
componentDidMount(): void
$('[data-toggle="popover"]').popover();
...
“导入表格”didn't work for me,所以我不得不require()
它。
该代码在整个 html 页面中搜索带有 data-toggle="popover"
的元素,并返回一个具有您可以调用的 popover()
方法的 JQuery 对象(这是整个 JQuery 插件部分)。
一旦在带有 popover 属性的元素上调用了popover()
,点击该元素时会自动显示弹出框(无需管理特定于弹出框的 React 状态)。
编辑
如上所示,在整个 HTML 页面中搜索所有弹出框并不是一个好主意。在多个 React 组件中有多个弹出框的复杂页面中,每个组件最终会覆盖彼此的 popover()
选项。
这是我目前针对可重用 React bootstrap Popover 组件的解决方案。
扩展 Typescript 类型以了解更多 popover options:
// support for JQuery popover plugin from Bootstrap 4
interface JQuery
popover(options?: PopoverOptions) : any;
interface PopoverOptions
container?: string | Element | boolean;
content?: string | Element | Function;
placement?: "auto" | "top" | "bottom" | "left" | "right" | Function;
title?: string | Element | Function;
...
创建Popover.tsx
喜欢:
export interface PopoverProps
popoverTitle: string | Element | Function;
popoverContent: string | Element | Function;
export class Popover
extends PureComponent<PopoverProps, object>
selfRef: HTMLSpanElement;
componentDidMount(): void
$(this.selfRef).popover(
container: this.selfRef,
placement: "auto",
title: this.props.popoverTitle,
content: this.props.popoverContent,
);
render()
return <span
ref=(ref)=>if(ref) this.selfRef = ref
data-toggle="popover"
>
this.props.children
</span>;
然后像这样使用弹出框:
<Popover
popoverTitle="The popover title"
popoverContent="The popover content"
>
<span>
Click this to show popover.
</span>
</Popover>
注意与动态内容的 Popover 定位相关的问题:Bootstrap 4 - how does automatic Popover re-positioning work?
【讨论】:
【参考方案2】:文档试图说明的是,简单地使用带有 data-toggle="popover" 的元素不会创建弹出框的实例。您需要使用 javascript 调用显式初始化它。
在非 React 环境下,可以将其添加到文档就绪函数中,例如这样
$(document).ready(function ()
$('.myPopoverItem').popover(
html: true
, trigger: 'focus'
, content: $.proxy(this.getContent, this)
);
不过,在 React 中,您需要将它添加到对象的构造函数代码中,以便在 render() 之后调用它(元素必须在页面上)。
我找到了这个潜在的答案:React "after render" code? 它推荐了 componentDidMount 函数,您可以在其中调用弹出框初始化。
所以在你的 React 对象中,你会有一个函数
componentDidMount()
$('.myPopoverItem').popover(
html: true
, trigger: 'focus'
, content: $.proxy(this.getContent, this)
);
【讨论】:
以上是关于如何在 React 应用程序中初始化 Bootstrap 4 弹出框?的主要内容,如果未能解决你的问题,请参考以下文章
如何将从远程 API 获取的初始数据与 React.Suspense 集成?
如何在 React Native 应用程序初始化期间防止与节点相关的错误
如何在 Apollo 客户端的初始化中使用来自 React 的全局数据?