Redux 订阅似乎不起作用,因此我的页眉和页脚未显示

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

我正在开发一个使用 Redux 进行状态管理的 React 应用程序。在我的布局组件中,我尝试仅在有用户时才显示页眉和页脚,但我面临一个问题,即它们都没有显示。 我知道这是因为用户仍然为空,但我可以找到解决方法,也尝试过订阅,但没有任何变化。

这是我的布局组件的简化版本:


 import Routing from "../Routing/Routing";
 import "./Layout.css";
 import { NavLink, useLocation } from "react-router-dom";
 import { authStore } from "../../redux/redux";
 import { useEffect, useState } from "react";
 import UserModel from "../../../models/UserModel";


  function Layout(): JSX.Element {

    const { pathname } = useLocation()
    const hideHeaderPaths: string[] = ['/login']

    const [user, setUser] = useState<UserModel>();
    console.log(user)
    useEffect(() => {


        setUser(authStore.getState().user);

        const unsubscribe = authStore.subscribe(() => {
            const updatedUser = authStore.getState().user
            setUser(updatedUser);
            alert("Change")

        });
        
        setUser(authStore.getState().user);

        return () => unsubscribe();

    }, []);


    return (
        <div className="Layout" style={{ display: hideHeaderPaths.includes(pathname) ? "block" : "grid" }}>


            {!hideHeaderPaths.includes(pathname) && user  && <header><p>{`${user.firstName}  ${user.lastName}`}  |<NavLink to={"/logout"}>Logout</NavLink> </p></header>}

            <main>
                {/* <Main /> */}
                <Routing />
            </main>
            {!hideHeaderPaths.includes(pathname) && <footer>this is the footer</footer>}






        </div>
    );
}

  export default Layout;`


有人可以帮我理解为什么用户信息在初始渲染上没有正确显示吗?

我也尝试过在页眉和页脚中删除用户的条件渲染,但我仍然面临同样的问题。用户的名字和姓氏在初始渲染中显示为未定义。

reactjs redux subscribe
2个回答
1
投票

要记住的重要一点:

useEffect
是异步的,并且总是在初始渲染之后发生。

在您的情况下,React 首次渲染您的组件并使用您在

useState
中提供的初始状态。您什么也没提供,这基本上是
undefined
的别名。这基本上就是您看到
undefined
的原因。然后一段时间后,调用
useEffect
并用正确的数据更新状态。

我建议进行以下更改:

const [user, setUser] = useState<UserModel>(authStore.getState().user);

这样,一旦组件安装完毕,您就可以到达商店,并且用户将在初始渲染时定义。


0
投票

这不是 React 组件订阅 Redux 存储的方式。使用

useSelector
挂钩并选择适当的状态。 不要使用
store.subscribe
和重复的本地状态。

示例:

import { useEffect, useState } from "react";
import { NavLink, useLocation } from "react-router-dom";
import { useSelector } from "react-redux"; // <-- import hook
import Routing from "../Routing/Routing";
import "./Layout.css";
import { authStore } from "../../redux/redux";
import UserModel from "../../../models/UserModel";

function Layout(): JSX.Element {
  const { pathname } = useLocation()
  const hideHeaderPaths: string[] = ['/login']

  const user = useSelector(state => state.user); // <-- subscribe to user state

  return (
    <div
      className="Layout"
      style={{ display: hideHeaderPaths.includes(pathname) ? "block" : "grid" }}
    >
      {!hideHeaderPaths.includes(pathname) && user && (
        <header>
          <p>
            {user.firstName} {user.lastName} |
            <NavLink to="/logout">Logout</NavLink>
          </p>
        </header>
      )}
      <main>
        {/* <Main /> */}
        <Routing />
      </main>
      {!hideHeaderPaths.includes(pathname) && (
        <footer>this is the footer</footer>
      )}
    </div>
  );
}

export default Layout;
© www.soinside.com 2019 - 2024. All rights reserved.