2

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;
skyboyer
  • 22,209
  • 7
  • 57
  • 64
Hasan Zubairi
  • 1,037
  • 4
  • 23
  • 57

2 Answers2

0

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!

Wing Choy
  • 900
  • 10
  • 25
0

You should try use the setUser and setRole state on your login component instead of using a function of the context.

In the login component try this:

    function App() {
      // renamed the input state
      const [userInput, setUserInput] = useState("");
      const [passInput, setPassInput] = useState("");
    
      const { role, setUser, setRole } = useContext(ExamContext);
    
      const handleSubmit = () => {
          // setting the context state on Login component
          setUser(userInput);
          setRole("Admin");
      };
Victor Hugo
  • 31
  • 1
  • 4