I have added a Googole button to sign in with google account. I have a state property called loggedIn which value is initially false for log in screen. When I am login 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 come back to login page.
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.