MyContext.js
import React from "react"; const MyContext = React.createContext('test'); export default MyContext;
I created my context in a separated js
file where I can access my parent as well as my child component
Parent.js
import MyContext from "./MyContext.js"; import Child from "./Child.js"; class Parent extends Component { constructor(props) { super(props); this.state = { Message: "Welcome React", ReturnMessage:"" }; } render() { return ( <MyContext.Provider value={{state: this.state}}> <Child /> </MyContext.Provider> ) } }
So I created the parent component with a Provider context and calling child component in the provider tab
Child.js
import MyContext from "./MyContext.js"; class Child extends Component { constructor(props) { super(props); this.state = { ReturnMessage:"" }; } ClearData(context){ this.setState({ ReturnMessage:e.target.value }); context.state.ReturnMessage = ReturnMessage } render() { return ( <MyContext.Consumer> {(context) => <p>{context.state.Message}</p>} <input onChange={this.ClearData(context)} /> </MyContext.Consumer> ) } }
So in child by using the Consumer
, I can display the data in child rendering part.
I'm facing an issue when I want to update the state from the consumer.
How to update provider state or manipulate state of provider?
To update a React Context from inside a child component, we can wrap the React Context provider around the child components. Then we set the value prop of the context provider to the the state setter function that lets us update the context value. Then we can use the useContext hook to access the context.
To access a React context outside of the render function, we can use the useContext hook. We create the UserContext by calling the React. createContext method with a default context value. Then in the Users component, we call the useContext hook with UserContext to accxess the current value of UserContext .
To pass multiple values in React Context, we can use the Provider API. Also, we can easily consume the context data by utilizing the useContext React Hook. However, it is important to understand the basic syntax and approach behind this. To get a better idea, let us look at a simple example.
You could use the useContext hook to achieve this. It's quite easy to use it in the child elements of the Provider. As an example...
authContext.js
import { createContext } from "react"; const authContext = createContext({ authenticated: false, setAuthenticated: (auth) => {} }); export default authContext;
Login.js (component consuming the Context)
import React, { useContext } from "react"; import authContext from "./authContext"; export default () => { const { setAuthenticated } = useContext(authContext); const handleLogin = () => setAuthenticated(true); const handleLogout = () => setAuthenticated(false); return ( <React.Fragment> <button onClick={handleLogin}>login</button> <button onClick={handleLogout}>logout</button> </React.Fragment> ); };
Finally the index.js
import ReactDOM from "react-dom"; import React, { useState } from "react"; import authContext from "./authContext"; import Login from "./Login"; const App = () => { const [authenticated, setAuthenticated] = useState(false); return ( <authContext.Provider value={{ authenticated, setAuthenticated }}> <div> user is {`${authenticated ? "" : "not"} authenticated`} </div> <Login /> </authContext.Provider> ); }; ReactDOM.render(<App />, document.getElementById("container"));
As you can see, it becomes quite easy to consume the data stored in the context using the useContext hook. Of course, as with every React hook, it only works with functional components.
If you want to see the code working. https://codesandbox.io/s/react-playground-forked-wbqsh?file=/index.js
It is often necessary to update the context from a component that is nested somewhere deeply in the component tree. In this case you can pass a function down through the context to allow consumers to update the context:
theme-context.js
// Make sure the shape of the default value passed to // createContext matches the shape that the consumers expect! export const ThemeContext = React.createContext({ theme: themes.dark, toggleTheme: () => {}, });
theme-toggler-button.js
import {ThemeContext} from './theme-context'; function ThemeTogglerButton() { // The Theme Toggler Button receives not only the theme // but also a toggleTheme function from the context return ( <ThemeContext.Consumer> {({theme, toggleTheme}) => ( <button onClick={toggleTheme} style={{backgroundColor: theme.background}}> Toggle Theme </button> )} </ThemeContext.Consumer> ); } export default ThemeTogglerButton;
app.js
import {ThemeContext, themes} from './theme-context'; import ThemeTogglerButton from './theme-toggler-button'; class App extends React.Component { constructor(props) { super(props); this.toggleTheme = () => { this.setState(state => ({ theme: state.theme === themes.dark ? themes.light : themes.dark, })); }; // State also contains the updater function so it will // be passed down into the context provider this.state = { theme: themes.light, toggleTheme: this.toggleTheme, }; } render() { // The entire state is passed to the provider return ( <ThemeContext.Provider value={this.state}> <Content /> </ThemeContext.Provider> ); } } function Content() { return ( <div> <ThemeTogglerButton /> </div> ); } ReactDOM.render(<App />, document.root);
The above example is straight from the React Context API docs v16.8.6, and is the recommended way to update a context value from a consumer. https://reactjs.org/docs/context.html#updating-context-from-a-nested-component
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With