簡體   English   中英

僅在刷新頁面后,按注銷按鈕后導航欄不更新

[英]Navbar not updating upon pressing the logout button, only after refreshing the page

我正在嘗試使用 useContext 作為全局狀態管理器。 用戶注銷確實有效,但導航欄上的信息在我點擊刷新之前不會反映此更改。 為什么它不特別更新導航欄超出了我的理解,因為按下注銷按鈕正確地將用戶路由回登錄頁面,但在用戶刷新之前不會更新導航欄。 基本上,需要的是導航欄的用戶信息在點擊注銷后立即更新,而不是在用戶刷新或轉到另一個頁面時更新。

下面是我的相關代碼。

const Logout = () => {
    const navigate = useNavigate();
    const { user } = useContext(ContextHolder);

    useEffect(() => {
        const onLogoutSuccess = () => {
            _logger('Logged out successfully.');
            toast('You have been logged out');
            navigate('/login');
        };
        const onLogoutError = (message) => {
            _logger('Logout failed:', user.email + ' ' + message);
            navigate('/');
        };

        userService.logout().then(onLogoutSuccess).catch(onLogoutError);
    }, []);

    return <>Logging out ...</>;
};

export default Logout;
const defaultUser = {
    id: 0,
    roles: [],
    email: '',
    isLoggedIn: false,
};

const ContextHolder = React.createContext({
    user: defaultUser,
});

export default ContextHolder;
const NavBar = () => {
    const { user } = useContext(ContextHolder);


    return (
        <Navbar collapseOnSelect expand="lg" className="py-lg-3 navbar" variant="light">
            <div className="d-flex justify-content-center mx-4">
                <Navbar.Brand href="/" className="me-lg-5">
                    <img src={logo} alt="" className="logo-dark" height="50px" />
                </Navbar.Brand>

                <Navbar.Toggle aria-controls="responsive-navbar-nav">
                    <i className="mdi mdi-menu"></i>
                </Navbar.Toggle>
                <Navbar.Collapse id="responsive-navbar-nav">
                    <Nav as="ul" className="me-auto align-items-center">
                        <Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
                            <AiOutlineLink /> <Nav.Link href="/listings">View Listings</Nav.Link>
                        </Nav.Item>
                        <Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
                            <MdOutlineQuestionAnswer /> <Nav.Link href="/faq">FAQs</Nav.Link>
                        </Nav.Item>
                        <Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
                            <BsFillPeopleFill /> <Nav.Link href="/blogs">Blogs</Nav.Link>
                        </Nav.Item>
                        <Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
                            <AiFillPhone /> <Nav.Link href="/contactus">Contact</Nav.Link>
                        </Nav.Item>
                        <Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
                            <RiProfileLine /> <Nav.Link href="/profile">Profile</Nav.Link>
                        </Nav.Item>
                        <Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
                            <BiMap /> <Nav.Link href="/location">Location</Nav.Link>
                        </Nav.Item>
                        <Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
                            <GoVerified /> <Nav.Link href="/location/verification">Location Verification</Nav.Link>
                        </Nav.Item>
                        <Nav.Item className="mx-lg-1 btn btn-outline-light text-nowrap border-0 text-center">
                            <TbInfoCircle /> <Nav.Link href="/AboutUs">About Us</Nav.Link>
                        </Nav.Item>
                        <Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
                            <FaCogs /> <Nav.Link href="/externallinks">External Links</Nav.Link>
                        </Nav.Item>
                        <Nav.Item className="mx-lg-1 btn btn-outline-light border-0">
                            <GoChecklist /> <Nav.Link href="/venues">Venues</Nav.Link>
                        </Nav.Item>
                    </Nav>

                    <Nav className="ms-auto align-items-center">
                        {user.isLoggedIn ? (
                            <React.Fragment>
                                <Nav.Item className="me-0 text-center">
                                    <span className="text-dark fw-bold"> Welcome back, {user.email}!</span>
                                </Nav.Item>
                                <Nav.Item>
                                    <Link
                                        to="/logout"
                                        className="mx-3 btn btn-sm btn-outline-dark d-none d-lg-inline-flex mt-1"
                                        style={{ width: '80px' }}>
                                        Log Out
                                    </Link>
                                </Nav.Item>
                            </React.Fragment>
                        ) : (
                            <Nav.Item className="me-0">
                                <Nav.Link href="/login" target="_self" className="d-lg-none">
                                    Log In
                                </Nav.Link>
                                <Link
                                    to="/login"
                                    target="_self"
                                    className="mx-3 btn btn-sm btn-outline-dark d-none d-lg-inline-flex">
                                    Log In
                                </Link>
                            </Nav.Item>
                        )}
                    </Nav>
                </Navbar.Collapse>
            </div>
        </Navbar>
    );
};

NavBar.propTypes = {
    currentUser: PropTypes.shape({
        id: PropTypes.number,
        roles: PropTypes.arrayOf(PropTypes.string),
        email: PropTypes.string,
        isLoggedIn: PropTypes.bool,
    }),
};

export default NavBar;

所有相關組件都無法知道變量“user”在任何給定時刻發生了變化,因為“user”不是一個狀態。 現在,react 通過“靜態”渲染您的組件,並且據其所知,“永不改變的變量”解釋了為什么視圖只有在刷新后才能正確渲染。 你應該像這樣創建一個狀態

const [user, setUser] = useState(defaultUser);

此外,您應該使用上下文提供程序包裝您的代碼,並在“value”屬性中添加“用戶”狀態,同時傳遞“setUser”函​​數,以便您可以在任何給定時刻從應用程序設置用戶。 在你的情況下:

<ContextHolder.Provider value={{ user, setUser }}>
    ...
</ContextHolder.Provider>

總而言之,您的代碼應如下所示:

const defaultUser = { ... };

function App () {
    const [user, setUser] = useState(defaultUser);

    return (
        <ContextHolder.Provider value={{ user, setUser }}>
            <NavBar />
            <Logout />
            ...etc..
        </ContextHolder.Provider>
    )
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM