【问题标题】:Dynamic React Redux Header component in large application大型应用程序中的动态 React Redux Header 组件
【发布时间】:2016-12-02 10:34:06
【问题描述】:

我正在构建一个在整个应用程序中使用的 Header 组件。我正在使用 React 和 Redux (obvz) 来保持 Header 的默认状态,例如在 header reducer 的默认 state 参数中:

state = { 
     showUserMenu: true,
     redirectUrl: '/'
}

这对于所有组件来说都是完美的,但对于某些路由/组件,我希望标题显示用户菜单。

所以当这些组件挂载时,我会向 HIDE_USER_MENU 发送一个操作。

问题在于,因为默认设置为true,所以userMenu最初会在那里,即使在componentWillMount中调用dispatch,也会有一瞬间出现userMenu。

所以没有默认值?但反过来也是如此,它默认不显示菜单,并且仅在操作处理完毕后才出现。

This is nice,但它并没有更进一步(以我的示例为例)并解释了如何根据路由或组件选择减速器。

我也尝试过使用 react-router-redux 基于 location.pathname 触发操作,但即使这样也不会发生得足够快,无法避免 FOUH(不需要的标题闪烁!:'()

我想知道是否存在用于动态加载初始状态的既定模式,该模式保证会出现在初始渲染中。

希望我的要求很清楚,非常感谢任何帮助!

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

    最简单的方法是让 Header 成为路由的子节点。这可以很容易地决定要传递哪些道具: * 您根本不需要存储标头状态 - 路由组件只需将适当的道具(例如 showUserMenu)传递给标头。

    但是,它有几个缺点: * 所有路由都必须处理 Header 的渲染(不是问题,有很多方法可以共享代码) * 重新路由时,Header 被卸载并安装一个新的(因为它的父级路由组件被卸载)。所以任何 DOM 和 React 状态都会丢失。

    可以通过对所有路由使用相同的组件类型来避免卸载(这可能会呈现标题),但传递它的 props 以配置适当的路由处理行为(例如子组件)。

    另一个(可能是错误的)选项是让您的 Header 状态监听 redux-react-router 的 LOCATION_CHANGE 操作,并基于此更改 showUserMenu 的值。文档似乎建议不要这样做,因为由于动态路由加载等原因,在实际呈现新路由之前可能存在一些异步性,但它可能适用于正常情况。

    【讨论】:

    • 感谢您的想法,汤姆!我知道我可以在每个组件中呈现标题,但这正是我试图摆脱的。在 50 多个具有不同配置的组件中呈现标题是痛苦的 un-DRY :(。另外,当我提到使用 react-redux-router 基于 location.pathname 触发动作时,我使用的是 history.listen 例如 LOCATION_CHANGE。不幸的是(如你提到的)具有相同的效果。我也尝试将标题包装在一个高阶组件中,同样的问题......
    • 如果所有组件的配置不同,那么就没有任何重复;)!不过说真的,包括如果您将所有内容都分解为 StandardScreen 之类的组件(例如,一条路线可能是 <StandardScreen includeMenu={true}><UserPage/></StandardScreen>),那么这就是路线的配置,而不是重复。也就是说,您几乎肯定需要在某些时候更新存储状态作为路由的一部分:如果您使用 history.listen 并让回调调度您自己的 routeChanged 操作,那么这是否为您提供了一个可行的钩子来更新您的存储状态之前渲染?
    • 抱歉离开了!我明白你的意思,但对我来说,这正是 Redux 的用途:处理整个应用程序的状态,这就是我试图用它做的所有事情。所以你知道,我更新状态的代码已经在 history.listen 回调中,例如:history.listen(location => dispatch(hideUserMenu())); 里面有一些有条件的东西来检查我在哪条路线上,但就是这样!
    • 我同意能够同步更新状态以响应许多大型应用程序中的路由绝对至关重要(我自己的应用程序广泛使用此工具从路由参数初始化存储状态,但我正在使用我自己的通量 + 路由库)。我很惊讶您的渲染出现闪烁,因为我原以为重新渲染会在没有任何“让步”返回浏览器的情况下发生。双重渲染意味着您的历史监听器被异步调用。值得在您的渲染方法中放置一个断点并检查 2 个调用的调用堆栈。
    • 再次感谢汤姆的帮助。我接受这一点,因为您的帮助和信息有助于解决一个非常模糊的问题!最终,只要它处于 SPA 模式,它现在就可以工作。在硬重载时加载会有延迟,但我现在对此很满意。
    猜你喜欢
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多