You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Redux无法获取更新后的user状态值,求解决方案

解决React+Redux+Firebase登录后无法获取更新user值的问题

核心问题

你当前的代码中,登录成功后仅将用户信息存入localStorage,但没有同步更新Redux Store中的user状态。Redux的状态只有通过触发reducer更新才会通知组件重新渲染,因此Index.jsx中通过useSelector获取的始终是初始化时从localStorage读取的旧值。

解决方案步骤

1. 在Redux Slice中添加更新用户状态的Reducer

修改BooksSlice.jsx,新增一个setUser的reducer函数,用于更新Store中的user值:

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.find(book => book.id === id); // 替换filter为find,更高效
      if (isBookExist) {
        isBookExist.title = title;
        isBookExist.author = author;
      }
    },
    // 新增更新用户的reducer
    setUser: (state, action) => {
      state.user = action.payload;
    },
  },
});

// 导出新增的setUser action
export const { showBooks, addBook, deleteBook, updateBook, setUser } = BooksSlice.actions;
export default BooksSlice.reducer;

2. 在Login组件中触发更新Redux状态的Action

修改Login.jsx,导入useDispatch和setUser,在登录成功后dispatch这个action来同步更新Redux的user状态:

import React, { useState } from 'react';
import { signInWithEmailAndPassword } from 'firebase/auth';
import { auth } from '../firebase/firebase';
import { useNavigate } from 'react-router-dom';
// 新增导入
import { useDispatch } from 'react-redux';
import { setUser } from '../path/to/BooksSlice'; // 替换为你的实际路径

const Login = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState(false);

  const navigate = useNavigate();
  // 初始化dispatch
  const dispatch = useDispatch();

  // 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));
        // 新增:dispatch action更新Redux中的user状态
        dispatch(setUser(user));
        navigate('/show-books', { replace: true });
      })
      .catch(error => {
        setError(true);
      });
  };

  // 其余代码不变...
};

export default Login;

3. (可选)监听Firebase Auth状态变化,处理自动登录/登出

为了处理页面刷新、用户主动登出等场景,建议在Index.jsx中添加Firebase Auth状态监听,自动同步到Redux:

import React, { useEffect } from 'react';
import { useSelector, useDispatch } 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';
// 新增导入
import { auth } from '../firebase/firebase';
import { setUser } from '../path/to/BooksSlice'; // 替换为实际路径

const Index = () => {
  const { user } = useSelector(state => state.case);
  const dispatch = useDispatch();

  // 监听Auth状态变化
  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged(authUser => {
      if (authUser) {
        localStorage.setItem('user', JSON.stringify(authUser));
        dispatch(setUser(authUser));
      } else {
        localStorage.removeItem('user');
        dispatch(setUser(null));
      }
    });

    // 组件卸载时取消监听
    return () => unsubscribe();
  }, [dispatch]);

  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;

说明

完成以上修改后,登录成功时Redux Store的user状态会被更新,Index.jsx通过useSelector能实时获取到最新的用户信息,从而正确渲染对应的路由。

内容的提问来源于stack exchange,提问作者Mahbubul Hasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 10:33:46