Sławomir Kwiatkowski

by: Sławomir Kwiatkowski

2025/02/09

useContext hook



Content description:
In this post, I will describe how to use the useContext hook to display appropriate links depending on whether the user is already logged in or not.
If you are not logged in, the navigation bar will display Login and Register links, and after a successful login, a Logout link will be displayed.

In the project src directory I placed the context directory which contains the LoginContext.jsx file. In this file I create the context and provider.

     
import { useState, createContext } from "react"

export const LoginContext = createContext()

export const LoginProvider = ({children}) => {
  const [loginState, setLoginState] = useState(true)
  
  return (
    <LoginContext.Provider value={{loginState, setLoginState}}>
      {children}
    </LoginContext.Provider>
  ) 
}

The provider will pass the loginState variable and the setLoginState function to components.

The provider will be placed in the main layout so that all components can use it.

     
import {Outlet} from "react-router-dom"
import NavBar from "../components/NavBar"
import { createTheme } from '@mui/material/styles';
import { ThemeProvider } from "@emotion/react"
import { LoginProvider } from "../context/LoginContext";

function MainLayout() {
  const theme = createTheme({
      palette: {
        primary: {
          main: '#1b5e20',
        },
        secondary: {
          main: '#7b1fa2',
        },
      },
  });
  return (
    <ThemeProvider theme={theme}>
      <LoginProvider>
        <NavBar/> 
        <Outlet/>
      </LoginProvider>
    </ThemeProvider>
  )
}

export default MainLayout

loginState can now be used in all components, e.g. NavBar component

     
import { LoginContext } from '../context/LoginContext';
import { useContext } from 'react';

function NavBar() {
  const {loginState} = useContext(LoginContext)
  return (
    <Box sx={{ flexGrow: 1 }}>
      <AppBar position="static">
        <Toolbar>
          <img src={logo} style={{ width: 32, height: 32, paddingRight: 10 }}/>
          <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
            Contracts
          </Typography>
          <Link to='/contracts' style={{color: '#FFFFFF'}}>
            <Button color="inherit">Contracts</Button>
          </Link>
          <Link to='/warehouses' style={{color: '#FFFFFF'}}>
            <Button color="inherit">Warehouses</Button>
          </Link>
          {loginState ? 
            <div>
              <Link to='/register' style={{color: '#FFFFFF'}}>
                <Button color="inherit">Sign Up</Button>
              </Link>
              <Link to='/login' style={{color: '#FFFFFF'}}>
                <Button color="inherit">Login</Button>
              </Link>
            </div> :
            <Link to='/logout' style={{color: '#FFFFFF'}}>
            <Button color="inherit">Logout</Button>
          </Link>}
        </Toolbar>
      </AppBar>
    </Box>
  )
}

export default NavBar