You’re now going to learn to work with the member of the hooks family that lets you easily use React Context.
What’s React Context? 🤔
Context is a way of easily sharing props between components. It’s native to React, so there is no need to install anything else.
If you took the previous course, you’d have seen how to pass simple props between parent and child components and how to use props to lift state up. But can you imagine what that would be like in a complex application, where to pass a prop to a child component, you’d have to go through dozens of parent components that don’t need it?

Enter React Context, which lets you get your data without having to pass it manually. To do this, wrap the parent component that is highest up in the component tree with a Provider . All child components will then be able to connect to the Provider , thereby accessing the props without having to go through all of the components in between. These child components are known as Consumers .

The notion of quickly passing data between components is at the heart of many issues, ensuring code performs well and is readable. In particular, there are many discussions on how to manage state in a comprehensible way that performs well. This is known as state management. Ring any bells?
Before hooks came along, using context was much more difficult. Count yourself lucky that the useContext hook exists! 😍
useContextNow that you know what context is, let’s put it to work in the Shiny application.
What data should we put in the context?
React’s documentation states that “Context is designed to share data that can be considered global,” for example, current authenticated user, theme, or preferred language.
Let’s start by creating a dark mode for the app. As you’ll know, this is a theme using darker colors that gives your eyes a rest when looking at the screen.
To set this up, create a footer in which you add a button. In /components , create a Footer/index.jsx file that works in quite a basic way:
import styled from 'styled-components'
import colors from '../../utils/style/colors'
const FooterContainer = styled.footer`
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding-top: 60px;
`
const NightModeButton = styled.button`
background-color: transparent;
border: none;
cursor: pointer;
color: ${colors.secondary};
`
function Footer() {
return (
<FooterContainer>
<NightModeButton>Switch mode</NightModeButton>
</FooterContainer>
)
}
export default FooterUse this button in the footer to switch to dark mode in the app. Now create the context provider for the theme. To do this, make a folder especially for context in utils/context . Then create an index.jsx file .
To start, import { createContext } from react , and set up the context for the theme with:
export const ThemeContext = createContext()Next use ThemeContext :
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light')
const toggleTheme = () => {
setTheme(theme === 'light' ? 'dark' : 'light')
}
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
)
}We’ve created a component that wraps the parent component with the theme Provider . The theme state and the function to modify it, setTheme , are passed in the values . This means that all the child components wrapped by the Provider will be able to access theme and setTheme .
It’s now time to use the Provider at the highest level where components will need access to the context. Put it in index.jsx at the /src root . That gives you:
ReactDOM.render(
<React.StrictMode>
<Router>
<ThemeProvider>
<GlobalStyle />
<Header />
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/survey/:questionNumber">
<Survey />
</Route>
<Route path="/results">
<Results />
</Route>
<Route path="/freelancers">
Freelancers />
</Route>
<Route>
<Error />
</Route>
</Switch>
<Footer />
</ThemeProvider>
</Router>
</React.StrictMode>,
document.getElementById('root')
)Does this mean that we have to put the Provider at the level of the router ? 🤔
Well, not necessarily! As its name suggests, context “contextualizes” your data. Certain parts of the application need to know about certain parts of state, while others don’t. It’s up to you to decide where best to put it.
useContextBut wait, what’s useContext ?
useContext is a hook used for “hooking” from a child component that has been wrapped by a Provider , providing easy access to the shared state.
Let’s give it a go.
First, use the theme to make a very visible modification: changing the background-color across the whole application.
Before, GlobalStyle was in the index.jsx file at the /src root, but now move it into a separate file in /utils/style/GlobalStyle.jsx . You’re also going to change GlobalStyle to a function component that allows you to use hooks (before, it was just a styled-component). That gives you:
function GlobalStyle() {
return <StyledGlobalStyle />
}Next, import ThemeContext and useContext with:
import { useContext } from 'react'
import { ThemeContext } from '../context/ThemeProvider'Which lets you get the theme:
function GlobalStyle() {
const { theme } = useContext(ThemeContext)
return <StyledGlobalStyle isDarkMode={theme === 'dark'} />
}Pass an isDarkModeprop according to the theme activated.
In Style , use it like this:
const StyledGlobalStyle = createGlobalStyle`
* {
font-family: 'Trebuchet MS', Helvetica, sans-serif;
}
body {
/* Here this syntax goes back to the same as
background-color: ${({ props }) =>
props.isDarkMode ? '#2F2E41' : 'white'};
*/
background-color: ${({ isDarkMode }) => (isDarkMode ? 'black' : 'white')};
margin: 0;
}
`All that remains now is to tackle the final piece of the puzzle: implementing the button changes modes. ☀️/🌙
So let’s go back to Footer/index.jsx . Just like earlier, import ThemeContext and useContext .
Then get the action toggleTheme and theme with:
const { toggleTheme, theme } = useContext(ThemeContext)You can use it just underneath:
function Footer() {
const { toggleTheme, theme } = useContext(ThemeContext)
return (
<FooterContainer>
<NightModeButton onClick={() => toggleTheme()}>
Switch mode : {theme === 'light' ? '☀️' : '🌙'}
</NightModeButton>
</FooterContainer>
)
}Let’s test it out.
Amazing! 🤩

Great work: you’ve just created a context and used it with useContext to create a dark mode in your application. 🎉
As I’ve said, you’re lucky. Before hooks came along, context was much harder to implement. Watch the demonstration below to see how it used to work. 👇
It’s time to put all of this into practice. For this exercise, you’ll use context to get the results of your survey between pages.
Start the exercise on branch P2C2-begin. In context/index.jsx , you’ll find a ready-to-use SurveyProvider .
In /Survey/index.jsx , you’ll find the codebase for storing user responses in the context and buttons for entering responses.
Like in the first course, you’re using the spread operator to store the object. Remember learning that state is immutable in the chapter “Share State Between Different Components”? For this exercise, do the following:
Use useTheme in your Footer/index.jsx .
Use your SurveyProvider in src/index.jsx .
Save the results in your state from pages/Survey/index.jsx .
Get the results in /pages/results.jsx with useContext , and display them in a simple console.log() .
If you struggle, you’ll find all of the code for the solution on branch P2C2-solution.
Context is a React feature for sharing state between several parent and child components with the help of a provider.
useContext is a hook that lets you easily “hook into” context, thereby accessing shared state.
Using context is one method of state management, which can be combined with other methods such as Redux.
So, how was using context in your application with the useContext hook?
In the next chapter, you’ll learn more about hooks by creating your own custom ones. You’ll even see how to create your own useFetch hook to call an API. Sounds like fun, doesn’t it? 😎