Vanilla React 导航栏在更新本地存储时无反应

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

我有这个反应应用程序结构。一些组件根据本地存储的内容被隐藏。

import React from "react";
import { BrowserRouter as Router } from "react-router-dom";
import AppRoutes from "./Routes";
import NavBar from "./components/NavBar";

const App = () => {
  return (
    <Router>
      <NavBar />
      <AppRoutes />
    </Router>
  );
};

export default App;

除了导航栏之外,我的所有其他反应组件都是响应式的。我做错了什么?这是我的导航栏代码:

import { useEffect, useState } from "react";
function NavBar() {
  const [role, setRole] = useState("");
  
  useEffect(() => {
    setRole(localStorage.getItem("tempUserRole"));
  }, []);
    return (
        <header className="bg-white">
            <nav className="" aria-label="Global">
                {/* Links (Center-aligned) */}
                <div className="">
                    {role==='a' && <a href="/events" className="">a</a>}
                    {role==='b' && <a href="/events" className="">EveBnts</a>}
                </div>

            </nav>
        </header>
    );
}

export default NavBar;

问题是,我必须刷新页面才能看到更改生效。我该如何解决这个问题?

javascript reactjs react-hooks local-storage jsx
2个回答
0
投票

您的

useEffect
依赖项数组为空,因此挂钩只会在导航栏首次呈现时运行(当然,或者在刷新之后)。

最简单的解决方案是将

localStorage.getItem("tempUserRole")
添加到依赖项数组中。它会起作用,但会抛出警告,因为 React 不希望在数组中使用复杂的函数,因为与变量不同,跟踪更改的成本非常昂贵。

更复杂的解决方案是在窗口上创建一个事件侦听器并以这种方式更新您的状态。您可以将该逻辑捆绑在自定义挂钩中。我将在此处包含 Maxim 在另一个问题中的回答

您可以使用自定义挂钩

const profile = useProfileData();
import { useEffect, useState } from "react";

function getProfileData() {
  return JSON.parse(localStorage.getItem('profile'));
}

export default function useProfileData() {
  const [profile, setProfile] = useState(getProfileData());

  useEffect(() => {
    function handleChangeStorage() {
      setProfile(getProfileData());
    }

    window.addEventListener('storage', handleChangeStorage);
    return () => window.removeEventListener('storage', handleChangeStorage);
  }, []);

  return profile;
}

如果您不明白为什么没有捕获它,请参阅问题存储事件未触发

总而言之,它捕获不同页面上的事件


0
投票

您首先可以看看本地存储中是否存储有任何内容吗?

import { useEffect, useState } from "react";

function NavBar() {
const [role, setRole] = useState(null);

useEffect(() => {
const storedRole = localStorage.getItem("tempUserRole");
if (storedRole) {
  setRole(storedRole);
} else {
  setRole("");
}
}, []);

return (
<header className="bg-white">
  <nav aria-label="Global">
    {/* Links (Center-aligned) */}
    <div>
      {role === 'a' && <a href="/events" className="">a</a>}
      {role === 'b' && <a href="/events" className="">EveBnts</a>}
    </div>
  </nav>
 </header>
 );
 }

export default NavBar;
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.