登錄完成且用戶導航到新頁面后導航欄未更新

我在導航欄中對幾個按鈕使用選擇性渲染。首先,我檢查accessToken是否在localStorage中找到,然后只呈現這些按鈕,但當我登錄并將用戶導航到新頁面時,導航欄不會更新以顯示這些按鈕。

import React,{forwardRef, useEffect, useState} from "react";
import { logoutUser } from "@/features/userSlice";
import { NavLink, useNavigate } from "react-router-dom";
import { LogOut, Settings, User, Users, Plus } from "lucide-react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

//********************************* getting token from localStorage********************
const token = localStorage.getItem("token");
************************************************************************************

const AvatarDropdown = () => {
  return (
    <>
      <DropdownMenu modal={true} onOpenChang={() => setIsOpen(!isOpen)}>
        <DropdownMenuTrigger className="outline-none">
          <Avatar>
            <AvatarImage src="https://github.com/shadcn.png" />
            <AvatarFallback>CN</AvatarFallback>
          </Avatar>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end" className="text-center">
          <DropdownMenuItem
            onClick={() => handleLogout()}
            className="px-5 py-1 "
          >
            <LogOut className="mr-3" />
            Logout
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
    </>
  );
};

const Header = forwardRef((props, ref) => {
  const navigate = useNavigate();

******************tried this re-rendering method*** doesn't work******
  const [re, setRe] = useState(true);
  const user = useSelector(getUserInfo);

  useEffect(()=>{
    setRe(!re)
  },[user.accessToken])
***********************************************************************
  return (
    <main
      className="w-full bg-orange-400 h-fit md:px-[100px] px-[40px] py-2 flex items-center justify-between box-border fixed top-0 z-10"
      ref={ref}
    >
      <div className=" md:flex hidden w-[70%] items-center gap-5">
        <div className="w-full flex flex-1 items-center justify-end gap-5">
          {!token && (
            <NavLink
              className={({ isActive }) =>
                `p-2 font-semibold rounded-md bg-teal-400
                 text-white hover:bg-teal-500 active:bg-teal-700
                 ${isActive ? "border-[2px]" : ""}`
              }
              to="/register-login"
            >
              Register / Login
            </NavLink>
          )}
          <NavLink
            className={({ isActive }) =>
              `p-2 font-semibold rounded-md bg-indigo-400
               text-white hover:bg-indigo-500 active:bg-indigo-700
               ${isActive ? "border-[2px]" : ""}`
            }
            to="/"
          >
            All Memories
          </NavLink>
          {token && (
            <NavLink
              className={({ isActive }) =>
                `border p-2 font-semibold rounded-md text-black
             hover:bg-orange-500 active:bg-orange-700
             ${isActive ? "border-[2px]" : ""}`
              }
              to="/my-memories"
            >
              My Memories
            </NavLink>
          )}
        </div>
        <div>{token && <AvatarDropdown />}</div>
      </div>
      <div className="md:hidden flex flex-row-reverse items-center space-x-5">
        {token && (
          <div className="ml-3">
            <AvatarDropdown />
          </div>
        )}
        <DropdownMenu modal={true} onOpenChang={() => setIsOpen(!isOpen)}>
          <DropdownMenuTrigger className="outline-none">
            <i className="fa-solid fa-bars text-2xl p-2 text-black"></i>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end" className="text-center">
            <DropdownMenuItem
              onClick={() => navigate("/register-login")}
              className="px-5 py-1 "
              disabled={token}
            >
              <Plus className="mr-3" />
              Register or Login
            </DropdownMenuItem>
            <DropdownMenuSeparator />
            <DropdownMenuItem
              onClick={() => navigate("/")}
              className="px-5 py-1 "
            >
              <Users className="mr-3" />
              All Memories
            </DropdownMenuItem>
            <DropdownMenuSeparator />
            <DropdownMenuItem
              onClick={() => navigate("/my-memories")}
              className="px-5 py-1"
              disabled={!token}
            >
              <User className="mr-3" />
              My Memories
            </DropdownMenuItem>
            <DropdownMenuSeparator />
          </DropdownMenuContent>
        </DropdownMenu>
      </div>
    </main>
  );
});

export default Header;

我登錄的表單組件,如果登錄成功,則將用戶導航到新頁面。

import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { registerUser, loginUser } from "@/features/userSlice";
import { useToasts } from "@/utils/useToastHook";
import { unwrapResult } from "@reduxjs/toolkit";
import { useNavigate } from "react-router-dom";
import { useDispatch } from "react-redux";
import { Footer } from "../exporter";
import { useState } from "react";

