来源:https://segmentfault.com/a/1190000011668286

Portals是react 16.3 提供的官方解决方案,使得组件可以脱离父组件层级挂载在DOM树的任何位置。

普通情况下,组件的render函数返回的元素会被挂载在它的父级组件上。

import DemoComponent from './DemoComponent';
render() {
// DemoComponent元素会被挂载在id为parent的div的元素上
return (
<div id="parent">
<DemoComponent />
</div>
);
}

然而,有些元素需要被挂载在更高层级的位置。最典型的应用场景:当父组件具有overflow: hidden或者z-index的样式设置时,组件有可能被其他元素遮挡,这个时候你就可以考虑要不要使用Portal使组件的挂载脱离父组件。例如:对话框,tooltip。

import DemoComponent from './DemoComponent';

render() {
// react会将DemoComponent组件直接挂载在真真实实的 dom 节点 domNode 上,生命周期还和16版本之前相同。
return ReactDOM.createPortal(
<DemoComponent />,
domNode,
);
}

组件的挂载点虽然可以脱离父组件,但组件的事件通过冒泡机制仍可以传给父组件。

官方domo

// These two containers are siblings in the DOM
const appRoot = document.getElementById('app-root');
const modalRoot = document.getElementById('modal-root'); class Modal extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement('div');
} componentDidMount() {
modalRoot.appendChild(this.el);
} componentWillUnmount() {
modalRoot.removeChild(this.el);
} render() {
return ReactDOM.createPortal(
this.props.children,
this.el,
);
}
} class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {clicks: };
this.handleClick = this.handleClick.bind(this);
} handleClick() {
// This will fire when the button in Child is clicked,
// updating Parent's state, even though button
// is not direct descendant in the DOM.
this.setState(prevState => ({
clicks: prevState.clicks +
}));
} render() {
return (
<div onClick={this.handleClick}>
<p>Number of clicks: {this.state.clicks}</p>
<p>
Open up the browser DevTools
to observe that the button
is not a child of the div
with the onClick handler.
</p>
<Modal>
<Child />
</Modal>
</div>
);
}
} function Child() {
// The click event on this button will bubble up to parent,
// because there is no 'onClick' attribute defined
return (
<div className="modal">
<button>Click</button>
</div>
);
} ReactDOM.render(<Parent />, appRoot);

 

react portals的更多相关文章

  1. react portals 插槽 实现简易弹窗

    Portal 提供了一种将子节点渲染到存在于父节点以外的DOM节点的优秀方案: 尽管 portal 可以被放置在 DOM 树中的任何地方,但在任何其他方面,其行为和普通的 React 子节点行为一致. ...

  2. ZooTeam 前端周刊|第 111期

    转: ZooTeam 前端周刊|第 111期 ZooTeam 前端周刊|第 111期 浏览更多往期周刊,请访问: https://weekly.zoo.team 基于Vue的前端架构,我做了这15点 ...

  3. 学习React系列(七)——Fragments、Portals、Error Boundaries与WEB组件

    React.Fragment portals Error Boundaries WEB组件 React.Fragment 想象一个场景,想把td包装为组件添加到table中去,代码如下: class ...

  4. react 插槽(Portals)

    前言: 昨天刚看了插槽,以为可以解决我工作中遇到的问题,非常激动,我今天又仔细想了想,发现并不能解决... 不过还是记录一下插槽吧,加深印象,嗯,就酱. 插槽作用: 插槽即:ReactDOM.crea ...

  5. [React] Render Elements Outside the Current React Tree using Portals in React 16

    By default the React Component Tree directly maps to the DOM Tree. In some cases when you have UI el ...

  6. React——组件的生命周期函数

    每一个组件都有一些生命周期函数. 当组件实例被创建并且会插入到DOM中,下面这些函数会被调用 constructor componentWillMount render componentDidMou ...

  7. [译文]React v16(新特性)

    [译文]React v16(新特性) 查看原文内容 我们很高兴的宣布React v16.0发布了! 这个版本有很多长期被使用者期待的功能,包括: fragments (返回片段类型) error bo ...

  8. React 特性剪辑(版本 16.0 ~ 16.9)

    Before you're going to hate it, then you're going to love it. Concurrent Render(贯穿 16) 在 18年的 JSConf ...

  9. 22.1 、react生命周期(一)

    在每个react组件中都有以下几个生命周期方法~我们需要在不同阶段进行讨论 组件生命周期概述 1.初始化 在组件初始化阶段会执行 constructor static getDerivedStateF ...

随机推荐

  1. MFC VC++获取当前程序的运行路径

    ]; GetModuleFileName(, szDir, ); int i; i = lstrlen(szDir) - ; ) { if(szDir[i] == _T('\\')) { szDir[ ...

  2. 自动化测试-2.seleniumIDE

    一.安装步骤 1. 打开Firefox浏览器 2. 打开https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/versions/,点击 ...

  3. cocos2dx粒子系统的简单使用

    cocos2dx自带的几种封装好的粒子系统,下面做个简单使用演示. ParticleFire 火焰粒子系统 ParticleFireworks 烟花粒子系统 ParticleSun 太阳粒子系统 Pa ...

  4. Codeforces1062B. Math(合数分解)

    题目链接:传送门 题目: B. Math time limit per test second memory limit per test megabytes input standard input ...

  5. vue调用支付接口

    html: <div class="paymentHtml" v-html="paymentHtml"></div> script: d ...

  6. IIS发布错误及解决

    HTTP 错误 403.14 - Forbidden  解决办法: 打开iis管理器,找到对应网站,并找到目录浏览,双击打开. 点击启用即可. HTTP 错误 500.19 - Internal Se ...

  7. PythonStudy——编程基础 Python Primary

    1.什么是编程语言 语言:  一个事物与另外一个事物沟通的介质 .编程语言是程序员与计算机沟通的介质. 编程: 将人类内识别的语言转化为机器能识别的指令,这种过程就叫做编程. 注:最终这些指令会被转化 ...

  8. 使用mysqlproxy实现mysql读写分离

    先说一下什么是读写分离吧. 以三台虚拟机为例,搭建一主一从一代理,全部配置好之后,当从proxy插入数据时,该数据会同时插入主数据库,因为主从关系,从数据库也会有数据.当把从数据库执行slave st ...

  9. DevExpress中barManager下的toolbar如何在panel中显示

    如题,我的Dev Toolbar需要在一个pannel中显示,并且居于最顶部.可是好像默认情况下toolbar都是在窗体的最顶部的,如何设置才能使其位于一个panel的最顶部呢? 解决方案:经过测试, ...

  10. linux删除某用户密码

    1.清空一个linux用户密码 # passwd -d user1 passwd: password expiry information changed. 2.指定key登录 ssh port111 ...