The React Context API uses a Provider and Consumer pattern to share data throughout an application. The provider role is played by a React component that makes data available to its descendant components. When one of those descendants accesses the shared data, it becomes a consumer.
To use the React Context API, we start by creating a React context object, a named object created by the React.createContext()
function.
const MyContext = React.createContext();
Context objects include a .Provider
property that is a React component. It takes in a value
prop to be stored in the context.
<MyContext.Provider value="Hello world!"> <ChildComponent /> </MyContext.Provider>
That value — in this case, the string "Hello world!"
— is available to all its descendent components. Descendent components — in this case, ChildComponent
— can then retrieve the context’s value with React’s useContext()
hook.
import { useContext } from 'react'; import { MyContext } from './MyContext.js' const ChildComponent = () => { const value = useContext(MyContext); return <p>{value}</p>; } // Renders <p>Hello, world!</p>
The useContext()
hook accepts the context object as an argument and returns the current value of the context. Rejoice — prop drilling that value is no longer needed!
Note: If a component attempts to use a context that isn’t provided by one of its ancestors,
useContext()
will returnnull
.
Note: In some older React applications, you might instead see
SomeContext.Consumer
used to subscribe to a Context. That alternative is generally considered bad practice and avoided for being overly verbose and difficult to work with.
Instructions
In the workspace’s ThemeContext.js
file, use React.createContext()
to create a new context. Then, store the new context in a variable named ThemeContext
. Finally, export ThemeContext
as a named export.
Now that you’ve created a ThemeContext
, import it into the ContactsApp.js
file. In the ContactsApp
function component, wrap the existing returned children inside a <ThemeContext.Provider>
component with a value
prop set to "light"
.
You’ve successfully set up the ThemeContext
object’s .Provider
property to be used by the ContactsApp
component to provide the "light"
value to all its descendants. Let’s use that value in the ContactItem
component instead of the drilled theme prop.
In the ContactItem.js
file, remove the theme
prop from the ContactItem
component’s prop list. Have it use React’s useContext()
hook to retrieve the ThemeContext
’s provided theme
value instead.
Now that ContactItem
can retrieve the theme
using useContext()
, its parent component ContactList
doesn’t need to prop drill the theme
prop.
In ContactsList.js
, remove the unused prop drilling.
Now that ContactsList
components don’t need to prop drill a theme
prop, its parent component ContactsSection
doesn’t need to prop drill the theme
prop either.
In ContactsSection.js
, remove the unused prop drilling.
And finally, now that ContactsSection
components don’t need to prop drill a theme
prop, its parent component ContactsApp
doesn’t need to prop drill the theme
prop either.
In ContactsApp.js
, remove the unused prop drilling.