Search code examples
javascriptreactjsfirebasereduxredux-toolkit

redux state is not resetting to initial state value


In my header component, there is a sign in link when the user signs in the user is authenticated and stored in firesbase and when they sign out the 'currentUser' state is set to its initial value (null). previously the header component is getting the state from App.js. However, I'm trying to implement redux toolkit and after doing so, once I signed in the currentUser state is holding on to the value and not resetting to null after signing out (and the way i coded it was to check for the current user state, if it was null or an object and then toggle the sign In/sign out button). I'm just learning redux so I understand I might have done something silly but I can't seem to get over this obstacle. App.js


    class App extends React.Component {
      
    
      unsubscribeFromAuth=null;
    
      componentDidMount(){
        const {setCurrentUser}=this.props
    
        this.unsubscribeFromAuth=auth.onAuthStateChanged( async userAuth=>{
        
          if (userAuth){
            const userRef= await createdUserProfileDocument(userAuth);
    
            userRef.onSnapshot(snapShot=>{
             setCurrentUser({
                 id:snapShot.id,
                    ...snapShot.data()
              })
                })
              
          
          }else
          setCurrentUser({userAuth})
          
        })
      }
    
    componentWillUnmount(){
      this.unsubscribeFromAuth();
    }
    
      render(){
         return (
        <div className='App'>
            <Header />
            <Routes>
               <Route  path='/' element={<HomePage />} />  
               <Route path='/shop' element={<ShopPage />} />
               <Route exact path='/signin' element={ <SignInAndSignUp/>}/>
            </Routes> 
        </div>
      );
      } 
    }
    const mapStateToProps=({user})=>({
      currentUser:user.currentUser
    })
     const mapDispatchToProps=dispatch=>({
       setCurrentUser:user=>dispatch(setCurrentUser(user))
     })
    
    export default connect(mapStateToProps, mapDispatchToProps)(App);

Header.js


    const Header=({currentUser})=>{
       
        return(
        <div className="header">
            <Link className="logo-container" to='/'>
                <Logo className="logo"/>
            </Link>
        <div className="options">
            <Link className="option" to='/shop'>
                Shop
            </Link>
            <Link className="option" to='/contact'>
                Contact
            </Link>
                {
                currentUser ?
                <div className="option" onClick={()=> auth.signOut()}>SIGN OUT </div>
                :
                <Link className="option" to='/signIn'>SIGN IN</Link>
                }
        </div>
        </div>
    )}
     const mapStateToProps=(state)=>({
         currentUser:state.user.currentUser
     })
    
    //    
    export default  connect(mapStateToProps)(Header);

UserSlice.js [redux file]

import { createSlice } from "@reduxjs/toolkit";

const initialState= {
    currentUser: null
}

  const userSlice= createSlice({
     name:'user', 
     initialState,
     reducers:{
         setCurrentUser:(state, action)=>{
             state.currentUser=action.payload
         }
     }
  })
export default userSlice.reducer;
export const {setCurrentUser}=userSlice.actions

store.js [redux file]

import { configureStore} from "@reduxjs/toolkit";
import logger from "redux-logger";
import  userReducer  from './user/userSlice';



const store= configureStore({
    reducer:{
       user:userReducer
    },
    
    middleware:(getDefaultMiddleware)=>getDefaultMiddleware({serializableCheck:false}).concat(logger)
    
    
})

export default store;

When I stored the state locally in App.js it works fine, I can sign in and sign out and current user state resets to null value when signing out. Then, I integrated redux toolkit successfully however the state doesn't seem to be resetting to initial value when signing out

To be more precise the problem lies here...after signing in when I attempt to sign out the sign out button was supposed to toggle to Sign In according to the following condition in Header component file

           {
            currentUser ?
            <div className="option" onClick={()=> auth.signOut()}>SIGN OUT </div>
            :
            <Link className="option" to='/signIn'>SIGN IN </Link>
            }

Solution

  • I see you are using the setCurrentUser function to change the global state of Redux. Usually the Redux Provider is connected at the very top and will never be unmounted (I don't know about your case, probably the same). Since it will not be unmounted, its state will never be reset. You need to do it yourself. You already have the setCurrentUser function. Make another one like deleteCurrentUser. And add it to componentWillUnmount

    Update:
    In general, yes, you can not write a new reducer, but use setCurrentUser. And I seem to understand what this.unsubscribeFromAuth is. You say it has worked before. Let's assume it is. After logout state.currentUser={userAuth:null}. Perhaps this is the problem. As far as I understood from your code, there should be null instead of an object, try making a call to setCurrentUser(null) enter image description here