是的。考虑以下两个示例,每个示例都涉及三个嵌套组件。这两个示例都使用以下 HTML 文件:
文件 - index.html
<!DOCTYPE html>
<html>
<head>
<title>Hello React</title>
<!-- Not present in the tutorial. Just for basic styling. -->
<link rel="stylesheet" href="css/base.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/JSXTransformer.js"></script>
</head>
<body>
<div id="content"></div>
<script type="text/jsx" src="components/ParentComponent.jsx"></script>
<script type="text/jsx" src="components/ChildComponent.jsx"></script>
<script type="text/jsx" src="components/GrandchildComponent.jsx"></script>
<script type="text/jsx">
React.render(<ParentComponent />, document.getElementById('content'));
</script>
</body>
</html>
示例 1:
文件 - ParentComponent.jsx
var ParentComponent = React.createClass({
render: function () {
console.log("context in render method of ParentComponent: ");
for(var propName in this.context)
{
console.log(propName + ": " + this.context[propName]);
}
return (
<div>
<h1>Text displayed by ParentComponent</h1>
<ChildComponent />
</div>
);
},
//for sending to descendants
childContextTypes: {
styleA: React.PropTypes.object,
},
getChildContext() {
return {
styleA: customStyleA
};
}
});
var customStyleA = {
color: 'blue'
};
文件 - ChildComponent.jsx
var ChildComponent = React.createClass({
contextTypes: {
styleA: React.PropTypes.object
},
render: function () {
console.log("context in render method of ChildComponent: ");
for(var propName in this.context)
{
console.log(propName + ": " + this.context[propName]);
}
return (
<div>
<h1 style={this.context.styleA}>Text displayed by ChildComponent</h1>
<GrandchildComponent />
</div>
);
},
//for sending to descendants
childContextTypes: {
styleB: React.PropTypes.object,
},
getChildContext() {
return {
styleB: customStyleB
};
}
});
var customStyleB = {
color: 'red'
};
文件 - GrandchildComponent.jsx
var GrandchildComponent = React.createClass({
contextTypes: {
styleA: React.PropTypes.object,
styleB: React.PropTypes.object
},
render: function () {
console.log("context in render method of GrandchildComponent: ");
for(var propName in this.context)
{
console.log(propName + ": " + this.context[propName]);
}
return (
<h1 style={this.context.styleB}>Text displayed by GrandchildComponent</h1>
);
}
});
运行此示例后,控制台中的输出如下:
context in render method of ParentComponent:
context in render method of ChildComponent:
styleA: [object Object]
context in render method of GrandchildComponent:
styleA: [object Object]
styleB: [object Object]
可以看出,在这种情况下,ChildComponent 向上下文对象添加了一个新的key:value 对。因此,ChildComponent 的getChildContext() 函数返回的对象被添加到上下文中。
在输出中,第一行文字为黑色,第二行文字为蓝色,最后一行文字为红色。
示例 2
文件 - ParentComponent.jsx
var ParentComponent = React.createClass({
render: function () {
console.log("context in render method of ParentComponent: ");
for(var propName in this.context)
{
console.log(propName + ": " + this.context[propName]);
}
return (
<div>
<h1>Text displayed by ParentComponent</h1>
<ChildComponent />
</div>
);
},
//for sending to descendants
childContextTypes: {
styleA: React.PropTypes.object,
},
getChildContext() {
return {
styleA: customStyleA
};
}
});
var customStyleA = {
color: 'blue'
};
文件 - ChildComponent.jsx
var ChildComponent = React.createClass({
contextTypes: {
styleA: React.PropTypes.object
},
render: function () {
console.log("context in render method of ChildComponent: ");
for(var propName in this.context)
{
console.log(propName + ": " + this.context[propName]);
}
return (
<div>
<h1 style={this.context.styleA}>Text displayed by ChildComponent</h1>
<GrandchildComponent />
</div>
);
},
//for sending to descendants
childContextTypes: {
styleA: React.PropTypes.object,
},
getChildContext() {
return {
styleA: customStyleB
};
}
});
var customStyleB = {
color: 'red'
};
文件 - GrandchildComponent.jsx
var GrandchildComponent = React.createClass({
contextTypes: {
styleA: React.PropTypes.object,
styleB: React.PropTypes.object
},
render: function () {
console.log("context in render method of GrandchildComponent: ");
for(var propName in this.context)
{
console.log(propName + ": " + this.context[propName]);
}
return (
<h1 style={this.context.styleA}>Text displayed by GrandchildComponent</h1>
);
}
});
运行此示例后,控制台中的输出如下:
context in render method of ParentComponent:
context in render method of ChildComponent:
styleA: [object Object]
context in render method of GrandchildComponent:
styleA: [object Object]
styleB: undefined
可以看出,在这种情况下,ChildComponent 尝试将新的 key:value 对添加到上下文中。但是,由于密钥已经存在,其现有值被ChildComponent 提供的新值替换。本质上,新值 OVERRODE 之前的值。
输出与第一个示例相同。所以总的来说,可以推断出上下文可以被层次链上的组件修改。此外,如果此修改涉及现有键,则与该键对应的值将被覆盖(替换)。否则,只需将新的键:值对添加到上下文对象中。