React useContext hook : A Beginner's Guide
What is useContext() hook?
React useContext()
hook provides data to nested component. Using useContext()
hook it is very easy to manage certain state like user information globally. With the help of useContext()
we can create common data that can be accessed and modify throughout the component hierarchy.
How to use React Context?
To use useContext()
we need to follow following steps:
- Creating a context
- Providing the context
- Consuming the context
1. Creating a context
we need to import createContext
from React which creates a context instance with its default value. Here we are taking a scenario where we need to set a global user name and at first, we do not have any user so the default value will be null
:
//fileName: UserContex.js
import { createContext } from "react";
const userContext = createContext(null);
export default userContext;
2. Providing the context
To provide context we need to wrap the tree of components with Context Provider. Context Provider wraps child components and supplies the state value. So, first of all, let's import our context instance in the App.js
file and provide the value.
import UserContex from './components/UserContex';
import Login from './components/Login';
import Signup from './components/Signup';
import Home from './components/Home';
import Profile from './components/Profile';
import {Route ,Routes} from "react-router-dom";
import UserContex from './components/UserContex';
function App() {
const [user, setUser] = useState(null);
return (<>
<UserContex.Provider value={{user, setUser}}>
<Navbar/>
<Routes>
<Route path='/' element = {<Home/>}/>
<Route path = "/login" element ={<Login/>} />
<Route path = "/signup" element = {<Signup/>} />
<Route path='/profile' element = {<Profile/>}/>
</Routes>
</UserContex.Provider>
</>
);
}
export default App;
3. Consuming the context
Now we can access this value anywhere in our component tree. To use value we need another hook called useContext
and we need to our context instance as well. Frist of all let's set our user. For that we have a signup form once the user type name, emali and password we will set email id as user and redirect user to prifile
page. At the same time our Navbar
links will change and display user email at top.
import React, { useContext, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import userContext from "./UserContex";
const Signup = ()=>{
const {setUser} = useContext(userContext);
const navigate = useNavigate();
const [user,setSignUser] = useState({
userName:"",
email: "",
password: ""
});
const inputHandeler = (e)=>{
setSignUser({...user,[e.target.name]:e.target.value})
}
const [error, setError] = useState(null)
const formHandeler = (e)=>{
e.preventDefault();
if(user.userName.trim()=== ""|| user.email.trim() === "" || user.password.trim()=== "")return setError("All fields are required to fill")
setUser(user.email);
setSignUser({
userName:"",
email: "",
password: ""
})
setError(null)
navigate("/profile");
}
return( <div className="form-container">
<form className="Auth-form">
<div className="Auth-form-content">
<h3 className="Auth-form-title">Sign Up</h3>
<div className="text-center">
Already registered?
<span className="link-primary">
<Link className = 'nav-link'to = "/login">Sign In</Link>
</span>
{error && <div className="”alert error"> {error} </div>}
</div>
<div className="form-group mt-1">
<label>Full Name</label>
<input
type="email" onChange={inputHandeler} value={user.userName} name="userName"
className="form-control mt-1"
placeholder="e.g Jane Doe"
/>
</div>
<div className="form-group mt-1">
<label>Email address</label>
<input
type="email" onChange={inputHandeler} value={user.email} name = "email"
className="form-control mt-1"
placeholder="Enter email"
/>
</div>
<div className="form-group mt-1">
<label>Password</label>
<input
onChange={inputHandeler}
type="password" value={user.password} name = "password"
className="form-control mt-1"
placeholder="Enter password"
/>
</div>
<div className="d-grid gap-2 mt-3">
<button type="submit"onClick={formHandeler} className="btn btn-primary">
Submit
</button>
</div>
<p className="forgot-password text-right mt-2">
Forgot <Link to = "/passwordreset" > Password</Link>
</p>
</div>
</form>
</div>)
}
export default Signup;
Navbar.js
import React, {useContext} from 'react';
import {Link} from "react-router-dom";
import Container from 'react-bootstrap/Container';
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import userContext from './UserContex';
function Navigation() {
const {user} = useContext(userContext);
return (<>
<Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
<Container>
<Nav className="me-auto">
{user && <Navbar.Brand>{user}</Navbar.Brand>}
<Link className='nav-link' to = "/">Home</Link>
{user ? (<Link className = 'nav-link 'to = "/profile">Profile</Link>):(<><Link className = 'nav-link 'to = "/Signup">Sign up</Link>
<Link className='nav-link' to = "/login">Log In</Link>
</>
)}
</Nav>
</Container>
</Navbar>
</>
);
}
export default Navigation;