React useContext rerender component

Viewed 5767

I am trying to use useContext hook instead of Redux in my app. Both Header component and Login page are using same context. Both are children of Routing component which is using context provider. In sign up form I am using hard coded data to check the functionality. The header is not rerendering after the sign up.

App.js (login component)

import React, { useContext, useState } from "react";
import { ExamContext } from "./Context/ExamContext";

function App() {
  const [user, setUser] = useState("");
  const [pass, setPass] = useState("");

  const { role, login } = useContext(ExamContext);

  const handleSubmit = () => {
    login(user, "Admin");
  };

  return (
    <React.Fragment>
      <div className="appbg">
        <div className="container">
          <div className="panel panel-success" style={{ marginTop: 20 }}>
            <div className="panel-heading">Login Forms</div>
            <div className="panel-body">
              <div className="form-group">
                <label>Email</label>
                <input
                  type="text"
                  className="form-control"
                  value={user}
                  onChange={e => setUser(e.target.value)}
                />
              </div>
            </div>
            <div className="panel-body">
              <div className="form-group">
                <label>Password</label>
                <input
                  type="password"
                  className="form-control"
                  value={pass}
                  onChange={e => setPass(e.target.value)}
                />
              </div>
            </div>
            <button className="btn btn-success" onClick={handleSubmit}>
              Submit
            </button>
          </div>
        </div>
      </div>
    </React.Fragment>
  );
}

export default App;

The Header component

const Header = () => {
  const { role } = useContext(ExamContext);

  const [user] = useState(role);

  switch (user) {
    case "Admin":
      return (
        <div>
          <h4>Admin</h4>
        </div>
      );
    case "User":
      return (
        <div>
          <h4>User</h4>
        </div>
      );
    default:
      return (
        <div>
          <h4>No User</h4>
        </div>
      );
  }
};
export default Header;

and The Context

import React, { createContext, useState } from "react";

const ExamContext = createContext();

const ExamConProvider = ({ children }) => {
  const [user, setUser] = useState("");
  const [role, setRole] = useState("NoUser");

  const login = (getuser, getrole) => {
    setRole(getrole);
    setUser(getuser);
  };

  return (
    <ExamContext.Provider value={{ user, role, login }}>
      {children}
    </ExamContext.Provider>
  );
};

export { ExamContext, ExamConProvider }; 

Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Routing from './components/Routing';
import { ExamConProvider } from './Context/ExamContext'
import './scss/style.scss';


ReactDOM.render(
    <ExamConProvider>
        <Routing />
    </ExamConProvider>
    ,document.getElementById("root"))

Routing Module

import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import App from '../App';
import Home from '../containers/Home';
import Header from '../components/Header';
import Footer from '../components/Footer';

const Routing = () => {
    return(
        <BrowserRouter>
        <Header />
            <Route exact path="/" component={App}></Route>
            <Route path="/home" component={Home}></Route>
        <Footer />
        </BrowserRouter>
    )
}

export default Routing;
1 Answers

not sure if you are asking why the header is not re-rendering. If yes, the reason is because you didn't add the Context Provider into the <App />.

You should add it like below:

import React, { useContext, useState } from 'react';
import { ExamConProvider, ExamContext } from './Context/ExamContext';
// Remember to import ExamConProvider at above line

function App() {

    // ... blah blah blah

    return(
        <ExamConProvider> {/* <--- Add this */}
            <React.Fragment>
                {/* Blah blah blah */}
            </React.Fragment>
        </ExamConProvider> {/* <--- Add this */}
    );
}

export default App;

Cheers!

Related