I am a beginner and I am learning react js. I made a crud app for practice. I am implementing firebase to this app for authentication. But the problem is that I am not getting the updated value.
Index.jsx
Here in line no 11, I am not getting the latest user
value.
import React, { useEffect } from 'react';
import { useSelector } from 'react-redux';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import ShowBooks from '../pages/ShowBooks';
import AddBook from '../pages/AddBook';
import EditBook from '../pages/EditBook';
import Login from '../pages/Login';
import Navbar from '../components/Navbar';
const Index = () => {
const { user } = useSelector(state => state.case);
let routes;
if (user === null || user === undefined) {
routes = (
<Routes>
<Route path="/login" element={<Login />} />
<Route path="*" element={<Navigate to="/login" replace={true} />} />
</Routes>
);
} else {
routes = (
<>
<Navbar />
<Routes>
<Route path="/" element={<ShowBooks />} />
<Route path="/show-books" element={<ShowBooks />} />
<Route path="/add-book" element={<AddBook />} />
<Route path="/edit-book" element={<EditBook />} />
<Route path="/login" element={<Login />} />
<Route path="*" element={<Navigate to="/" replace={true} />} />
</Routes>
</>
);
}
return <BrowserRouter>{routes}</BrowserRouter>;
};
export default Index;
Here is the code of BooksSlice.jsx:
import { createSlice } from '@reduxjs/toolkit';
import { v4 as uuidv4 } from 'uuid';
const initialBooks = {
books: [
{
id: uuidv4(),
title: 'Ordinary Differential Equation',
author: 'Prof. Md. Abu Yousuf',
},
{ id: uuidv4(), title: 'CSE Kit', author: 'Gyan Bitan' },
],
user: JSON.parse(localStorage.getItem('user')) || null,
};
export const BooksSlice = createSlice({
name: 'books',
initialState: initialBooks,
reducers: {
showBooks: state => state,
addBook: (state, action) => {
state.books.push(action.payload);
},
deleteBook: (state, action) => {
const id = action.payload;
state.books = state.books.filter(book => book.id !== id);
},
updateBook: (state, action) => {
const { id, title, author } = action.payload;
const isBookExist = state.books.filter(book => book.id === id);
if (isBookExist) {
isBookExist[0].title = title;
isBookExist[0].author = author;
}
},
},
});
export const { showBooks, addBook, deleteBook, updateBook } =
BooksSlice.actions;
export default BooksSlice.reducer;
Here is the code of store.js
import { configureStore } from '@reduxjs/toolkit';
import booksReducer from './BooksSlice';
const store = configureStore({
reducer: {
case: booksReducer,
},
});
export default store;
And here is Login.jsx code:
import React, { useState } from 'react';
import { signInWithEmailAndPassword } from 'firebase/auth';
import { auth } from '../firebase/firebase';
import { useNavigate } from 'react-router-dom';
const Login = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState(false);
const navigate = useNavigate();
// Login Handler Function
const loginHandler = event => {
event.preventDefault();
signInWithEmailAndPassword(auth, email, password)
.then(userCredential => {
// Signed in
const user = userCredential.user;
localStorage.setItem('user', JSON.stringify(user));
navigate('/show-books', { replace: true });
})
.catch(error => {
// const errorCode = error.code;
// const errorMessage = error.message;
setError(true);
});
};
return (
<div className="container pt-5">
{error && (
<p className="text-danger text-center">Wrong email or password!</p>
)}
<form className="w-75 mx-auto" onSubmit={loginHandler}>
<div className="form-floating mb-3">
<input
type="email"
className="form-control"
placeholder="Email"
value={email}
onChange={event => setEmail(event.target.value)}
required
/>
<label>Email</label>
</div>
<div className="form-floating my-3">
<input
type="password"
className="form-control"
placeholder="Password"
value={password}
onChange={event => setPassword(event.target.value)}
required
/>
<label>Password</label>
</div>
<button type="submit" className="btn btn-dark btn-lg text-light">
Log In
</button>
</form>
</div>
);
};
export default Login;
How can I get the updated user
value on Index.jsx?
CodePudding user response:
You need to create a "login" action and dispatch the authenticated user object to the store when a user authenticates.
Example:
export const BooksSlice = createSlice({
name: 'books',
initialState: initialBooks,
reducers: {
...
login: (state, action) => {
state.user = action.payload;
localStorage.setItem('user', JSON.stringify(action.payload));
},
},
});
export const {
showBooks,
addBook,
deleteBook,
updateBook,
login,
} = BooksSlice.actions;
export default BooksSlice.reducer;
...
import React, { useState } from 'react';
import { signInWithEmailAndPassword } from 'firebase/auth';
import { useDispatch } from 'react-redux';
import { auth } from '../firebase/firebase';
import { useNavigate } from 'react-router-dom';
import { login } from '../path/to/BooksSlice';
const Login = () => {
...
const navigate = useNavigate();
const dispatch = useDispatch();
// Login Handler Function
const loginHandler = event => {
event.preventDefault();
signInWithEmailAndPassword(auth, email, password)
.then(userCredential => {
// Signed in
const user = userCredential.user;
dispatch(login(user)); // <-- dispatch user object to store
navigate('/show-books', { replace: true });
})
.catch(error => {
// const errorCode = error.code;
// const errorMessage = error.message;
setError(true);
});
};
return (
...
);
};