React 16 已经发布了,其中一个很有趣的是添加了 “Portals”。
Portals 可以让你在父组件外渲染 react 受控 DOM 节点。react doc 也使用了一个模态框的例子很好地解释了它。用也做 tooltips 也很合适(这是我早前做的一个例子)。
因为所有 portal 做的,都是将一个元素放到其他元素上,你并没有被限制放在 当前 document 的任何地方。你可以添加到另一个 document 的 body 中,可能是完全不同浏览器窗口的一个 document。
下面我有一个基本的页面(左边),包含一个计数器及深红色按钮。另一个窗口(右边)同样是 react app 的一部分。
右边的窗口是属于 同一个 React app 这个事实应该让你感到惊讶。
上面图片中能看到的所有东西(除了树)都是在下面代码展示的同一个组件中:
你已经成功了,
有一点特殊,里面的所有东西都会被渲染到另一个 window 下。
尤其是,
做了两件事。
- 1、 当组件渲染时打开一个浏览器窗口。
- 2、 创建一个
portal
并将props.children
添加到新窗口的 body。
这不是最酷的事情吗?
我是多么兴奋,必须得冷静一下。
…
I saw a duck!
…
上面提到的 body中的组件就是下面这样。 React 16 新增的部分 ReactDOM.createPortal
在 11 行 —— 那就是黑魔法。
那有意义吗?组件并没有返回什么,只是做了一些其他事情。
换一个角度来想可能是这样的:按理来说,一个父组件对子组件说:“嘿,渲染 DOM, 然后把结果添加到我这里。”,然后子组件照做了。但是这次,任性的子组件说,“不!我要将东东渲染到另一个窗口,然后写一篇关于它的博客。”
现在,我知道你在想什么。
你有点渴,并且想知道你是否该喝点水了。是的,去吧。
另一件你可能在想的事情是:将一些 DOM 注入到无样式的空白窗口有什么好处?可能 Craigslist 或 Wikipedia 也不知道。但你的网站很美,任何时候都不能弹出小窗口。
好吧,好消息来了,大家注意了!
起初,我还在想是否有一个简单的方式将样式复制到新窗口。然后我想起我的生活只是被一些毫无意义的事件填充,它们唯一的目的只是让我分心,阻止我内心的空虚寂寞冷。
所以亲自写这个函数就是乐趣!
看下面:
事实上,我并不是很了解 styleSheet
。我期待从评论中得知有什么奇技淫巧。
现在我可以在打开新窗口的时候很简单地复制样式,像这样:
我不认为这能在 Medium app 的 iOS/Android 平台上运行,所以请在浏览器打开。
好了,我认为这篇文章该结束了。
Bye!