I know that in ReactJS, "context" can be used to pass down data from a component to its ancestors. However, can this context be modified along the hierarchy? If yes, how is this behavior described?
For instance: let's say that components are nested as follows: (A -> B -> C) component B is a child of component A, and component C is a child of component B. If A passes down some data through context, it can be accessed likewise from B and C. However, can B modify this context before it is passed down to C?
Updating Context value js components, we cannot update this value. To switch between the two theme types, we need to pass a function as well. This function will allow us to switch between both themes. So we need to pass this function along with the dark theme via the Provider component.
To update our state, we use this. setState() and pass in an object. This object will get merged with the current state. When the state has been updated, our component re-renders automatically.
Yes. Consider the following two examples, each involving three nested components. Both of these examples use the following HTML file:
File - 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>
EXAMPLE 1:
File - 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'
};
File - 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'
};
File - 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>
);
}
});
Upon running this example, this is the output in the console:
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]
As can be seen, in this case, ChildComponent
added a new key:value
pair to the context object. Hence, the object returned by the getChildContext()
function of ChildComponent got ADDED to the context.
In the output, the first line of text is black, the second line of text is blue, and the final line of text is red.
EXAMPLE 2
File - 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'
};
File - 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'
};
File - 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>
);
}
});
Upon running this example, this is the output in the console:
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
As can be seen, in this case, ChildComponent
tried to add a new key:value
pair to the context. However, since the key already existed, its existing value got replaced by the new value supplied by ChildComponent
. Essentially, the new value OVERRODE the previous value.
The output is the same as the first example. So in general, it can be inferred that the context can be modified by components along the hierarchy chain. Moreover, if this modification involves an existing key, the value corresponding to that key is overridden (replaced). Otherwise, the new key:value pairs are simply added to the context object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With