-
Notifications
You must be signed in to change notification settings - Fork 4.1k
[Edit] React: Context #7441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
mamtawardhani
wants to merge
3
commits into
Codecademy:main
Choose a base branch
from
mamtawardhani:context
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+160
−7
Open
[Edit] React: Context #7441
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,184 @@ | ||
--- | ||
Title: 'Context' | ||
Description: 'In React, Context can be used to manage state globally without the need of prop drilling.' | ||
Description: 'Enables data sharing across the component tree without passing props down manually at every level.' | ||
Subjects: | ||
- 'Mobile Development' | ||
- 'Web Development' | ||
Tags: | ||
- 'Components' | ||
- 'React' | ||
- 'Components' | ||
CatalogContent: | ||
- 'react-101' | ||
- 'paths/front-end-engineer-career-path' | ||
--- | ||
|
||
The **Context** API in [React](https://www.codecademy.com/resources/docs/react) is an easy way to manage the state of some information. It lets the parent [component](https://www.codecademy.com/resources/docs/react/components) pass the information down to any other component further down the tree hierarchy without needing to pass it as a [prop](https://www.codecademy.com/resources/docs/react/props). It can be used in combination with the [`useState()`](https://www.codecademy.com/resources/docs/react/hooks/useState) hook to change the state. Typical use cases are passing themes (e.g. color, paddings, font sizes, etc.) or the authenticated user. | ||
**Context** in [React](https://www.codecademy.com/resources/docs/react) is a feature that allows data to be shared across the component tree without passing props manually at every level. It solves the prop drilling problem by enabling [components](https://www.codecademy.com/resources/docs/react/components) to access shared state directly, no matter their depth in the hierarchy. This is useful when multiple components at different nesting levels need access to the same data, such as authentication state, theme preferences, or application settings. | ||
|
||
## Implementation Methods | ||
|
||
Context is implemented using three core React APIs: | ||
|
||
- `createContext()`: Creates a new context object that can hold and share data | ||
- `Context.Provider`: A component that supplies the context value to its descendants | ||
- `useContext()`: A React hook that consumes context values within functional components | ||
|
||
The typical setup is: | ||
|
||
1. Create a context using `createContext()` with an optional default value. | ||
2. Wrap components needing access in `Context.Provider` and pass the shared value via the `value` prop. | ||
3. Use `useContext()` in child components to consume the nearest context value. | ||
|
||
## Example 1: Theme Management with React Context | ||
|
||
This example demonstrates creating a theme context for managing application-wide color themes: | ||
|
||
```jsx | ||
import React, { createContext, useContext, useState } from 'react'; | ||
|
||
// Define context type | ||
interface ThemeContextType { | ||
theme: 'light' | 'dark'; | ||
toggleTheme: () => void; | ||
} | ||
|
||
// Create context with default value | ||
const ThemeContext = | ||
createContext < | ||
ThemeContextType > | ||
{ | ||
theme: 'light', | ||
toggleTheme: () => {}, | ||
}; | ||
|
||
// Provider component | ||
const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ | ||
children, | ||
}) => { | ||
const [theme, setTheme] = (useState < 'light') | ('dark' > 'light'); | ||
|
||
const toggleTheme = () => { | ||
setTheme((prev) => (prev === 'light' ? 'dark' : 'light')); | ||
}; | ||
|
||
return ( | ||
<ThemeContext.Provider value={{ theme, toggleTheme }}> | ||
{children} | ||
</ThemeContext.Provider> | ||
); | ||
}; | ||
|
||
// Consumer component | ||
const ThemedButton: React.FC = () => { | ||
const { theme, toggleTheme } = useContext(ThemeContext); | ||
|
||
return ( | ||
<button | ||
onClick={toggleTheme} | ||
style={{ | ||
backgroundColor: theme === 'light' ? '#ffffff' : '#333333', | ||
color: theme === 'light' ? '#000000' : '#ffffff', | ||
padding: '10px 20px', | ||
border: 'none', | ||
borderRadius: '4px', | ||
}} | ||
> | ||
Switch to {theme === 'light' ? 'dark' : 'light'} theme | ||
</button> | ||
); | ||
}; | ||
|
||
// Main app | ||
const App: React.FC = () => ( | ||
<ThemeProvider> | ||
<div style={{ padding: '20px' }}> | ||
<h1>Theme Example</h1> | ||
<ThemedButton /> | ||
</div> | ||
</ThemeProvider> | ||
); | ||
|
||
export default App; | ||
``` | ||
|
||
The `ThemeContext` holds the current theme and a function to toggle it. `ThemeProvider` manages the state, while `ThemedButton` consumes it for UI changes. | ||
|
||
## Example 2: Sharing User Data with React Context | ||
|
||
This example demonstrates sharing user information across components without prop drilling: | ||
|
||
```jsx | ||
import React, { createContext, useContext, useState } from 'react'; | ||
|
||
// Define user type | ||
interface User { | ||
name: string; | ||
role: string; | ||
} | ||
|
||
// Create context | ||
const UserContext = (createContext < User) | (null > null); | ||
|
||
// Provider | ||
const UserProvider: React.FC<{ children: React.ReactNode }> = ({ | ||
children, | ||
}) => { | ||
const [user] = | ||
useState < | ||
User > | ||
{ | ||
name: 'John Doe', | ||
role: 'Administrator', | ||
}; | ||
|
||
return <UserContext.Provider value={user}>{children}</UserContext.Provider>; | ||
}; | ||
|
||
// Consumers | ||
const Header: React.FC = () => { | ||
const user = useContext(UserContext); | ||
|
||
return ( | ||
<header style={{ padding: '1rem', backgroundColor: '#f0f0f0' }}> | ||
<h1>Welcome, {user?.name}!</h1> | ||
</header> | ||
); | ||
}; | ||
|
||
const UserProfile: React.FC = () => { | ||
const user = useContext(UserContext); | ||
|
||
return ( | ||
<div style={{ padding: '1rem' }}> | ||
<h2>User Profile</h2> | ||
<p>Name: {user?.name}</p> | ||
<p>Role: {user?.role}</p> | ||
</div> | ||
); | ||
}; | ||
|
||
// Main app | ||
const App: React.FC = () => ( | ||
<UserProvider> | ||
<Header /> | ||
<UserProfile /> | ||
</UserProvider> | ||
); | ||
|
||
export default App; | ||
``` | ||
|
||
The `UserContext` stores user information. Both `Header` and `UserProfile` read from the same source without manually passing props. | ||
|
||
## Frequently Asked Questions | ||
|
||
### 1. Why do we need to use Context? | ||
|
||
It avoids passing props through multiple layers when many components need the same data. This makes code easier to maintain. | ||
|
||
## Benefit | ||
### 2. Is React Context a hook? | ||
|
||
Normally, information on values is passed between components as props. But sometimes it has to be passed down several levels in the tree, also called `prop drilling`. In larger applications, this can be complicated and lead to code that is hard to maintain. With `Context` this is no longer necessary. | ||
No, React Context is not a hook. Context is a feature consisting of `createContext()` and Provider/Consumer components. However, `useContext()` is a hook that allows functional components to consume context values. | ||
|
||
## API Implementation | ||
### 3. When to use React Context vs Redux? | ||
|
||
To implement the Context API, it's necessary to first create the Context using [`createContext()`](https://www.codecademy.com/resources/docs/react/context/createContext). Afterward, the [`useContext()`](https://www.codecademy.com/resources/docs/react/hooks/useContext) hook can be used to read the context from the appropriate component. | ||
Use Context for simpler state management like themes, user data, or small-to-medium applications. Choose Redux for complex applications with frequent state updates, complex state logic, and when you need advanced debugging tools. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.