当嵌套在“智能” Redux容器组件下时,React路由不会自动更新

Tag*_*agc 2 javascript reactjs react-router redux react-redux

我正在尝试使用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>
  );
}
Run Code Online (Sandbox Code Playgroud)

在这两个容器组件中,DetailPaneSideBar是包装在同名表示组件周围的。

在启动时(以及在热重载期间),我使用以下函数创建我的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>
Run Code Online (Sandbox Code Playgroud)

这意味着它<Switch>...</Switch>嵌套在下面<DetailPane>

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

不过,我觉得如果我忽略按预期的路由作品DetailPane来自Page

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

这是我的没有 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>
  );
}
Run Code Online (Sandbox Code Playgroud)

但是,我仍然很好奇为什么这对于容器组件版本不起作用。供参考,这是的容器组件版本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);
Run Code Online (Sandbox Code Playgroud)

Mic*_*per 5

connectHOC工具shouldComponentUpdate的逻辑,所以如果道具不改变,组件不更新。

为了防止这种情况的发生并使组件始终呈现,可以pureconnect调用中覆盖该选项。

export default connect(mapStateToProps, mapDispatchToProps, undefined, { pure: false })(DetailPane);
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参见react-redux API文档