To pass data through the component tree
In React, data is passed from top-down (parent to child) via props by drilling/passing the props at each direct child level. Context provides a way to pass data through multi-level child component tree without having to passing the props at each direct child level.
The React Context API is designed to share data: - between a provider component and its descendants, - not between a provider and its ancestor.
returns: createContext returns a context object.
const someContextObj = createContext(defaultValue)
Wrap your components into a context provider to specify the value of this context for all components inside:
<someContextObj.Provider value={someData}>
<Page />
</someContextObj.Provider>
Before useContext existed, there was an older way to read context:
<someContextObj.Consumer> <h1>{someData}</h1> </someContextObj.Consumer>
Although this older way still works, but newly written code should read context with useContext()
instead:
useContext
is a React Hook that lets you read and subscribe to context from your component.
//In Consumer component
const someData = useContext(someContextObj)
returns: useContext
returns the context value for the calling component.
Example 1:
Context lets components pass information deep down without explicitly passing props.
Call createContext
outside any components to create one or more contexts.
myContext.js
import { createContext } from "react";
//createContext returns a context object.
const myNewContext_1 = createContext("Karthi");
const myNewContext_2 = createContext("Monisha");
export { myNewContext_1, myNewContext_2 };
A.js
import { myNewContext_1, myNewContext_2 } from "./myContext";
import { useContext } from "react";
function A() {
//Components can read context by passing it to useContext()
const data1 = useContext(myNewContext_1);
const data2 = useContext(myNewContext_2);
return (
<div>
<h1>{data1}</h1> //Karthi
<p>{data2}</p> //Monisha
</div>
);
}
export default A;
Example 2:
Let' say there are components A,B,C. Iam going to pass data from A to C component directly
Context lets components pass information deep down without explicitly passing props.
Call createContext
outside any components to create one or more contexts.
MyContext.js
import { createContext } from "react";
const ThemeContext = createContext();
const AuthContext = createContext();
export { ThemeContext, AuthContext };
A.js
import { useState } from "react";
import { ThemeContext, AuthContext } from "./MyContext";
import B from "./B.js";
import "./A.css";
function A2() {
const [theme, setTheme] = useState("light");
const [user, setUser] = useState({ name: "karthi" });
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<AuthContext.Provider value={user}>
<B />
</AuthContext.Provider>
</ThemeContext.Provider>
);
}
export default A;
B.js
import C from "./C";
function B() {
return (
<div>
This is B componenet
<C />
</div>
);
}
export default B;
C.js
import { useContext } from "react";
import { ThemeContext, AuthContext } from "./MyContext";
function C() {
const { theme, setTheme } = useContext(ThemeContext);
const user = useContext(AuthContext);
return (
<div class={theme}>
This is C componenet
<p>{user.name}</p>
<button
onClick={() =>
setTheme(theme === "light" ? "dark" : "light")
}
>
Change Theme
</button>
</div>
);
}
export default C;
You can pass callback functions from the parent to the child components as props. The child components can then call these functions to communicate with the parent
(Pass data in the function call parameter).
eg: func1(data)
If your application is complex and you need to manage global state, you might consider using state management libraries like Redux. These libraries allow you to manage application state in a centralized store that can be accessed by any component.
You could use an event bus or a pub/sub pattern to create a simple mechanism for components to communicate indirectly. However, this approach can lead to some challenges and is generally not recommended for complex applications.