【发布时间】:2021-05-26 02:18:30
【问题描述】:
我正在努力查明我的代码存在什么问题。基本上,我设置了一个 hooks.js 文件,如果用户通过身份验证,则检查并获取当前用户详细信息,否则返回 null。这个钩子应该是一个辅助函数,然后控制对页面的访问(即尝试访问登录/注册页面的经过身份验证的用户将被重定向到仪表板,反之亦然)。
但是,它目前只能部分工作。例如,如果我登录然后尝试访问登录/注册页面,它会自动将我重定向到仪表板页面。但是,如果我已注销并尝试访问仪表板,我可以访问它,但它不会将我重定向到登录页面。有谁知道我做错了什么?我试图通过遵循代码流(控制台在各个地方登录)来调试它,甚至在 hooks.js 中,它似乎 应该 已经执行了 Router.push(redirectTo) 代码但它似乎并没有这样做。任何帮助表示赞赏(以及下面包含的代码的 sn-ps)!
hooks.js
import { useEffect } from 'react';
import Router from 'next/router';
import useSWR from 'swr';
const fetcher = (url) =>
fetch(url)
.then((r) => r.json())
.then((data) => {
if (data?.user) {
return { user: data?.user };
} else {
return null;
}
});
export function useUser({ redirectTo, redirectIfFound } = {}) {
const { data, error } = useSWR('api/users/profile', fetcher);
const user = data?.user;
const finished = Boolean(data);
const hasUser = Boolean(user);
useEffect(() => {
if (!redirectTo || !finished) return;
if (
// If redirectTo is set, redirect if the user was not found.
(Boolean(redirectTo) && !redirectIfFound && !hasUser) ||
// If redirectIfFound is also set, redirect if the user was found
(redirectIfFound && hasUser)
) {
Router.push(redirectTo);
}
}, [redirectTo, redirectIfFound, finished, hasUser]);
return error ? null : user;
}
dashboard.js
import React from 'react';
import PrivateRouteLayout from '../components/privateRouteLayouts';
import { useUser } from '../lib/hooks';
function Dashboard() {
useUser({ redirectTo: '/signin', redirectIfFound: false });
return (
<PrivateRouteLayout title='Dashboard'>
<div>
<h1>Welcome !</h1>
</div>
</PrivateRouteLayout>
);
}
export default Dashboard;
signinform.js
import React, { useState, useEffect } from 'react';
import Link from 'next/link';
import Router from 'next/router';
import { useUser } from '../lib/hooks';
import validateSigninInput from '../lib/validation/login';
function SigninForm() {
useUser({ redirectTo: '/dashboard', redirectIfFound: true });
const [userDetails, setUserDetails] = useState({
email: '',
password: '',
});
const [error, setError] = useState({
email: '',
password: '',
});
function handleChange(event) {
setError({
email: '',
password: '',
});
setUserDetails({
...userDetails,
[event.target.name]: event.target.value,
});
}
async function handleSubmit(event) {
event.preventDefault();
const body = userDetails;
try {
const res = await fetch('/api/users/signin', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
if (res.status === 200) {
Router.push('/dashboard');
} else if (res.status === 400) {
res.json().then((errMessage) => {
setError(errMessage);
});
}
} catch (error) {
console.error(error);
}
}
return (
<div className='valign-wrapper row auth-form-container'>
<div className='row'>
<div className='col s8 offset-s2'>
<Link href='/'>
<a>{'< Back to home page'}</a>
</Link>
</div>
<div className='input-field col s8 offset-s2'>
<label htmlFor='email'>Email</label>
<input
type='email'
onChange={handleChange}
name='email'
value={userDetails.email}
/>
<p className='error-message'> {error.email} </p>
</div>
<div className='input-field col s8 offset-s2'>
<label htmlFor='password'>Password</label>
<input
type='password'
onChange={handleChange}
name='password'
value={userDetails.password}
/>
<p className='error-message'>{error.password}</p>
</div>
<div className='col s8 offset-s2'>
<button
className='btn waves-effect waves-light submit-button'
onClick={handleSubmit}
>
Login
</button>
</div>
<div className='col s8 offset-s2 mt-10'>
<Link href='/register'>
<a>Don't have an account yet? Create one here</a>
</Link>
</div>
</div>
</div>
);
}
export default SigninForm;
【问题讨论】: