我的目标是创建受保护的路线。现在这有点有效,但我需要手动刷新页面,以便在登录后将我导航到仪表板。目前发生的所有事情是:我登录,获得成功 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'
);
}
};```
在您的登录代码中,您可以使用 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;