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

React应用User属性传递异常,点击按钮后页面循环跳转求助

React页面循环跳转问题:点击按钮后反复重定向回主页

作为React新手,我开发的应用遇到了循环跳转问题:点击"Go to Sales Dashboard"按钮后,页面会不断在主页和销售仪表盘之间循环跳转。我怀疑是User属性没有正确传递,点击后alert显示{object, object},推测是user或handleLogout未正确获取,导致触发了返回主页的逻辑。

相关代码文件

Mainpage.js

import React, { useState, useEffect } from 'react';
import { Container, Typography, Button } from '@mui/material';
import { doc, getDoc } from 'firebase/firestore';
import { onAuthStateChanged, signOut } from 'firebase/auth';
import { auth, db } from '../firebase';
import { Link, useNavigate } from 'react-router-dom'; // Import useNavigate

const MainPage = () => {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  
  const navigate = useNavigate(); // Add this line

  const goToSalesDashboard = () => {
    navigate('/sales-dashboard', { state: { user } });
  };

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, async (currentUser) => {
      console.log('Current User:', currentUser);
      if (currentUser) {
        const userDocRef = doc(db, 'users', currentUser.uid);
        const userDocSnap = await getDoc(userDocRef);

        if (userDocSnap.exists()) {
          const userData = userDocSnap.data();
          setUser(userData);
          console.log('User data:', userData);
        } else {
          console.error('User not found in Firestore');
        }
      } else {
        setUser(null);
      }
      setLoading(false);
    });

    return () => {
      unsubscribe();
    };
  }, []);

  const handleLogout = async () => {
    try {
      await signOut(auth);
    } catch (error) {
      console.error('Error logging out:', error);
    }
  };

  if (loading) {
    return <Typography>Loading...</Typography>;
  }

  if (!user) {
    return <Typography>No user data found</Typography>;
  }

  return (
    <Container>
      <Typography>Name: {user.name}</Typography>
      <Typography>Role: {user.role}</Typography>
      <Typography>Company: {user.company}</Typography>
      {user.dateCreated && (
        <Typography>Date Created: {user.dateCreated.toDate().toLocaleDateString()}</Typography>
      )}
      <Button
        variant="contained"
        color="secondary"
        onClick={handleLogout}
        style={{ marginTop: '1rem' }}
      >
        Logout
      </Button>
      {user && (
        <Button
          variant="contained"
          color="primary"
          onClick={goToSalesDashboard} // Call the goToSalesDashboard function
          style={{ marginTop: '1rem', marginLeft: '1rem' }}
        >
          Go to Sales Dashboard
        </Button>
      )}
    </Container>
  );
};

export default MainPage;

SalesDashboard.js

import React from 'react';
import { Container, Button, Typography } from '@mui/material';
import { Link, useLocation, Navigate } from 'react-router-dom';

const SalesDashboard = () => {
  const location = useLocation();
  const { user, handleLogout } = location.state || {};

  if (!user || !handleLogout) {
    // Redirect to the main page if user or handleLogout is not available
    alert(user, handleLogout, location.state);
    return <Navigate to="/" />;
  }

    return (
        <Container>
            <Typography variant="h4" gutterBottom>
                Sales Dashboard
            </Typography>
            <div>
                <Button component={Link} to="/sales-dashboard/add-product" variant="contained" color="primary">
                    Añadir producto
                </Button>
                <Button variant="contained" color="primary">
                    Ingresar Venta
                </Button>
                <Button variant="contained" color="primary">
                    Consultar Puntos
                </Button>
                <Link
                    to={{
                        pathname: '/sales-dashboard/view-products',
                        state: { user },
                    }}
                >
                    <Button variant="contained" color="primary">
                        Ver Inventario
                    </Button>
                </Link>
            </div>
           
        </Container>

    );
};

export default SalesDashboard;
解决方案

问题核心

循环跳转的原因很明确:SalesDashboard组件里设置了!user || !handleLogout就重定向回主页,但MainPage跳转时只通过路由state传递了user,完全没传handleLogout。这个条件永远为真,一进入SalesDashboard就被踢回主页,主页又能重新跳过去,形成死循环。

具体修复

  1. 修改SalesDashboard的判断逻辑
    删掉对handleLogout的判断,只校验user是否存在即可——注销逻辑不需要通过路由传递,应该在组件内部单独实现或者用全局状态管理。修改后的代码片段:

    const location = useLocation();
    const { user } = location.state || {};
    
    if (!user) {
      alert('用户信息未传递,将返回主页');
      return <Navigate to="/" />;
    }
    
  2. 可选优化:全局管理用户状态
    用路由state传递用户信息不是长期方案,尤其是后续有更多页面需要用户数据时,建议使用React Context把用户状态全局共享,这样所有组件都能直接获取用户信息,不用每次跳转手动传参。

内容的提问来源于stack exchange,提问作者Fabricio la Torre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:43:16