Context API - andrewkyllo-401-advanced-javascript/seattle-javascript-401d34 GitHub Wiki
- Provides a means of passing state down the component tree through a Provider/Consumer relationship
- At as high a level as makes sense, a provider can make its state available, along with the means of altering it
import React from 'react';
export const SettingsContext = React.createContext();
class SettingsProvider extends React.Component {
constructor(props) {
super(props);
this.state = {
changeTitleTo: this.changeTitleTo,
title: 'My Amazing Website',
};
}
changeTitleTo = title => {
this.setState({ title });
};
render() {
return (
<SettingsContext.Provider value={this.state}>
{this.props.children}
</SettingsContext.Provider>
);
}
}
export default SettingsProvider;
at the app level
<SettingsContext>
<Content />
</SettingsContext>
- At the lower levels any component can "opt-in" and become a "consumer" and receive
this.statefrom context - In a class style component, you can attach to context in 2 ways:
- Wrap your component with and use a function to "get" the context object itself, which is
this.statefrom the provider component
- Wrap your component with and use a function to "get" the context object itself, which is
<SettingsContext.Consumer>
{context => {
console.log(context);
return (
<div>
<h1>{context.title}</h1>
<button onClick={() => context.changeTitleTo('Your Website')}>
Change Title
</button>
</div>
);
}}
</SettingsContext.Consumer>
- Statically declare a connection to the context provider and then use `this.context to connect to the state from the context provider
import {SettingsContext} from '../settings/context.js';
class MyComponent extends React.Component {
static contextType = SettingsContext;
render() {
return (
<div>
<h1>{this.context.title}</h1>
<button onClick={() => this.context.changeTitleTo('Your Website')}>
Change Title
</button>
</div>
);
)
}
-
In a functional component, you can use the
useContext()hook to tap right in -
Returns and provides access to whatever your context provider exports
-
In this example, our context provider gives us a
titleproperty and achangeTitleTo()method that we can call. This is much easier than referencing the context variable inline as you normally would. -
Note - the context Api is still critically important even with this hook available. Not every React shop is using hooks, so know both ways
import faker from 'faker';
import { useContext } from 'react';
import { SettingsContext } from './settings/context';
function Counter() {
const context = useContext(SettingsContext);
return (
<div>
<h2>{context.title}</h2>
<button
type="button"
onClick={() => context.changeTitleTo(faker.company.companyName())}
>
Change Title
</button>
</div>
);
}
export default Counter;