如果 Next.js 中不存在 sessionStorage 变量,如何有条件地渲染 React 组件?

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

我有一个

<Authenticated>
组件,用于渲染所有经过身份验证的路由。我想阻止渲染页面,直到检查了存储在
sessionStorage
中的令牌。

'use client';

export const Authenticated = ({ children }) => {
  const token = typeof window !== 'undefined' ? sessionStorage.getItem('token') : null;

  if (!token) {
    return <></>;
  }

  return (
    <main>{children}</main>
  );
}

这有效,但我收到此水合作用错误:

Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.

有更好的方法吗?

reactjs next.js session-storage
1个回答
0
投票

根据 Next.js 文档 水合错误可能由以下原因引起:

在渲染逻辑中使用

typeof window !== 'undefined'
之类的检查

这就是你在这里所做的:

const token = typeof window !== 'undefined' ? sessionStorage.getItem('token') : null;

而是将会话处理逻辑包装到

useEffect
钩子中。这将确保您仅在页面完全加载并且
token
可用时检查
window

'use client';

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

export const Authenticated = ({ children }) => {
  const [token, setToken] = useState('');

  useEffect(() => {
     setToken(window.sessionStorage.getItem('token'))
  }, [])

  return (
    {token ? <main>children</main> : null}
  );
}

此方法需要注意的一些事项:

  • 我们使用state来存储令牌。这是因为在

    token
    运行之前
    useEffect
    将为假。这让我们可以在检索到令牌后更新状态并重新渲染 UI

  • 基于最后一点,我们使用三元运算符来确定是否渲染某些内容。以前的方法可能不起作用的原因(即使您修复了水合错误)是因为这个逻辑错误,您的代码说:

    • 如果我们有一个令牌(可能在页面加载之前)返回一个片段
    • 否则返回
      {children}

    问题是第一个条件永远是

    true
    ,然后可能是假的。不过,目前你只能在满足真实条件之前返回。但是当在单个
    return
    上使用 if/else 逻辑时,你可以解决这个问题

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