我想用一个处理相同任务的React组件替换内置在alert()
函数中的javascript:即向用户显示快速,不允许的消息。
现在,我可以通过创建一个组件并将其放在我的标记中来实现这一点。例如
<div>
<BunchOfComponents />
<MoreComponents />
<MyAlertDialog open={this.props.shouldShowAlert} />
</div>
然后通过Redex或其他方式控制其open
状态来显示它。
但是,我喜欢做什么,它能够不在我的标记中声明它,而是注入它通过一个函数进入dom。
像...一样的东西。
myCoolFunction() {
const alert = (
<MyAlert
open={true}
msg="Hello World"
/>
)
DOM.findNode('someID').insert(alert); <-- fake API obviously
}
是否可以动态附加这样的组件?
答案 0 :(得分:2)
如果将其渲染为空节点,则可以在React渲染树中注入一些带有DOM操作的自定义内容。假设你在react的渲染中有某个地方:
import { provide } from '@angular/core';
import { LocationStrategy } from '@angular/common';
import { Router, ActivatedRoute } from '@angular/router';
import { addProviders } from '@angular/core/testing';
import { SpyLocation } from '@angular/common/testing';
class MockRouter {
createUrlTree() {}
navigateByUrl() {}
navigate() {}
}
class MockActivatedRoute { }
beforeEach(() => {
addProviders([
{provide : Router useClass: MockRouter },
{provide : ActivatedRoute, useClass: MockActivatedRoute },
{provide:LocationStrategy, useClass: SpyLocation }
]);
});
然后,您可以按ID找到此节点,并为其<div id="you-know-id />
分配一些内容。更“反应”的方式是使用refs而不是id。
通常情况下,这些内容会被包含在innerHTML
(您插入的位置)和componentDidMount
(您删除和取消订阅任何内容)方法中。
因为做肮脏的技巧你可能想避免内存泄漏。所以,就是这样。
顺便说一句,我认为这不是解决你刚才描述的问题的正确方法。你可以做什么,是这样的:
componentWillUnmount
然后在它打开时实际上挂载,并在它关闭时卸载。
但是,控制状态或道具成员的注射更安全。当你直接操作DOM时,你真的需要知道你在做什么。说,包装一些jQuery插件:)。那你很好,因为别无他法:)。
答案 1 :(得分:2)
这是我在工作中做的肮脏方式(听起来不对......) http://codepen.io/matthsiung/pen/JKOpVW
我确信有更好的“正确”方法,但它会自行清理,因此对我有用。
以下是要点:
对话框触发器
//Your trigger function will render the dialog component to a newly created dummy div,
// while also passing it into the component as a prop
function showDialog() {
var div = document.createElement('div');
ReactDOM.render(
<Dialog container={div}/>,
document.body.appendChild(div)
);
}
对话框组件:
//When your dialog component closes it unmounts itself
close(){
ReactDOM.unmountComponentAtNode(this.props.container);
},
//Before unmount it cleans up after itself by removing the dummy div
componentWillUnmount() {
document.body.removeChild(this.props.container);
},
答案 2 :(得分:1)
也许react-portal可以帮到你。
来自文档:
将其子项传输到新的React组件并将其附加到document.body(创建一个新的独立React树)
我经常使用(对话框/模态和菜单弹出窗口)。非常有用和轻量级。