React + Semantic-UI:在 UI MODAL 中使用表单

IT技术 javascript reactjs modal-dialog semantic-ui
2021-04-28 16:59:12

在没有 React 的普通旧语义 UI 中,我已经能够在模态中放置一个表单而没有任何问题。

使用 Semantic-UI + React 版本,我能够在模态内显示表单,但它并没有像我期望的那样工作。

例如,在模态显示之后,模态内的表单也被显示。如果我开始在输入字段中输入,则会显示此错误:

Error: Invariant Violation: findComponentRoot(..., .1.1.1.0.4.0.0.1): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child nodes of the element with React ID ``.

由于这个错误,我使用输入的其他react代码无法按预期工作。

这是演示问题的代码的最简单版本:

ConfirmEdit = React.createClass({

    render(){
        return (
            <div className="ui modal editform">
                <form className="ui form">
                    <div className="field">
                        <label>Name</label>
                        <input name="name" type="text" placeholder="Name">
                        </input>
                    </div>
                </form>
            </div>
        );
    }
});

在我添加上面的组件的组件中,我确保触发它:

$('.ui.modal.editform').modal('show');

正如刚才提到的。它显示正常,但由于不变量违反而无法正常工作。

我如何解决这个问题并让它发挥作用?

4个回答

您想componentDidMount使用 detachable = false 选项初始化模态

$('.ui.modal').modal({detachable: false});

这将防止模态在全局调光器对象内移动,并且 DOM 仍将由 React 拥有和管理。此处记录其他选项

我创建了一个示例JSFiddle供您测试。

好吧...我希望我早点想到这个....

我决定分析 DOM 并直接操作 DOM 以获得解决方案。

我曾试图寻找其他更“优雅”的解决方案,但事情并没有解决。我尝试将 Material-UI 的 modal 与 Semantic-UI 表单集成,但发现如果 modal 的内容像表单等一样长,它就不会滚动......

我也曾尝试依赖 Semantic-UI 的 API(可用设置等),但它们都有一些负面影响。

所以这就是我为找到解决方案所做的工作。我查看了 MODAL 显示时生成的 HTML,并查看了它在 DOM 中的位置。

事实证明,当调光器处于活动状态时,Semantic-UI 会为调光器显示一个具有此类的 div

ui dimmer modals page transition visible active

我发现这个 div 是一个兄弟姐妹,而不是另一个 div 的孩子

ui fluid container pushable

其中包含我所有的其他内容。

所以我所做的是每次触发我的模态时,我立即调用代码使模态成为我其他内容的容器的子项......这样我的模态就不会被调光器覆盖。

showModal: function() {
    $('.ui.modal.editform').modal('show');
    //$('.ui.dimmer.modals').dimmer('hide');
    //$('.ui.dimmer.modals').after('.pusher');
    // $('.ui.dimmer.modals').appendTo('#render-target');
    $('.ui.dimmer.modals').appendTo('.ui.fluid.container.pushable');
}

总结: 1.) 根据我使用带有 React 的 Semantic-UI 在模态中显示表单的经验,如果您没有设置 Semantic-UI 的 UI MODAL 的 detachable 属性,则会出现 Invariant Violation 等错误。解决方案是将 detachable 设置为 false。

2.) 之后,你可能会遇到模态的调光器覆盖模态和表单的问题,因此它不仅看起来很糟糕,你也无法点击输入字段等......解决方案,至少在我的情况下,是使用 jQuery 操作 dom 并修复 Semantic-UI 忘记自动执行的任何操作。

我希望对未来的人有所帮助......现在已经坚持了 3 天......

我不知道这是否是最好的解决方案......但它确实有效......如果你有更好的解决方案,请告诉我......

好的...我找到了一个更好的答案。

我在上面给出的第一个答案是当模态可以位于层次结构中较低的任何容器中时,将调光器移动到与模态相同的父级。

通过这样做,模态和模态中的形式不再被调光器覆盖。

现在的问题(至少在我的情况下)是调光器只覆盖了窗户的特定部分,而不是整个窗户,这才是它应该做的。在这种情况下,如果您尝试将 css 高度设置为 100% 并不重要......因为它可能已经是 100% 但父容器只会上升到那个点,因此调光器也是如此。

所以这是我找到的更好的解决方案。

我发现如果你在层次结构中声明模态更高,在我的例子中,我在目标容器之前的最顶层容器中声明它。

这是目标容器:

<div id="render-target"></div>

这是告诉 react 渲染到那个容器:

React.render(<App />, document.getElementById("render-target"));

里面最上面的 div 容器是我用设置声明 UI MODAL 的地方detachable:false...

现在,当我触发 UI MODAL 显示时,我然后使用 jQuery 将模态移动到更高的 div 容器,在这种情况下是目标容器:

$('.ui.modal.editform').appendTo('#render-target');

通过这样做,调光器位于模态和窗体的后面,但它也以动态的方式完全覆盖了整个窗口。因此,如果您有一个包含大量条目的长表,并且整个文档很长,调光器仍会完全覆盖它,而您无需再进行任何手动调整。