如何动态地将React组件(例如对话框)插入到DOM中?

8
我希望用一个React组件来替换javascript内置的 alert() 函数,以完成相同的任务:快速向用户显示可关闭的消息。现在,我可以通过创建一个组件并将其放置在我的标记中来实现这一点。例如:
<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   
}

有没有可能动态添加组件呢?

ReactDOM.render() ? - webdeb
3个回答

6
这是我在工作中采用的"肮脏"做法(听起来似乎不对...),这里是链接: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); 
},

FYI,ReactDOM已被弃用,新的语法是import { createRoot } from 'react-dom/client'
const root = createRoot(document.createElement('div'))
root.render(<Dialog />)
- undefined

4
也许 react-portal 能够帮助您。
从文档中得知:
将其子组件传输到一个新的 React 组件并将其附加到 document.body 上(创建一个独立的 React 树)。
我经常用它来制作对话框/弹出菜单,非常实用且轻量。

1
这应该是一个注释 - omarjmh
2
我的回答是建议一个能够满足OP需求的库(我猜测)。做不到吗?根据占位符所述,评论应该用于“询问更多信息”或“提出改进建议”。 - mrlew

4
如果React渲染为空节点,则可以通过DOM操作注入一些自定义内容。假设您在React的渲染中有以下代码:
<div id="you-know-id />

你可以通过节点的id找到它,并将其innerHTML赋值为某些内容。更"reactish"的方法是使用refs而不是id。
通常,这些东西被包裹在componentDidMount(插入时)和componentWillUnmount(删除和取消订阅任何内容时)方法中。
因为使用不当可能会导致内存泄漏,所以要避免脏技巧。所以,这是正确的方式。
顺便说一下,我认为这不是解决你刚才描述的问题的正确方法。相反,你可以尝试这样做:
{ this.props.shouldShowAlert && <MyAlertDialog open={ true } /> }

当它打开时,它将被实际挂载,并在关闭时取消挂载。

不过,使用状态或props成员来控制注入要更安全。如果您直接操作DOM,确实需要知道自己在做什么。比如,包装一些jQuery插件。这样你就没问题了,因为没有其他方式可以做到 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接