nextjs - useState和useRef导致意外结果

fbcarpbf  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(104)

我是学习Nextjs的初学者,现在我正在做一个小项目,涉及登录和导航栏。我希望下面的代码能说明一切。一开始,我想通过从本地后端获取数据来获取用户令牌,然后将其存储在localStorage中,一切都正常。我得到了我需要的东西,并为组件创建了几个帮助器,以便从localStorage获取令牌。按照教程,我可以直接读取令牌并将其用于条件渲染,如下所示:

import { readToken, removeToken } from '@/lib/authenticate';
...
const token = readToken();
// readtoken will return something like 
{iat: 1690891359, userName: "test1", _id: "64c0320797629f3ad3a9acde"}
...
return (
    <Navbar ...
        {token ? 
                ....<>Logout</>....
            : ....<>Login</>
        }
    </Navbar>
)

字符串
但问题是,服务器没有localStorage,所以服务器将呈现Logout部分,但客户端将呈现Login部分。参考(来自物料):

<Navbar.Collapse id="basic-navbar-nav">
     <Nav className="me-auto">
         <Link href="/" passHref legacyBehavior >               
            <Nav.Link>Home</Nav.Link>
        </Link>
         {token && <Link href="/vehicles" passHref legacyBehavior><Nav.Link>Vehicles</Nav.Link></Link>}
 </Nav>
 <Nav className="ml-auto">
     {!token && <Link href="/login" passHref legacyBehavior><Nav.Link>Login</Nav.Link></Link>}
     {token && <Nav.Link onClick={logout}>Logout</Nav.Link>}
 </Nav>


在我找到解决方案之后,我将令牌移动到状态,而不是直接检索它。

const [ token, setToken ] = useState(null)
    useEffect(() => {
        const token = readToken();
        setToken(token)
    }, [])


唯一的问题是它不会触发渲染,在刷新整个页面(又名F5)后,我找到了所需的导航栏。而且,我把它改为useRef而不是useState,令人惊讶的是,它工作得很好,每次我登录和注销,导航栏都会相应地改变。

let token = useRef(null);

    useEffect(() => {
        token.current = readToken();
    })


我的问题是:
1.据我所知,重新渲染是由任何状态更改触发的,但我确实通过setState将状态从null更改为某个令牌,我不明白为什么它不重新渲染。
1.其次,我记得,useRef只会影响ref本身,与状态无关,我不明白为什么导航栏会相应地改变。如有任何帮助,我们将不胜感激。如果需要,我可以将所有代码粘贴在这里。
我试着记录所有的东西,但我没有关于这个问题的想法。我希望useEffect(又名componentDidmount)中的useState将获得令牌、状态更改和相应的Navbar显示。

tzxcd3kk

tzxcd3kk1#

你可以试试

const [ token, setToken ] = useState({ iat: null, userName: null, _id: null })
    useEffect(() => {
        const token = readToken();
        setToken({...token})
    }, [])

字符串
参考:Updating Objects in State

相关问题