【问题标题】:React routes not automatically updating when nested under 'smart' Redux container components嵌套在“智能”Redux 容器组件下时,React 路由不会自动更新
【发布时间】:2017-04-27 14:16:00
【问题描述】:

我正在尝试使用 React、React-router 和 Redux 创建一个 Electron 应用程序。我发现当我将开关/路由逻辑嵌套在纯粹的表示组件(Page)下时,我的路由逻辑工作得非常好,但是如果嵌套,我不得不刷新页面以查看导航更改在“智能”容器组件下。

在我的 React 组件层次结构的顶部附近(HashRouter 正下方)我有一个 Page:

export default function Page (props) {
  return (
      <div className={`${styles.page}`}>
        <SideBar/>
        <DetailPane>{props.children}</DetailPane>
      </div>
  );
}

这里,DetailPane 和 SideBar 都是包装在同名表示组件周围的容器组件。

在启动时(以及在热重载期间),我使用这个函数创建我的 React 层次结构:

export default () => (
    <Router>
      <Page>
        <Switch>
          <Route exact path='/txDefinitions/:definitionName/:fieldName' component={FieldPage}/>
          <Route exact path='/txDefinitions/:definitionName?' component={DefinitionPage}/>
          <Route exact path='/rxDefinitions/:definitionName?' component={DefinitionPage}/>
          <Route exact path='/'/>
          <Route component={Route404}/>
        </Switch>
      </Page>
    </Router>

这意味着&lt;Switch&gt;...&lt;/Switch&gt; 嵌套在&lt;DetailPane&gt; 之下。

如果我尝试在我的应用中导航(单击侧栏中的链接),在我强制重新加载 Electron 应用之前,我实际上不会看到详细信息窗格呈现新组件。

但是,如果我从 Page 中省略 DetailPane,我发现路由会按预期工作:

export default function Page (props) {
  return (
      <div className={`${styles.page}`}>
        <SideBar/>
        {props.children}
      </div>
  );
}

这是我的 React 层次结构没有 DetailPane(工作正常):

这是我的 React 层次结构 DetailPane(不能正常工作):

(很抱歉使用图片,但我不确定是否有办法从 React devtools 复制到剪贴板 - 如果在新标签页中打开会显得更大)。


在我写这个问题的时候,我意识到这对我来说不是一个大问题,因为早期的重构已经使DetailPane 的“智能”版本显然已经过时了。使用 DetailPane 的纯演示版本 而是解决了这个问题:

import * as React from 'react';
//import {DetailPane} from '../../containers'; // Smart/Redux
import {DetailPane} from '../../components'; // Dumb/presentational
import {SideBar} from '../../containers/';
const styles = require('./Page.scss');

export default function Page (props) {
  return (
      <div className={`${styles.page}`}>
        <SideBar/>
        <DetailPane>{props.children}</DetailPane>
      </div>
  );
}

但是,我仍然很好奇为什么这不适用于容器组件版本。供参考,这是DetailPane的容器组件版本:

import {connect} from 'react-redux';
import {DetailPane} from '../../components';

// TODO: delete this container?

function mapStateToProps (state): {} {
  return {};
}

function mapDispatchToProps (dispatch) {
  // TODO.
  return {};
}

export default connect(mapStateToProps, mapDispatchToProps)(DetailPane);

【问题讨论】:

    标签: javascript reactjs redux react-router react-redux


    【解决方案1】:

    connect HOC 实现了shouldComponentUpdate 逻辑,所以如果道具没有改变,组件就不会更新。

    为防止这种情况发生并让组件始终呈现,您可以覆盖 connect 调用中的 pure 选项。

    export default connect(mapStateToProps, mapDispatchToProps, undefined, { pure: false })(DetailPane);
    

    有关详细信息,请参阅react-redux API docs。

    【讨论】:

    • 谢谢,这行得通。我现在坚持使用演示版本,但如果我以后需要切换回来,这非常有用。
    猜你喜欢
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 2017-01-29
    • 2021-11-15
    相关资源
    最近更新 更多