;
}
-});
+}
```
In this example, we manually thread through a `color` prop in order to style the `Button` and `Message` components appropriately. Theming is a good example of when you might want an entire subtree to have access to some piece of information (a color). Using context, we can pass this through the tree automatically:
-```javascript{2-4,7,18,25-30,33}
-var Button = React.createClass({
- contextTypes: {
- color: React.PropTypes.string
- },
- render: function() {
+```javascript{4,11-13,19,26-28,38-40}
+class Button extends React.Component {
+ render() {
return (
);
}
-});
+}
-var Message = React.createClass({
- render: function() {
+Button.contextTypes = {
+ color: React.PropTypes.string
+};
+
+class Message extends React.Component {
+ render() {
return (
;
}
-});
+}
+
+MessageList.childContextTypes = {
+ color: React.PropTypes.string
+};
```
By adding `childContextTypes` and `getChildContext` to `MessageList` (the context provider), React passes the information down automatically and any component in the subtree (in this case, `Button`) can access it by defining `contextTypes`.
-If `contextTypes` is not defined, then `this.context` will be an empty object.
+If `contextTypes` is not defined, then `context` will be an empty object.
## Parent-child coupling
@@ -150,13 +153,11 @@ void componentDidUpdate(
Stateless functional components are also able to reference `context` if `contextTypes` is defined as a property of the function. The following code shows the `Button` component above written as a stateless functional component.
```javascript
-function Button(props, context) {
- return (
-
- );
-}
+const Button = ({children}, context) =>
+ ;
+
Button.contextTypes = {color: React.PropTypes.string};
```
@@ -165,31 +166,36 @@ Button.contextTypes = {color: React.PropTypes.string};
The `getChildContext` function will be called when the state or props changes. In order to update data in the context, trigger a local state update with `this.setState`. This will trigger a new context and changes will be received by the children.
```javascript
-var MediaQuery = React.createClass({
- getInitialState: function(){
- return {type:'desktop'};
- },
- childContextTypes: {
- type: React.PropTypes.string
- },
- getChildContext: function() {
+class MediaQuery extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {type:'desktop'};
+ }
+
+ getChildContext() {
return {type: this.state.type};
- },
- componentDidMount: function(){
- var checkMediaQuery = function(){
- var type = window.matchMedia("(min-width: 1025px)").matches ? 'desktop' : 'mobile';
- if (type !== this.state.type){
- this.setState({type:type});
+ }
+
+ componentDidMount() {
+ const checkMediaQuery = () => {
+ const type = window.matchMedia("(min-width: 1025px)").matches ? 'desktop' : 'mobile';
+ if (type !== this.state.type) {
+ this.setState({type});
}
};
window.addEventListener('resize', checkMediaQuery);
checkMediaQuery();
- },
- render: function(){
+ }
+
+ render() {
return this.props.children;
}
-});
+}
+
+MediaQuery.childContextTypes = {
+ type: React.PropTypes.string
+};
```
## When not to use context