react-router 停留在登录页面而不是仪表板路线

问题描述 投票:0回答:1

我的目标是创建受保护的路线。现在这有点有效,但我需要手动刷新页面,以便在登录后将我导航到仪表板。目前发生的所有事情是:我登录,获得成功 toast,它尝试导航到仪表板,但它返回登陆页面。然后我需要手动重新加载页面才能访问仪表板。

routes.jsx

import React, { useContext } from 'react';
import { UserContext } from './context/userContext';
import {
    BrowserRouter as Router,
    Route,
    Routes,
    Navigate,
} from 'react-router-dom';
import Dashboard from './pages/dashboard';
import Landingpage from './pages/landingpage';
import Profile from './pages/profile';
import Login from './pages/auth/login';
import Register from './pages/auth/register';
import Friends from './pages/friends';
import Notifications from './pages/notifications';
import { Loader } from 'lucide-react';

function MyRoutes() {
    const { user, loading } = useContext(UserContext);

    if (loading) {
        return <Loader />;
    }

    return (
        <Router>
            <Routes>
                {user ? (
                    <>
                        <Route path='/dashboard' element={<Dashboard />} />
                        <Route path='/profile' element={<Profile />} />
                        <Route path='/friends' element={<Friends />} />
                        <Route
                            path='/notifications'
                            element={<Notifications />}
                        />
                        <Route
                            path='*'
                            element={<Navigate to='/dashboard' />}
                        />
                    </>
                ) : (
                    <>
                        <Route path='/' element={<Landingpage />} />
                        <Route path='/login' element={<Login />} />
                        <Route path='/register' element={<Register />} />
                        <Route path='*' element={<Navigate to='/login' />} />
                    </>
                )}
            </Routes>
        </Router>
    );
}

export default MyRoutes;

userContext.jsx

import React, { createContext, useState, useEffect } from 'react';
import axios from 'axios';

export const UserContext = createContext();

export const UserContextProvider = ({ children }) => {
    const [user, setUser] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        setLoading(true);
        axios
            .get('/profile')
            .then((response) => {
                if (response.data.success) {
                    setUser(response.data.user);
                } else {
                    setUser(null);
                }
            })
            .catch(() => {
                setUser(null);
            })
            .finally(() => {
                setLoading(false);
            });
    }, []);

    return (
        <UserContext.Provider value={{ user, setUser, loading, setLoading }}>
            {children}
        </UserContext.Provider>
    );
};

authContoller.jsx(后端路由/配置文件)

const getProfile = async (req, res) => {
    logger.info(texts.INFO.ATTEMPTING_PROFILE_RETRIEVAL);
    const { token } = req.cookies;

    if (token) {
        jwt.verify(
            token,
            'idsfu&ASUDIhiedUioGYUYFHIUGTygbhbhY3427HS',
            {},
            async (err, decoded) => {
                if (err) {
                    logger.warn(texts.WARNINGS.INVALID_TOKEN);
                    return res.json({ error: texts.WARNINGS.INVALID_TOKEN });
                }

                try {
                    const user = await User.findById(decoded.id).select(
                        '-password -goals'
                    );
                    if (!user) {
                        logger.warn(texts.WARNINGS.USER_NOT_FOUND);
                        return res
                            .status(404)
                            .json({ error: texts.WARNINGS.USER_NOT_FOUND });
                    }

                    logger.info(texts.SUCCESS.USER_LOGGED_IN(user.username));
                    res.json({ success: true, user });
                } catch (error) {
                    logger.error(
                        texts.ERRORS.ERROR('user profile retrieval', error)
                    );
                    res.status(500).json({
                        error: texts.ERRORS.USER_PROFILE_RETRIEVAL,
                    });
                }
            }
        );
    } else {
        logger.warn(texts.WARNINGS.NO_TOKEN_FOUND);
        res.json(texts.WARNINGS.NO_TOKEN_FOUND);
    }
};

login.jsx(仅逻辑)

const [data, setData] = useState({
        emailOrUsername: '',
        password: '',
    });
    const { setUser } = useContext(UserContext);
    const navigate = useNavigate();
    const { addToast } = useToast();

    const loginUser = async (event) => {
        event.preventDefault();
        const { emailOrUsername, password } = data;
        try {
            const { data } = await axios.post('/login', {
                emailOrUsername,
                password,
            });

            if (data.error) {
                addToast(data.error, 'error');
            } else {
                setUser(data.user);
                setData({});
                navigate('/dashboard');
                addToast('Login erfolgreich!', 'success');
            }
        } catch (error) {
            addToast(
                'Login fehlgeschlagen. Bitte versuchen Sie es erneut. ' + error,
                'error'
            );
        }
    };```
javascript reactjs react-router react-router-dom
1个回答
0
投票

在您的登录代码中,您可以使用 useEffect 来跟踪用户的状态更改并进行导航,以便当他们更改时,React 会知道某些内容已更改并触发重定向

参见示例代码

import React, { useContext, useEffect } from 'react';
import { UserContext } from './context/userContext';
import { useNavigate } from 'react-router-dom';
import { useToast } from './path-to-your-toast-context'; // Update with actual path
import axios from 'axios';

const Login = () => {
    const [data, setData] = useState({
        emailOrUsername: '',
        password: '',
    });
    const { user, setUser } = useContext(UserContext);
    const navigate = useNavigate();
    const { addToast } = useToast();

    // Effect for navigation based on user state
    useEffect(() => {
        if (user) {
            navigate('/dashboard');
        }
    }, [user, navigate]);

    const loginUser = async (event) => {
        event.preventDefault();
        const { emailOrUsername, password } = data;
        try {
            const { data } = await axios.post('/login', {
                emailOrUsername,
                password,
            });

            if (data.error) {
                addToast(data.error, 'error');
            } else {
                setUser(data.user); // This will trigger the useEffect above
                setData({});
                addToast('Login erfolgreich!', 'success');
            }
        } catch (error) {
            addToast(
                'Login fehlgeschlagen. Bitte versuchen Sie es erneut. ' + error,
                'error'
            );
        }
    };

    return (
        <form onSubmit={loginUser}>
            {/* Your form elements go here */}
        </form>
    );
};

export default Login;

© www.soinside.com 2019 - 2024. All rights reserved.