Browse Source

Context docs updated with ES6 examples (#6852)

main
Alex Zherdev 9 years ago
committed by Jim
parent
commit
b10ed5de2b
  1. 126
      docs/12-context.md

126
docs/12-context.md

@ -24,82 +24,85 @@ Occasionally, you want to pass data through the component tree without having to
Suppose you have a structure like: Suppose you have a structure like:
```javascript ```javascript
var Button = React.createClass({ class Button extends React.Component {
render: function() { render() {
return ( return (
<button style={{'{{'}}background: this.props.color}}> <button style={{'{{'}}background: this.props.color}}>
{this.props.children} {this.props.children}
</button> </button>
); );
} }
}); }
var Message = React.createClass({ class Message extends React.Component {
render: function() { render() {
return ( return (
<div> <div>
{this.props.text} <Button color={this.props.color}>Delete</Button> {this.props.text} <Button color={this.props.color}>Delete</Button>
</div> </div>
); );
} }
}); }
var MessageList = React.createClass({ class MessageList extends React.Component {
render: function() { render() {
var color = "purple"; const color = "purple";
var children = this.props.messages.map(function(message) { const children = this.props.messages.map((message) =>
return <Message text={message.text} color={color} />; <Message text={message.text} color={color} />
}); );
return <div>{children}</div>; return <div>{this.props.children}</div>;
} }
}); }
``` ```
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: 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} ```javascript{4,11-13,19,26-28,38-40}
var Button = React.createClass({ class Button extends React.Component {
contextTypes: { render() {
color: React.PropTypes.string
},
render: function() {
return ( return (
<button style={{'{{'}}background: this.context.color}}> <button style={{'{{'}}background: this.context.color}}>
{this.props.children} {this.props.children}
</button> </button>
); );
} }
}); }
var Message = React.createClass({ Button.contextTypes = {
render: function() { color: React.PropTypes.string
};
class Message extends React.Component {
render() {
return ( return (
<div> <div>
{this.props.text} <Button>Delete</Button> {this.props.text} <Button>Delete</Button>
</div> </div>
); );
} }
}); }
var MessageList = React.createClass({ class MessageList extends React.Component {
childContextTypes: { getChildContext() {
color: React.PropTypes.string
},
getChildContext: function() {
return {color: "purple"}; return {color: "purple"};
}, }
render: function() {
var children = this.props.messages.map(function(message) { render() {
return <Message text={message.text} />; const children = this.props.messages.map((message) =>
}); <Message text={message.text} />
);
return <div>{children}</div>; return <div>{children}</div>;
} }
}); }
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`. 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 ## 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. 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 ```javascript
function Button(props, context) { const Button = ({children}, context) =>
return (
<button style={{'{{'}}background: context.color}}> <button style={{'{{'}}background: context.color}}>
{props.children} {children}
</button> </button>;
);
}
Button.contextTypes = {color: React.PropTypes.string}; 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. 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 ```javascript
var MediaQuery = React.createClass({ class MediaQuery extends React.Component {
getInitialState: function(){ constructor(props) {
return {type:'desktop'}; super(props);
}, this.state = {type:'desktop'};
childContextTypes: { }
type: React.PropTypes.string
}, getChildContext() {
getChildContext: function() {
return {type: this.state.type}; return {type: this.state.type};
}, }
componentDidMount: function(){
var checkMediaQuery = function(){ componentDidMount() {
var type = window.matchMedia("(min-width: 1025px)").matches ? 'desktop' : 'mobile'; const checkMediaQuery = () => {
if (type !== this.state.type){ const type = window.matchMedia("(min-width: 1025px)").matches ? 'desktop' : 'mobile';
this.setState({type:type}); if (type !== this.state.type) {
this.setState({type});
} }
}; };
window.addEventListener('resize', checkMediaQuery); window.addEventListener('resize', checkMediaQuery);
checkMediaQuery(); checkMediaQuery();
}, }
render: function(){
render() {
return this.props.children; return this.props.children;
} }
}); }
MediaQuery.childContextTypes = {
type: React.PropTypes.string
};
``` ```
## When not to use context ## When not to use context

Loading…
Cancel
Save