嵌套在' smart'下的反应路线不会自动更新Redux容器组件

时间:2017-04-27 14:16:00

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

我正在尝试使用React,React-router和Redux创建一个Electron应用。我发现的是,当我将交换机/路由逻辑嵌套在一个纯粹的表示组件(Page)下时,我的路由逻辑工作得非常好,但是我被迫刷新如果嵌套在' smart'下面,可以看到导航更改的页面容器组件。

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

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

此处,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>

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

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

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

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

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

以下是我的React层次结构 with 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);

1 个答案:

答案 0 :(得分:5)

connect HOC实施shouldComponentUpdate逻辑,因此如果道具没有改变,则该组件不会更新。

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

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

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