TL;DR =>Portals
并Context
解决不同的目的,一个是在任何级别注入 DOM,另一个是在任何级别注入 props。Context
可以模仿Portals
,但至少在不引入代码异味的情况下Portals
不能模仿。Context
注意:以下是基于我对这两个概念的理解,如果有人对此有进一步的想法或更正,请随时编辑答案。
顾名思义,据我所知Portals
,这是一种渲染不需要在组件树层次结构中的组件的途径。这非常适用于Modals
,Popovers
或任何需要在树中特定位置缝合的组件。
Context
是与各种兄弟组件和子组件进行通信,而无需从父组件一直向下传递道具到预期组件。当然,这是一个重要的功能,但它仍处于实验阶段,可能是因为这可以通过event-emitters
和来实现Redux
,MobX
用于集中状态管理。
我假设您的用例i18n
需要跨组件进行大量通信,您可能希望查看这篇精彩的文章
组件通信
Portals 和 Context 有助于实现这种通信,但有区别。Portals 可以在任何级别渲染或注入 DOM,而 Context 可以在子组件树中的任何级别注入 props。
您总是Portals
可以使用可以实现的功能,Context
但我认为Portals
不能模仿Context
功能。
EG:可以做这样的事情来模仿Portals
使用Context
. 在Portals
AFAIK 中,您只能发送 DOM Nodes ReactDOM.createPortal(child, container)
。可能有一种方法可以实现该功能,但这肯定会导致代码异味。
class Parent extends React.Component {
getChildContext() {
return {
renderModal: this.renderModal
}
}
renderModal = (children) => {
this.setState({
open: !this.state.open,
injectableChildren: children
})
}
render() {
this.state.open
?
<div>
{this.state.injectableChildren}
</div>
:
null
// JSX
}
}
class SomeSibling extends React.Component {
static contextTypes = {
renderModal: React.PropTypes.func
}
handleOnClick = (event) => {
this.context.renderModal(renderableChildJSX);
}
renderableChildJSX = () => (
<div>
YAY I AM GETTING RENDERED AT THE ROOT
</div>
)
render() {
return(
<div onClick={this.handleOnClick}>
</div>
)
}
}
就我而言,尽管它很灵活,但我还是害怕使用Context
它,因为React
文档总是提到它是一个实验性功能,并反复警告不要全面使用此功能。我的猜测是,React 正在考虑稳定这个特性,或者完全从 React 代码库中删除它,这可能是双向的风险。
结论: IMO,Portals
在当前状态下,它试图解决的问题与Context
构建的目标完全不同,最好使用可能被弃用event-emitters
的唯一原因。Context