React用户认证后跳转至原访问页面的实现方案(Formik+Django Knox)
在React中实现登录后跳转至目标页面(模拟Django的request.GET.next功能)
核心实现思路
借助React Router的useLocation和useNavigate钩子,在需要权限的页面将目标路径存入跳转状态,登录成功后读取该状态完成跳转,相比用localStorage存储更贴合单页应用的路由逻辑。
1. 修改详情页(DETAIL.js)的未授权跳转逻辑
当接口返回401未授权时,通过navigate的状态参数传递当前页面路径,替代localStorage存储:
const getPosts = async () => { const token = localStorage.getItem('token') const response = await fetch(`http://127.0.0.1:8000/${id}/`, { method: 'GET', headers: { 'Accept': 'application/json', 'Authorization': `Token ${token}`, 'Content-Type': 'application/json' } }) if (response.status === 401) { // 将当前页面路径存入路由跳转状态 navigate('/auth', { state: { from: window.location.pathname } }) } else { const data = await response.json() setPost(data.music) } }
2. 修改登录页(AUTH.js)的登录成功跳转逻辑
登录成功后,读取路由状态中的目标路径,存在则跳转至该路径,否则默认跳首页:
const { setIsLoggedIn, setUserData, isloggedIn } = useContext(AuthContext) const location = useLocation() const navigate = useNavigate() // 需引入React Router的useNavigate钩子 const loginformik = useFormik({ initialValues: { email: "", password: "", }, validationSchema: Yup.object({ email: Yup.string().email('无效邮箱地址').required(), password: Yup.string().min(6, '密码长度不能少于6位').required(), }), onSubmit: (values => { fetch('http://127.0.0.1:8000/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(values) }).then(res => res.json()).then(data => { localStorage.setItem('token', data.token) setUserData(data.user) setIsLoggedIn(true) // 跳转到预存的目标页面,默认跳首页 const targetPath = location.state?.from || '/' navigate(targetPath) }) }) })
补充说明
- 如果用户直接访问登录页,
location.state.from会为空,此时自动跳首页即可,上述代码已处理该场景 - 用路由状态存储目标路径比localStorage更干净,不会留下持久化的冗余数据,逻辑也更贴合路由跳转的生命周期
内容的提问来源于stack exchange,提问作者miracle godwin
相关产品推荐
相关产品推荐

