我使用react-bootstrap的ModalTrigger来显示一个重字段模态(基于react-bootstrap的Modal),这意味着向它发送一堆 Prop :
<ModalTrigger modal={<MyModal field1={value1} field2={value2} (more fields...)/>}>
Click here to open
</ModalTrigger>
创建触发器的父组件具有通过 props 传入的字段/值,并且 该组件的父组件也将其作为 props 传递,由实际的顶级组件传递保存数据。两者基本上都是管道,这是一个经典的 childContext 场景,只不过它不起作用。这是我尝试过的简化版本:
var MyModal = React.createClass({
contextTypes : {foo : React.PropTypes.string},
render : function() {
return (
<Modal {...this.props} title="MyTitle">
<div className="modal-body">
The context is {this.context.foo}
</div>
</Modal>
);
}
});
var Content = React.createClass({
childContextTypes : {foo: React.PropTypes.string},
getChildContext : function() {return {foo : "bar"}},
render : function() {
return (
<ModalTrigger modal={<MyModal/>}>
<span>Show modal</span>
</ModalTrigger>
)
}
});
模式会弹出“上下文是”,但不显示实际上下文。
我相信发生这种情况是因为发送到 ModalTrigger 的 Prop 已经以某种方式渲染/安装,但我不确定为什么。据我所知,MyModal 的所有者是 Content 组件,这意味着上下文应该没问题,但事实并非如此。
更多信息:我已经尝试将 {...this.props}
和 context={this.context}
传递给 MyModal,但没有成功。另外,也许相关的是,ModalTrigger 使用cloneElement 确保模态的 onRequestHide 属性指向触发器的隐藏函数。
那么我在这里错过了什么? :/
最佳答案
当 ref
属性被覆盖时,
React.cloneElement
将更改元素的所有者,这意味着上下文不会从以前的所有者传递。 但是,ModalTrigger
的情况似乎并非如此。
请注意,基于所有者的方法在 React 0.14 中不会完全起作用,因为上下文将从父级传递到子级,而不是从所有者传递到所有者。 ModalTrigger
在 DOM 的另一个分支中渲染其 modal
节点 prop(参见 OverlayMixin
)。因此,您的 Modal
组件既不是 Content
组件的子组件,也不是 Content
组件的后代,并且不会从 Content
传递子上下文。
为了解决您的问题,您始终可以创建一个组件,其唯一目的是将上下文传递给其子组件。
var PassContext = React.createClass({
childContextTypes: {
foo: React.PropTypes.string
},
getChildContext: function() {
return this.props.context;
},
render: function() {
return <MyModal />;
},
});
使用它:
<ModalTrigger modal={<PassContext context={this.getChildContext()}/>}>
正如 Matt Smith 所暗示的那样,事实证明,react-bootstrap 已经包含了一种非常相似的方法来通过 ModalTrigger.withContext
转发上下文。 。这允许您创建一个 ModalTrigger
组件类,它将其上下文转发到它的 modal
节点 prop,无论它在 VDOM 树中的位置如何。
// MyModalTrigger.js
module.exports = ModalTrigger.withContext({
foo: React.PropTypes.String
});
关于reactjs - 使用组件作为 prop 时,React 上下文不会传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30368433/