React 重温之--Protals

2018-10-12 admin

什么东西

Portals 提供了一种很好的将子节点渲染到父组件以外的 DOM 节点的方式。 Plain Text ReactDOM.createPortal(child, container) 第一个参数(child)是任何可渲染的 React 子元素,例如一个元素,字符串或碎片。第二个参数(container)则是一个 DOM 元素。

简单来说就是提供一种可以自定义安排组件位置的API。一般情况下组件都是被安插在距离最近的父节点上,通过这个API,可以将组件安插在指定的DOM节点上。

Plain Text render() { // React does not create a new div. It renders the children into domNode. // domNode is any valid DOM node, regardless of its location in the DOM. return ReactDOM.createPortal(

this.props.children,
domNode,

); }

典型用例是当父组件有 overflow: hidden 或 z-index 样式,但你需要子组件能够在视觉上“跳出(break out)”其容器。例如,对话框、hovercards以及提示框:

事件冒泡

一个从 portal 内部会触发的事件会一直冒泡至包含 React 树 的祖先。

Plain Text <html> <body>

<div id="app-root"></div>
<div id="modal-root"></div>

</body> </html>

Plain Text // 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: 0};
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 + 1
}));

}

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);

在上面的例子中,app-root和modal-root是两个平级的dom节点,从结构上来说,在modal-root上触发的事件不会被app-root捕获。

但是我们使用createPortal接口将Modal组件的children绑定到modal-root节点上,然后再Parent组件中,包裹Modal组件并监听onClick事件,并将Parent组件绑定到app-root节点上。

从真实的DOM结构上来看,mdal-root节点上的Modal组件中Child组件的onClick事件不应该被在app-root中Parent组件捕获,但从虚拟DOM的解构上来看,Modal却是Parent组件的子节点,这个事件冒泡还是比较遵循虚拟DOM的。。

原文链接:https://segmentfault.com/a/1190000016658253

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-42466.html

文章标题:React 重温之--Protals

相关文章
JavaScript正则进阶之路——活学妙用奇淫正则表达式
有些童鞋肯定有所疑惑,花了大量时间学习正则表达式,却发现没有用武之地,正则不就是验证个邮箱嘛,其他地方基本用不上,其实,大部分人都是这种感觉,所以有些人干脆不学,觉得又难又没多大用处。殊不知,想要成为编程大牛,正则表达式必须玩转,GitH...
2017-05-31
ajax教程之ajax使用Http请求
ajax中是如何让使用http请求的呢? 在传统的JS编程中,如果您希望从服务器上的文件或数据库中得到任何的信息,或者向服务器发送信息的话,就必须利用一个 HTML 表单向服务器 GET 或 POST 数据。而用户则需要单击“提交”按钮来发...
2015-11-12
DOM之通俗易懂讲解
DOM 是所有前端开发每天打交道的东西,但是随着 jQuery 等库的出现,大大简化了 DOM 操作,导致大家慢慢的 “遗忘” 了它的本来面貌。不过,要想深入学习前端知识,对 DOM 的了解是不可或缺的,所以本文力图系统的讲解下 DOM 的...
2016-01-13
JS教程之基础
javascript教程之什么是 JavaScript? JavaScript 被设计用来向 HTML 页面添加交互行为。JavaScript 是一种脚本语言(脚本语言是一种轻量级的编程语言)。JavaScript 由数行可执行计算机代码组...
2015-11-12
Ajax教程之Ajax介绍
Ajax 由 HTML、JavaScript™ 技术、DHTML 和 DOM 组成,这一杰出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用程序。本文的作者是一位 Ajax 专家,他演示了这些技术如何协同工作 —— 从总体概述...
2015-11-12
bootstrap table之通用方法( 时间控件,导出,动态下拉框, 表单验证 ,选中与获取信息)代码分享
1.bootstrap-table 单击单行选中 $(&#x27;#gzrwTable&#x27;).on(&#x27;click-row.bs.table&#x27;, function(e, row, $element) { $(&#x...
2017-02-17
数据格式之战:JSON vs XML
在比较JSON和XML之前,我们先来上一堂关于数据格式的简要历史(更准确的说,是关于XML的始祖): 早在1970年,IBM开发了一种叫Generalized Markup Language的标记语言,简称GML,它主要是为脚本语言定义的一...
2016-01-13
[翻译]基于Webpack4使用懒加载分离打包React代码
原文地址:https://engineering.innovid.com/code-splitting-using-lazy-loading-with-react-redux-typescript-and-webpack-4-3ec601...
2018-03-11
JavaScript深入之类数组对象与
类数组对象 所谓的类数组对象: 拥有一个 length 属性和若干索引属性的对象 举个例子: var array = [&#x27;name&#x27;, &#x27;age&#x27;, &#x27;sex&#x27;]; var ...
2017-05-27
Vue.js原理分析之observer模块详解
介绍 observer是Vue核心中最重要的一个模块(个人认为),能够实现视图与数据的响应式更新,底层全凭observer的支持。 **注意:**本文是针对Vue@2.1.8进行分析 observer模块在Vue项目中的代码位置是src/c...
2017-03-16
回到顶部