On Github pierr / react-context-example
A component has props and can have a state
var MyOldWayComponent = React.createClass({ displayName: 'MyOldWayComponent', render: function renderOldWayComponent(){ return <div>MyOldWayComponent</div>; } });
class MyClassComponent extends React.Component { render(){ const {state, props} = this; return ( <ul> <li>Props :{JSON.stringify(props)}</li> <li>State: {JSON.stringify(state)}</li> </ul> ); } }
function MyFunctionComponent(props) { return <div>Props: {JSON.stringify(props)}</div> }
class MyAwesomeRootComponent extends React.Component { render(){ return ( <div> <span>Component Awesome</span> <Child1/> {this.props.children} </div> ); } getChildContext(){ return {color: "purple"}; } } MyAwesomeRootComponent.childContextTypes = { color: React.PropTypes.string }
class ComponentUsingContext extends React.Component { render(){ const {color} = this.context; return <div>{color}</div>; } } ComponentUsingContext.contextTypes = { color: React.PropTypes.string }
function MyFuncComponent(props, context){ const {color} = this.context; return <div>{color}</div>; } } MyFuncComponent.contextTypes = { color: React.PropTypes.string }
function App(props){ return ( <MyAwesomeRootComponent> <span>App</span> <Child1 /> <Child2 /> <Child3 /> </MyAwesomeRootComponent> ); } render(<App/>, document.querySelector("div#root"));
class Parent extends React.Component { render(){ const {lang} = this.props; return ( <div><Child lang={lang}></div> ); } } function Child({lang}){ return (<div><GrandChild lang={lang}></div>); } function GrandChild({lang}){ return (<div>{lang}</div>); }
ReactDOM.render(<Parent lang='fr'/>, document.querySelector('div#app'));JSBIN
This problem is even more a pain when you need to abstract things in your components.
class Parent extends React.Component { getChildContext(){ return {this.props.lang}; } render(){ return ( <div><h1>Parent</h1><Child></div> ); } } Parent.childContextTypes = { lang: React.PropTypes.string };
function Child(props){ return (<div><h2>Child</h2><GrandChild></div>); } function GrandChild(props, {lang}){ return (<div><h3>Child</h3>{lang}</div>); } GrandChild.contextTypes = { lang: PropTypes.string } ReactDOM.render(<Parent lang='fr'/>, document.querySelector('div#app'))
Can we be inspired by something great?
import { createStore } from 'redux' import { Provider } from 'react-redux' import App from './containers/App' import todoApp from './reducers' let store = createStore(todoApp); let rootElement = document.getElementById('root') const ConnectedApp = connect(getState)(App) render( <Provider store={store}> <ConnectedApp /> </Provider>, rootElement )
a LangProvider and LangConnector
class Parent extends React.Component { render(){ return ( <div><h1>Parent</h1><Child/></div> ); } }
function Child({lang}){ return (<div><h2>Child</h2><GrandChild /></div>); } function GrandChild({lang}){ return (<div><h3>GrandChild</h3>{lang}</div>); } connectLang(GrandChild); ReactDOM.render(<LangProvider lang='fr'><Parent/></LangProvider>, document.querySelector('div#app'))
class LangProvider extends React.Component { getChildContext(){ return {lang: this.props.lang}; } render() { return this.props.children; } } Provider.childContextTypes = { lang: React.PropTypes.string };
function connectLang(ComponentToConnect){ class ConnectedOnLang extends React.Component { render() { const {lang} = this.context; return <ComponentToConnect lang={lang} {...this.props} /> ; } } ConnectedOnLang.displayName = `${ComponentToConnect.displayName}ConnectedOnLang`; ConnectedOnLang.contextTypes = { lang: React.PropTypes.string.isRequired }; return ConnectedOnLang; }
RouteComponent, RouteComponent
React utility belt for function components and higher-order components
{ movie: { code: { domain: 'DO_ID', required: true }, title: { domain: 'DO_LABEL_LONG', required: true }, originalTitle: { domain: 'DO_LABEL_LONG', required: false } } }
When you cannot convert your mixin in an Higher Order Component
When you want to abstract something For things such as current user, language, theme, metadata. Every where you would have use a global variable or a separate module. When you wan to abstract a behaviour (often use to be complex mixins).