Context API Lucas Lira Gomes <@x8lucas8x>
Software Engineer Passionate Hacker ArchLinux Zealot FOSS Enthusiast I’m fond of doing things that last and all that jazz. Lucas Lira Gomes 2 contact@x8lucas8x.com linkedin.com/in/x8lucas8x facebook.com/x8lucas8x youtube.com/X80lucas08X twitter.com/x8lucas8x x8lucas8x.com github.com/x8lucas8x
Context API ● Built in ○ React 16.3 ● Solution for ○ “Prop-drilling”
That rings a bell ● Idea is not novel ○ Experimental API ■ 16.X ● Mobx ○ @inject ● React-intl ○ @injectIntl ● React-redux ○ @connect ● React-router ○ @withRouter
API Overview ● React.createContext(defaultValue); ○ <Producer value={...}/> ○ <Consumer> {context => (...)} </Consumer>
Single Context import React, { Component } from 'react'; const ContextA = React.createContext(); class ParentComponent extends Component { state = {data: "SomeValue"}; render() { return ( <ContextA.Provider value={this.state}> {this.props.children} </ContextA.Provider> ... const ChildComponent = () => ( <ContextA.Consumer> {context=> <h1>{context.data}</h1>} </ContextA.Consumer> );
Multiple Contexts import React, { Component } from 'react'; const ContextA = React.createContext(); const ContextB = React.createContext(); class ParentComponent extends Component { state = {data: "SomeValue"}; render() { return ( <ContextA.Provider value={this.state.dataA}> <ContextB.Provider value={this.state.dataB}> {this.props.children} </ContextB.Provider> </ContextA.Provider> ... const ChildComponent = () => ( <ContextA.Consumer> {ctxA => ( <ContextB.Consumer> {ctxB => <h1>{ctxA} or {ctxB}</h1>} </ContextB.Consumer> )} </ContextA.Consumer> );
Updating the Context ... const ContextB = React.createContext(); class ParentComponent extends Component { state = { isClicked: false, onClick: () => this.setState({isClicked: true}) }; render() { return ( <ContextA.Provider value={this.state}> {this.props.children} </ContextA.Provider> ... const ChildComponent = () => ( <ContextA.Consumer> {context => ( <button onClick={context.onClick}> Click me! </button> )} </ContextA.Consumer> );
Applications ● “Global” for a tree ○ Localisation ○ Routing ○ Theme ○ User ○ ...
Good Practices
Avoid re-renders ● Use the state ○ Referential identity import React, { Component } from 'react'; const ContextA = React.createContext(); class ParentComponent extends Component { render() { return ( <ContextA.Provider value={{clicked: true}}> {this.props.children} </ContextA.Provider> ...
Keep it DRY ● HOCs to the rescue import React, { Component } from 'react'; const WhateverContext = React.createContext(); export function withWhatever(Component) { return function ThemedComponent(props) { return ( <WhateverContext.Consumer> {context => ( <Component {...props} whatever={context.whatever} /> )} </WhateverContext.Consumer> ); }; }
References 1. https://reactjs.org/docs/context.html 13
Context API Lucas Lira Gomes <@x8lucas8x>

Context API in React

  • 1.
    Context API Lucas LiraGomes <@x8lucas8x>
  • 2.
    Software Engineer Passionate Hacker ArchLinuxZealot FOSS Enthusiast I’m fond of doing things that last and all that jazz. Lucas Lira Gomes 2 contact@x8lucas8x.com linkedin.com/in/x8lucas8x facebook.com/x8lucas8x youtube.com/X80lucas08X twitter.com/x8lucas8x x8lucas8x.com github.com/x8lucas8x
  • 3.
    Context API ● Builtin ○ React 16.3 ● Solution for ○ “Prop-drilling”
  • 4.
    That rings abell ● Idea is not novel ○ Experimental API ■ 16.X ● Mobx ○ @inject ● React-intl ○ @injectIntl ● React-redux ○ @connect ● React-router ○ @withRouter
  • 5.
    API Overview ● React.createContext(defaultValue); ○<Producer value={...}/> ○ <Consumer> {context => (...)} </Consumer>
  • 6.
    Single Context import React,{ Component } from 'react'; const ContextA = React.createContext(); class ParentComponent extends Component { state = {data: "SomeValue"}; render() { return ( <ContextA.Provider value={this.state}> {this.props.children} </ContextA.Provider> ... const ChildComponent = () => ( <ContextA.Consumer> {context=> <h1>{context.data}</h1>} </ContextA.Consumer> );
  • 7.
    Multiple Contexts import React,{ Component } from 'react'; const ContextA = React.createContext(); const ContextB = React.createContext(); class ParentComponent extends Component { state = {data: "SomeValue"}; render() { return ( <ContextA.Provider value={this.state.dataA}> <ContextB.Provider value={this.state.dataB}> {this.props.children} </ContextB.Provider> </ContextA.Provider> ... const ChildComponent = () => ( <ContextA.Consumer> {ctxA => ( <ContextB.Consumer> {ctxB => <h1>{ctxA} or {ctxB}</h1>} </ContextB.Consumer> )} </ContextA.Consumer> );
  • 8.
    Updating the Context ... constContextB = React.createContext(); class ParentComponent extends Component { state = { isClicked: false, onClick: () => this.setState({isClicked: true}) }; render() { return ( <ContextA.Provider value={this.state}> {this.props.children} </ContextA.Provider> ... const ChildComponent = () => ( <ContextA.Consumer> {context => ( <button onClick={context.onClick}> Click me! </button> )} </ContextA.Consumer> );
  • 9.
    Applications ● “Global” fora tree ○ Localisation ○ Routing ○ Theme ○ User ○ ...
  • 10.
  • 11.
    Avoid re-renders ● Usethe state ○ Referential identity import React, { Component } from 'react'; const ContextA = React.createContext(); class ParentComponent extends Component { render() { return ( <ContextA.Provider value={{clicked: true}}> {this.props.children} </ContextA.Provider> ...
  • 12.
    Keep it DRY ●HOCs to the rescue import React, { Component } from 'react'; const WhateverContext = React.createContext(); export function withWhatever(Component) { return function ThemedComponent(props) { return ( <WhateverContext.Consumer> {context => ( <Component {...props} whatever={context.whatever} /> )} </WhateverContext.Consumer> ); }; }
  • 13.
  • 14.
    Context API Lucas LiraGomes <@x8lucas8x>