ReactJS:导航到另一个组件后无法正确检索 localStorageItem

ReactJS: Unable to retrieve properly localStorageItem after navigate to another component

我有这种情况,在用户登录并假设成功后,用户详细信息/用户令牌存储到 localStorage 并将自动导航到仪表板页面,仪表板页面有一些 api 调用和存储在 localStorage 中的那些 api 调用 required/needs token,我的问题是它无法在 localStorage 中检索这些值,但是当我使用控制台从 localStorage 检查时,key/value 在那里,我注意到,我需要刷新页面才能毫无问题地检索这些详细信息。我怎样才能解决这个问题?导航到另一个组件后能够获得 localStorage 值?

这是我的 index.tsx

代码
 ReactDOM.render(
  <AuthContextProvider>
    <App />
  </AuthContextProvider>,
  document.getElementById("root")
);

AuthContext 代码:

    const AuthContext = React.createContext({
  user: "",
  isLoggedIn: false,
  login: (userdata: any, expirationTime: string) => {},
  logout: () => {},
});

export const AuthContextProvider = (props: any) => {
  const initialUser = localStorage.getItem("user") || "";
  const [userData, setUserData] = useState(initialUser);
  const userIsLoggedIn = !!userData;

  const logoutHandler = () => {
    setUserData("");
    localStorage.removeItem("user");
  };

  const loginHandler = async (
    user: any,
    expirationTime: string
  ) => {
    localStorage.setItem("user", JSON.stringify(user));
    setUserData(user);
  };

  const contextValue = {
    user: userData,
    isLoggedIn: userIsLoggedIn,
    login: loginHandler,
    logout: logoutHandler,
  };

  return (
    <AuthContext.Provider value={contextValue}>
      {props.children}
    </AuthContext.Provider>
  );
};

export default AuthContext;

App.tsx代码

 function App() {
    const authCtx = useContext(AuthContext);
    return (
      <BrowserRouter>
        <Routes>
          {!authCtx.isLoggedIn && (
            <Route element={<LoginLayout />}>
              <Route index element={<SignInForm />} />
              {/*Other links here */}
            </Route>
          )}
          {authCtx.isLoggedIn && (
            <Route element={<AdminLayout />}>
              <Route path="dashboard" element={<DashboardScreen />} />
                {/*Other links here */}
            </Route>
          )}
          <Route path="*" element={<PageNotFound />} />
        </Routes>
      </BrowserRouter>
    );
  }

登录码:

    try {
    await AuthService.login(email, password).then(
      (res) => {
        authCtx.login(res, "0");
        navigate("../dashboard", { replace: true });
      },
      (error) => {
      }
    );
  } catch (err) {
    console.log(err);
  }

仪表板代码:

    const loadCountOnlineUsers = useCallback(async () => {
    try {
      await DashboardService.loadCountOnlineUsers().then(
        (res) => {
          setCntOnlineUsers(res.count);
          setflagOnlineUsers(false);
        },
        (error) => {
          setflagOnlineUsers(false);
        }
      );
    } catch (err) {
      console.log(err);
      setflagOnlineUsers(false);
    }
  }, [setCntOnlineUsers, setflagOnlineUsers]);

  useEffect(() => {
    loadCountOnlineUsers();
  }, [loadCountOnlineUsers]);

仪表板服务代码:

  const config = {
    headers: {
      "Content-Type": "application/json",
      Authorization: AuthHeader(),
    },
    params: {},
  };
  const loadCountOnlineUsers = () => {
    config["params"] = {};
    return axios
      .get(API_URL + "api/v1/dashboard-related/online-users", config)
      .then((response) => {
        return response.data;
      });
  };
  
const DashboardService = {
    loadCountOnlineUsers,
  };
  
  export default DashboardService;

Auth-header代码:

 export default function AuthHeader() {
    const user = JSON.parse(localStorage.getItem("user") || "{}");
    if (user && user.token) {
      return "Bearer " + user.token;
    } else {
      return "";
    }
  }

问题是 AuthHeader() 中对 localStorage 的检查没有反应性地更新。解决方法是重写 AuthHeader 以接受这样的用户数据:

export default function AuthHeader(user) {
  const user = JSON.parse(user || "{}");
  if (user && user.token) {
    return "Bearer " + user.token;
  } else {
    return "";
  }
}

然后继续将数据管道传输到调用 AuthHeader() 的区域,可能是这样的:

const config = (user) => ({
    headers: {
      "Content-Type": "application/json",
      Authorization: AuthHeader(),
    },
    params: {},
  });
  const loadCountOnlineUsers = (user) => {
    config["params"] = {};
    return axios
      .get(API_URL + "api/v1/dashboard-related/online-users", config(user))
      .then((response) => {
        return response.data;
      });
  };
  
const DashboardService = {
    loadCountOnlineUsers,
  };

最后,在连接到上下文的同时,使用仪表板中的效果对其进行反应式更新:

const authCtx = useContext(AuthContext);
const user = authCtx.user;

const loadCountOnlineUsers = (user) => {
 return useCallback(async () => {
    try {
      await DashboardService.loadCountOnlineUsers(user).then(
        (res) => {
          setCntOnlineUsers(res.count);
          setflagOnlineUsers(false);
        },
        (error) => {
          setflagOnlineUsers(false);
        }
      );
    } catch (err) {
      console.log(err);
      setflagOnlineUsers(false);
    }
  }, [setCntOnlineUsers, setflagOnlineUsers]);
}

useEffect(() => {
  loadCountOnlineUsers(user);
}, [loadCountOnlineUsers, user]);