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:

  1. Creating a context
  2. Providing the context
  3. 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;

Comments

No comments