Why does the state is updating automatically again in React JS?

Viewed 27

I have added a Google button to sign in with google account. I have a state property called loggedIn which value is initially false. When I log in with the Google Button I am also dispatching login reducer and state is updating and navigating to home but instantly the state again updates to false and comes back to the login page.

What problem I am getting is in the video: Problem | Clipchamp

redux.js

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

const slice = createSlice({
  name: 'chat-app',
  initialState: {
    profile: null,
    loggedIn: false,
  },
  reducers: {
    login: state => {
      state.loggedIn = true;
    },
    logout: state => {
      state.loggedIn = false;
    },
  },
});

export const { login, logout } = slice.actions;
export default slice.reducer;

store.js

import { configureStore } from '@reduxjs/toolkit';
import chatReducer from './slice';

const store = configureStore({
  reducer: {
    item: chatReducer,
  },
});

export default store;

In the App.jsx, I have added routing. Here it is checking the loggedIn value and set routing. Check it out.

import React from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/js/bootstrap.min.js';
import 'bootstrap-icons/font/bootstrap-icons.css';
import Home from './pages/Home';
import Authentication from './pages/Authentication';
import { Routes, Route, Navigate } from 'react-router-dom';
import { useSelector } from 'react-redux';

const App = () => {
  const { loggedIn } = useSelector(state => state.item);
  console.log("App", loggedIn);
  let routes;

  if (loggedIn) {
    routes = (
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/home" element={<Home />} />
        <Route path="/logout" element={<Authentication />} />
        <Route
          path="*"
          element={<Navigate to="/" replace />} //this is a way to redirect
        />
      </Routes>
    );
  } else {
    routes = (
      <Routes>
        <Route path="/auth" element={<Authentication />} />
        <Route
          path="*"
          element={<Navigate to="/auth" replace />} //this is a way to redirect
        />
      </Routes>
    );
  }

  return <>{routes}</>;
};

export default App;

Authentication.jsx, here in the signInWithGoogle function I have dispatch and navigate.

import React, { useState } from 'react';
import SignIn from '../components/SignIn';
import SignUp from '../components/SignUp';
import { auth } from '../firebase/firebase';
import { signInWithRedirect, GoogleAuthProvider } from 'firebase/auth';
import GoogleButton from 'react-google-button';
import { useNavigate } from 'react-router-dom';
import { login } from '../redux/slice';
import { useDispatch } from 'react-redux';

const Authentication = () => {
  const [page, setPage] = useState(true);
  const [data, setData] = useState({ email: '', password: '' });
  const [signUpData, setSignUpdData] = useState({
    firstName: '',
    lastName: '',
    email: '',
    password: '',
    confirmPassword: '',
    phoneNumber: '',
    dateOfBirth: '',
  });

  const pageHandler = () => {
    setPage(!page);
  };

  const dataHandler = event => {
    event.preventDefault();
    setData({ ...data, [event.target.name]: event.target.value });
  };

  const signUpDataHandler = event => {
    event.preventDefault();
    setSignUpdData({ ...signUpData, [event.target.name]: event.target.value });
  };

  const navigate = useNavigate();
  const dispatch = useDispatch();

  // Google Button sign in
  const signInWithGoogle = () => {
    const provider = new GoogleAuthProvider();
    signInWithRedirect(auth, provider);
    dispatch(login());
    navigate('/', { replace: true });
  };

  return (
    <div className="container mt-5">
      <div className="card mx-auto w-75 bg-success p-4">
        <div className="card-body ">
          {page ? (
            <SignIn data={data} dataHandler={dataHandler} />
          ) : (
            <SignUp
              signUpData={signUpData}
              signUpDataHandler={signUpDataHandler}
            />
          )}
        </div>
      </div>
      <div className="d-flex w-75 mx-auto my-3 align-items-center">
        <hr className="w-100 m-0 p-0" />
        <p className="m-0 mx-3">or</p>
        <hr className="w-100 m-0 p-0" />
      </div>
      <div className="d-flex justify-content-center">
        <div>
          <GoogleButton onClick={signInWithGoogle} />
        </div>
      </div>
      <button
        className="btn btn-outline-success mx-auto d-block my-3"
        onClick={pageHandler}>
        {page ? 'Sign Up' : 'Sign In'}
      </button>
    </div>
  );
};

export default Authentication;

Home.jsx

import React from 'react';
import ChatBox from '../components/ChatBox';
import Navbar from '../components/Navbar';
import './home.scss';
import { auth } from '../firebase/firebase';
import { useAuthState } from 'react-firebase-hooks/auth';

const Home = () => {
  const [user] = useAuthState(auth);
  console.log('Home', user);
  return (
    <div className="home-main bg-light">
      <Navbar user={user} />
      <ChatBox />
    </div>
  );
};

export default Home;

Navbar.jsx

import React from 'react';
import './navbar.scss';
import { Link } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { logout } from '../redux/slice';
import { auth } from '../firebase/firebase';

const Navbar = ({ user }) => {
  console.log('nav', user);

  const dispatch = useDispatch();

  const signOut = () => {
    signOut(auth);
    dispatch(logout());
  };

  return (
    <div className="bg-success navigation">
      <div className="chats d-flex flex-column align-items-center">
        <Link to="/">
          <i className="bi bi-house text-light" style={{ fontSize: '30px' }} />
        </Link>
        <Link to="/logout">
          <i
            className="bi bi-sign-turn-left text-light"
            onClick={() => auth.signOut()}
            style={{ fontSize: '30px' }}
          />
        </Link>
      </div>
      <div className="profile">
        <Link to="/" className="profile-link">
          <img
            className="profile-picture"
            src="https://res.cloudinary.com/djz3p8sux/image/upload/v1660556173/image/IMG_20220703_174147_w8fbhq.jpg"
            alt="profile-picture"
          />
        </Link>
      </div>
    </div>
  );
};

export default Navbar;

My problem is why after updating the state value loggedIn to true it is automatically updating again to false? How to fix that? I want to go to homepage after signing in.

1 Answers

Try fixing, in Navbar.jsx, the signOut function: I see that you doing recursion (calling the function in itself). Probably what you wanted to do is importing another signOut function from another file (I think). Try fixing this (you can change the name of the function so you will have two different ones).

Related