Using multiple context in a class component

How can I use multiple Contexes in a React Class Component? Like how you can use multiple contexes in functional components like calling useContext twice or more on the contexes that you want to use?

export default class Component extends React.Component{

static contextType = LocalizationContext;

constructor(props){
    super(props);

    this.imageModule = new ImageModule();
    this.state = {

    }
}

componentDidMount = () => console.log(this.context);

render(){
    return(
        <React.Fragment>
            {}
        </React.Fragment>
    );
}

}

Upvotes: 15

Views: 12421

Answers (2)

Nicholas Tower
Nicholas Tower

Reputation: 85281

The static contextType property won't work if you need more than one, so instead you need to use a context consumer. This is easiest when you only need the value in the render function:

export class Example extends React.Component {
  render() {
    <LocalizationContext.Consumer>
      {(translate) => (
        <SomeOtherContext.Consumer>
          {(value) => (
            <div>{translate(value)}</div>
          )}
        </SomeOtherContext.Consumer>
      )}
    </LocalizationContext.Consumer>
  }
}

If you need the value in other lifecycle hooks, such as componentDidMount, then your best option is to wrap this component in one that can read the values from context and then pass them in as props:

export const Example = (props) => (
  <LocalizationContext.Consumer>
    {(translate) => (
      <SomeOtherContext.Consumer>
        {(value) => (
          <InnerComponent translate={translate} value={value} {...props} />
        )}
      </SomeOtherContext.Consumer>
    )}
  </LocalizationContext.Consumer>
)

class InnerComponent extends React.Component {
  componentDidMount() {
    // something with props.translate or props.value
  }
}

Francisco Garcia's solution is also a good one.

Upvotes: 23

Francisco Garcia
Francisco Garcia

Reputation: 376

A modern take on Nicholas Tower's solution above. Thanks Nicholas!

Before hooks, this problem was addressed using the render props pattern. This is made much easier now using the useContext hook:

const Example = (props) => {
  const translate = useContext(LocalizationContext);
  const value = useContext(SomeOtherContext);

  return <InnerComponent translate={translate} value={value} />
} 

class InnerComponent extends React.Component {
  componentDidMount() {
    // something with props.translate or  props.value
  }
}

Upvotes: 11

Related Questions