Skip to content

Commit e12c600

Browse files
committed
Add advanced questions related to useContext hook
1 parent 9493350 commit e12c600

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

README.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6744,6 +6744,126 @@ Technically it is possible to write nested function components but it is not sug
67446744
67456745
**[⬆ Back to Top](#table-of-contents)**
67466746
6747+
284. ### Can You Use Multiple Contexts in One Component?
6748+
Yes, it is possible. You can use multiple contexts inside the same component by calling useContext multiple times, once for each context.
6749+
6750+
It can be achieved with below steps,
6751+
6752+
* Create multiple contexts using `createContext()`.
6753+
* Wrap your component tree with multiple `<Provider>`s.
6754+
* Call `useContext()` separately for each context in the same component.
6755+
6756+
**Example: Using `ThemeContext` and `UserContext` Together**
6757+
```js
6758+
import React, { createContext, useContext } from 'react';
6759+
6760+
// Step 1: Create two contexts
6761+
const ThemeContext = createContext();
6762+
const UserContext = createContext();
6763+
6764+
function Dashboard() {
6765+
// Step 2: Use both contexts
6766+
const theme = useContext(ThemeContext);
6767+
const user = useContext(UserContext);
6768+
6769+
return (
6770+
<div style={{ background: theme === 'dark' ? '#333' : '#fff' }}>
6771+
<h1>Welcome, {user.name}</h1>
6772+
<p>Current theme: {theme}</p>
6773+
</div>
6774+
);
6775+
}
6776+
6777+
// Step 3: Provide both contexts
6778+
function App() {
6779+
return (
6780+
<ThemeContext.Provider value="dark">
6781+
<UserContext.Provider value={{ name: 'Sudheer' }}>
6782+
<Dashboard />
6783+
</UserContext.Provider>
6784+
</ThemeContext.Provider>
6785+
);
6786+
}
6787+
6788+
export default App;
6789+
```
6790+
6791+
**[⬆ Back to Top](#table-of-contents)**
6792+
6793+
285. ### What's a common pitfall when using useContext with objects?
6794+
A **common pitfall** when using `useContext` with objects is **triggering unnecessary re-renders** across all consuming components — even when only part of the context value changes.
6795+
6796+
When you provide an object as the context value, React compares the entire object reference. If the object changes (even slightly), React assumes the whole context has changed, and **all components using** `useContext(MyContext)` **will re-render**, regardless of whether they use the part that changed.
6797+
6798+
**Example:**
6799+
```js
6800+
const MyContext = React.createContext();
6801+
6802+
function MyProvider({ children }) {
6803+
const [user, setUser] = useState(null);
6804+
const [theme, setTheme] = useState('light');
6805+
6806+
// This causes all consumers to re-render on any state change
6807+
const contextValue = { user, setUser, theme, setTheme };
6808+
6809+
return (
6810+
<MyContext.Provider value={contextValue}>
6811+
{children}
6812+
</MyContext.Provider>
6813+
);
6814+
}
6815+
```
6816+
In this case, a change in `theme` will also trigger a re-render in components that only care about `user`.
6817+
6818+
This issue can be fixed in two ways,
6819+
**1. Split Contexts**
6820+
Create separate contexts for unrelated pieces of state:
6821+
6822+
```jsx
6823+
const UserContext = React.createContext();
6824+
const ThemeContext = React.createContext();
6825+
```
6826+
6827+
**2. Memoize Context Value**
6828+
Use `useMemo` to prevent unnecessary re-renders:
6829+
6830+
```jsx
6831+
const contextValue = useMemo(() => ({ user, setUser, theme, setTheme }), [user, theme]);
6832+
```
6833+
6834+
However, this only helps if the object structure and dependencies are well controlled.
6835+
6836+
**[⬆ Back to Top](#table-of-contents)**
6837+
6838+
286. ### What would the context value be for no matching provider?
6839+
6840+
When a component calls `useContext(SomeContext)` but **no matching** `**<SomeContext.Provider>**` **is present higher up in the component tree**, the **default value** passed to `React.createContext(defaultValue)` is returned.
6841+
6842+
```js
6843+
const ThemeContext = React.createContext('light'); // 'light' is the default value
6844+
6845+
function ThemedComponent() {
6846+
const theme = useContext(ThemeContext);
6847+
return <div>Current theme: {theme}</div>;
6848+
}
6849+
6850+
// No ThemeContext.Provider anywhere in the tree
6851+
```
6852+
In this case, `theme` will be 'light'. It's the default value you provided when you created the context.
6853+
6854+
**Note:** If you don’t specify a default value, the context value will be undefined when used without a provider:
6855+
6856+
```jsx
6857+
const AuthContext = React.createContext(); // No default
6858+
6859+
function Profile() {
6860+
const auth = useContext(AuthContext);
6861+
// auth will be undefined if there's no AuthContext.Provider
6862+
}
6863+
```
6864+
6865+
**[⬆ Back to Top](#table-of-contents)**
6866+
67476867
## Old Q&A
67486868
67496869
1. ### Why should we not update the state directly?

0 commit comments

Comments
 (0)