Using React Context
React Context it’s a neat tool to manage states between components. When working with React we may end up with a large component tree, so passing information among them can result in passing the same prop multiple times to get it from one component to another.
Considering this component tree:
Let’s say that we need a data on component F that’s being gathered on component C, we would have to go through like this:
C -> B -> A -> E -> F
This scales depending on how big the tree is.
This is where context comes in handy, it makes a parent component provide the context and all its children (no matter how far away they are) access that information without any props.
Here is an example:
Let’s build a small context (using the useContext hook) for a movie streaming platform step by step:
Considering this structure:
- Step 1:
On a new file create the context:
Import React, { useState } from ‘react’; const userContext = React.createContext({ isLogged: false, onLogin: () => {}, }); export const UserProvider = (props) => { const [isLogged, setIsLogged] = useState(false); const loginHandler = () => { setIsLogged(true); }; return ( <UserProvider.Provider value={{ isLogged: isLogged, onLogin: loginHandler }} > {props.children} </UserProvider.Provider> ); }; export default UserContext;
Inside the context you can have a simple state (a number, a string, a boolean) or an object of different states (isLogged in this case)
- Step 2
Provide the context to the components: wrap the components that need access to the context (in this case <App />
because we need all components to have access to the context)
<UserProvider> <App /> </UserProvider>
- Step 3
Use the context in the components, for this example we are going to use it on the Login
and MoviesCatalog
components
In the Login
component, once the user enters their information and it’s validated we can save change the login flag to true
Import React, { useContext } from ‘react’; Import UserContext from ‘context file location’; const Login = () => { const userContext = useContext(UserContext); const onSubmit = (userInfo) => { `validates the user info` `if succeeded` userContext.onLogin(); } return ( <Login> Here it would go the login form </Login> ); }; export default Login;
In the example once the user info has been validated we call the onLogin()
function (on the context) and change the value of the isLogged
flag.
In the MoviesCatalog
component we would access the isLogged
state to know if there’s an user logged in to show them the movies
Import React, { useContext } from ‘react’; Import UserContext from ‘context file location’; const MoviesCatalog = () => { const userContext = useContext(UserContext); return ( {userContext.isLogged ? <Catalog /> : <p> You have to log in to see the movies </p> } ); }; export default MoviesCatalog;
In this case, we are using the isLogged
state to show (or not) the movies catalog to the user.
In neither case we needed to pass any props to each component, because we used the context to get access to the variables and functions needed.