Cristian
Cristian

Reputation: 374

React hook issue. Is not re-render one component

I have created a global provider with a reducer that is holding the user state. When the user login successfully I dispatch and update the state, setting login=true. It is working perfectly in all components except for the top component where is not updating. I don't see any problem. Any idea what might be the problem?

// index.js
import './styles/tailwind.css'; 
import './styles/index.css';
import React from 'react';
import ReactDOM from 'react-dom';
import {StateProvider } from "./store";
import App from './App';

import * as serviceWorker from './serviceWorker';

const app = (
    <StateProvider>
        <App />
    </StateProvider>
);

ReactDOM.render(app, document.getElementById('root'));





//store.js - the provider that update the state
import React, {createContext, useReducer} from 'react';

const initialState = {
    login:false,
    token:'',
    refreshToken:'',
    user:{}
};

const store = createContext(initialState);
const { Provider } = store;

const StateProvider = ( { children } ) => {
    const [state, dispatch] = useReducer((state, action) => {

        switch(action.type) {
            case 'login user':
                state.login = true;
                state.token = action.token;
                state.refreshToken = action.refreshToken;

                return state;

            default:
                throw new Error();
        };

    }, initialState);

    return <Provider value={{ state, dispatch }}>{children}</Provider>;
};

export { store, StateProvider }


//App.js ---- in this page is not working, the rerendering doesn't happend and login remain false only in this component
import React, {useState, useContext, useEffect} from 'react';
import { store } from "./store";
import logo from './svg/book.svg';
import { BrowserRouter, Route, NavLink } from "react-router-dom";
import Classes from './components/school/Classes.js';
import Students from './components/school/Students.js';
import Home from './components/school/Home.js';
import Cards from './components/Cards.js';
import Login from "./components/Login";


function App() {

    const globalState =  useContext(store);
    const login = globalState.state.login;
    console.log(globalState);
    const message = (login) ? "Welcome user" : "You are not loged in";

  return (
    <div>
        <p>{message}</p>
       <BrowserRouter>
          <header className="grid grid-cols-1 sm:grid-cols-2">    
            <div className="flex align-middle"><img src={logo} className="h-12 p-1"></img>Bucharest Hi School
            </div>
              <div className="flex flex-wrap mr-5">
                <NavLink to="/"   className="w-full sm:w-1/4 text-center sm:text-right p-2" href="#" >Home</NavLink>
                <NavLink to="/classes"   className="w-full sm:w-1/4 text-center sm:text-right p-2" href="#" >Classes </NavLink>
                <NavLink to="/students" className="w-full sm:w-1/4 text-center sm:text-right p-2" href="#">Students</NavLink>
                <NavLink to="/statistics" className="w-full sm:w-1/4 text-center sm:text-right p-2" href="#">Statistics</NavLink>

                      <NavLink to="/logout" className="w-full sm:w-1/4 text-center sm:text-right bg-black text-white p-2" href="#">Logout</NavLink>

                      <NavLink to="/login" className="w-full sm:w-1/4 text-center sm:text-center bg-white rounded text-center p-2" href="#">Login</NavLink>

              </div>               
          </header>


          <div className="flex w-full flex-wrap justify-center my-10">

            <Route exact path="/" component={Home} />
            <Route path="/classes" component={Classes} /> 
            <Route path="/students" component={Students} />
            <Route path="/login" component={Login} />
          </div>
        </BrowserRouter>
    </div>
  );
}

export default App;

Thanks

Upvotes: 0

Views: 335

Answers (1)

Shashi Kumar
Shashi Kumar

Reputation: 96

You are mutating the state and returning same object in the reducer function, due to which your component assumes the data has never been changed.

Please make sure you return new object whenever you update your state, in your case you could use return { ...state }; instead of return state; in your reducer.

Upvotes: 2

Related Questions