从 login.jsx 提交登录后,用户将使用 导航到 index.jsx router.push('/')。这两个文件(更具体地说是页面)都位于 /pages 目录下的根目录中。所有页面都会自动使用 Layout.jsx 作为布局。布局文件有 Nav.jsx 组件。在 Nav.jsx 内部,注册了一个 useEffect 挂钩,但问题是:在router.push('/')我在挂钩内尝试 console.log() 但没有运气后,它永远不会触发。router.push('/')但是,它会在重新加载页面或替换为时执行挂钩window.location.replace('/')。这是我的代码:
登录.jsx:
... (previous code)
axios.post(`/auth/login`, loginForm).then((res) => {
const {data, token} = res.data;
localStorage.setItem('auth_token', token);
localStorage.setItem('user', JSON.stringify(data));
router.push('/');
... (next code)
Run Code Online (Sandbox Code Playgroud)
布局.jsx:
import Head from 'next/head'
import Nav from "./Nav";
export default function Layout({children}) {
return (
<>
<Head>
<title>Super site!</title>
<link rel="icon" href={"/favicon.ico"}/>
</Head>
<header>
<Nav/>
</header>
<main>{children}</main>
<footer>
<h1>Super site footer</h1>
</footer>
</>
)
}
Run Code Online (Sandbox Code Playgroud)
导航.jsx:
export default function Nav() {
const router = useRouter();
const [user, setUser] = useState(null);
const logout = (e) => {
e.preventDefault();
axios.post(`/auth/logout`).then(() => {
localStorage.removeItem('auth_token');
localStorage.removeItem('user');
router.replace('/');
router.reload();
}).catch((err) => {
if (err.response) {
toast.error(err.response.data.message, toasterOptions('error'));
} else {
toast.error(getServerErrorMessage(), toasterOptions('error'));
}
});
}
useEffect(() => {
console.log('hi');
const storedUser = JSON.parse(localStorage.getItem('user'));
if (storedUser) setUser(storedUser);
}, []);
return (
<>
<nav className={'sm-nav'}>
<input type="checkbox" name="menu-btn" id="menu-btn" className={'hidden menu-btn'}/>
<ul className={'header-ul'}>
<li>
<Link href="/">
<a className={'logo'}>Devlanceer</a>
</Link>
</li>
<li>
<label htmlFor="menu-btn" className={'menu-icon bars'}>
<FontAwesomeIcon icon={"bars"} className={'md:hidden cursor-pointer'} size={'lg'}/>
</label>
<label htmlFor="menu-btn" className={'menu-icon times hidden'}>
<FontAwesomeIcon icon={"times"} className={'cursor-pointer'} size={'lg'}/>
</label>
</li>
</ul>
<ul className={'dropmenu'}>
{
user && (
<li>
<a onClick={logout} className={'pointered'}>Logout</a>
</li>
)
}
{
!user && (
<>
<li>
<Link href={'/login'}>
<a>Login</a>
</Link>
</li>
<li>
<Link href={'/register'}>
<a>Create account</a>
</Link>
</li>
</>
)
}
</ul>
<Toaster/>
</nav>
<nav className={'md-nav'}>
<ul>
<li>
<Link href="/">
<a className={'logo'}>Super App</a>
</Link>
</li>
</ul>
<ul className={'block md:flex'}>
{
user && (
<li>
<a onClick={logout} className={'pointered'}>Logout</a>
</li>
)
}
{
!user && (
<>
<li>
<Link href={'/login'}>
<a className={'btn rounded-full'}>Login</a>
</Link>
</li>
<li>
<Link href={'/register'}>
<a className={'btn rounded-full btn-primary'}>Create account</a>
</Link>
</li>
</>
)
}
</ul>
</nav>
</>
)
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?我希望在 Nav.jsx 组件上执行 useEffect() 挂钩。
如果将您的位置写入钩子中会发生什么?来自文档:
如果您只想运行效果并仅清理一次(在安装和卸载时),则可以传递一个空数组 ([]) 作为第二个参数。
useEffect(() => {
console.log('hi');
const storedUser = JSON.parse(localStorage.getItem('user'));
if (storedUser) setUser(storedUser);
},[router.pathname]); // re-run the effect if your location changes, router.pathname or wherever your router stores the current location
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3519 次 |
| 最近记录: |