const RegisterAndLoginForm = ({
  name,
  loginForm,
  setLoginForm,
}) => {
  const navigate = useNavigate();
  const dispatch = useDispatch();
  const showToast = useToasts();

  const handleLoginInput = (e) => {
    setLoginForm({ ...loginForm, [e.target.name]: e.target.value });
  };

****************************** Handling login and then navigating to new page**********************
  const handleSubmit = async(e) => {
    e.preventDefault();
      try {
        const actionResult = await dispatch(loginUser(loginForm)).unwrap();
        const result = unwrapResult(actionResult);
        showToast("bg-green-700", "Success", "Login successfully.");
        localStorage.setItem("token", actionResult.data.accessToken)
        navigate("/my-memories");
        
      } catch (error) {
        showToast("bg-red-700", "Error", error.errorMessage);
      }
  };
****************************************************************************************************

  return (
    <main className="bg-transparent_bg w-full flex flex-col items-center box-border rounded-md">
      <form
        className="w-full text-center space-y-3 p-2 box-border"
        onSubmit={handleSubmit}
      >
        <h3 className="font-extrabold text-foreground text-xl bg-slate-500 py-2 rounded-md tracking-widest">
          {name}
        </h3>
        <label className="form__label" htmlFor="username">Username: </label>
        <input
          id="username"
          className="input"
          type="text"
          placeholder="username"
          name="username"
          value={loginForm.username}
          onChange={handleLoginInput}
          required
          pattern="^[^\d]*$"
          title="name can not contains numbers"
        />
        <label className="form__label" htmlFor="password">Password: </label>
        <input
          id="password"
          className="input"
          type="password"
          placeholder="password"
          name="password"
          value={loginForm.password}
          onChange={handleLoginInput}
          required
        />

        <div className="flex justify-center gap-5 py-1 box-border">
          <button
            type="submit"
            className="bg-blue-400 w-24 px-3 py-2 rounded-md hover:bg-blue-500 active:bg-blue-600 text-white tracking-widest"
          >
            {name}
          </button>
        </div>
      </form>
    </main>
  );
};

const LoginAndRegister = () => {
  const [loginForm, setLoginForm] = useState({username: "", password: ""});

  return (
    <>
      <div className="w-[80%] grid m-auto grid-cols-12 gap-1">
        <div className="md:col-span-6 col-span-12 md:text-center md:m-0 m-auto">
          <Tabs defaultValue="register" className="md:w-auto p-1">
            <TabsList className="w-full">
              <TabsTrigger value="register" className="w-[50%]">
                Register
              </TabsTrigger>
              <TabsTrigger value="login" className="w-[50%]">
                Login
              </TabsTrigger>
            </TabsList>
            <TabsContent value="register" className="border rounded-md">
              <RegisterAndLoginForm
                name={"Register"}
              />
            </TabsContent>
            <TabsContent value="login" className="border rounded-md">
              <RegisterAndLoginForm
                name={"Login"}
                loginForm={loginForm}
                setLoginForm={setLoginForm}
              />
            </TabsContent>
          </Tabs>
        </div>
        <div className=" max-h-[680px] md:col-span-6 overflow-hidden rounded-lg relative md:block hidden">
          <img src="login-hero.jpg" alt="login-hero" className="object-cover rounded-lg" />
        </div>
      </div>
      <Footer />
    </>
  );
};

export default LoginAndRegister;

我使用的是react-router-dom v6,布局組件如下所示:

const Layout = () => {
  const [headerHeight, setHeaderHeight] = useState(0);
  const headerRef = useRef(null);

  useEffect(() => {
    if (headerRef) {
      const height = headerRef.current.offsetHeight;
      if (height) {
        setHeaderHeight(height);
      }
    }
  }, [headerRef.current]);

  return (
    <>
      <Header ref={headerRef} />
      <Suspense fallback={<div>Loading...</div>}>
        <div className="max-w-[1484px] flex flex-col items-center m-auto">
          <MemoriesHeader />
          <Outlet context={[headerHeight]} />
        </div>
      </Suspense>
    </>
  );
};

export default Layout;

我嘗試了re-rendering使用狀態的頭組件,并根據條件將其設置為false和true,但這也不起作用。

? 最佳回答:

你不需要把它用起來嗎?

something like

 const LOCAL_STORAGE_KEY_TOKEN = 'token';

  const [token, setToken] = useState(() => {
    const storedToken = localStorage.getItem(LOCAL_STORAGE_KEY_TOKEN);
    return storedToken !== null ? JSON.parse(storedToken) : null;
  });

  useEffect(() => {
    localStorage.setItem(LOCAL_STORAGE_KEY_TOKEN, JSON.stringify(token));
  }, [token]);
主站蜘蛛池模板: 亚洲国产韩国一区二区| 亚洲一区精彩视频| 麻豆文化传媒精品一区二区| 91福利国产在线观看一区二区 | 精品乱人伦一区二区三区| 亚洲AV无码一区二区乱孑伦AS| 奇米精品视频一区二区三区| 一区二区三区免费高清视频| 亚洲AV无码片一区二区三区| 国产日韩AV免费无码一区二区三区 | 成人免费av一区二区三区| 国产一区二区三区露脸| 3D动漫精品啪啪一区二区下载| 国产视频福利一区| 一区二区高清视频在线观看| 91福利视频一区| 狠狠做深爱婷婷综合一区| 竹菊影视欧美日韩一区二区三区四区五区 | av无码精品一区二区三区四区| 亚洲色婷婷一区二区三区| 日韩精品一区二区三区中文字幕| 无码日韩精品一区二区免费暖暖 | 无码人妻精品一区二区三区久久| 日韩在线一区视频| 日韩视频一区二区在线观看| 亚洲av无码天堂一区二区三区 | 亚洲AV成人一区二区三区观看| 精品人妻中文av一区二区三区| 国产一区二区视频在线播放| 国产大秀视频一区二区三区| 久久精品国内一区二区三区| 国产经典一区二区三区蜜芽| 日韩人妻一区二区三区免费 | 国产精品一区二区久久乐下载| 日韩精品一区二区三区中文精品 | 99精品一区二区三区| 日本一区二区不卡视频| 精品一区二区三区波多野结衣| 国偷自产av一区二区三区| 日本不卡免费新一区二区三区| 亚洲综合色自拍一区|