【问题标题】:Why is PrivateRoute preventing my Redux-connected component from re-rendering on store state update?为什么 PrivateRoute 会阻止我的 Redux 连接组件在存储状态更新时重新渲染?
【发布时间】:2019-01-25 16:04:30
【问题描述】:

在我的<Content> 组件中,我有:

<PrivateRoute path="/monitors" component={MonitorsPage}/>

在&lt;MonitorsPage&gt;内:

<Route path="/monitors/:device_id/live" component={MonitorLive}/>

&lt;MonitorsLive&gt; 使用 Redux connect() 订阅存储状态更改。

这是我的测试&lt;PrivateRoute&gt;:

import React from "react";
import { Route } from "react-router-dom";

function delay(t, v) {
  return new Promise(function(resolve) {
    setTimeout(resolve.bind(null, v), t)
  });
}

class PrivateRoute extends React.Component {
  state = {
    isLoaded: false,
  };

  authenticate() {
    delay(1000).then(()=>{
      console.log('AUTHENTICATED');
      this.setState({isLoaded: true})
    })
  }

  componentDidMount() {
    this.authenticate()
  }

  render() {
    const {component: Component, ...rest} = this.props;
    const { isLoaded } = this.state;

    return (
      <Route {...rest} render={
        props => (!isLoaded ? <div>loading...</div> : <Component {...props} />)
      }
      />
    )}}

export default PrivateRoute

如果我导航到/monitors/:device_id/live 路由并刷新浏览器,组件加载和安装正常,但在这种情况下无法重新渲染存储状态更改。它在许多其他条件下都能正常工作,包括:

  1. 从/monitors 路由导航到问题路由(而不是浏览器硬重新加载)或
  2. &lt;Content&gt; 和 &lt;MonitorsPage&gt; 都使用 &lt;Route&gt; 而不是 &lt;PrivateRoute&gt; 或
  3. &lt;Content&gt; 和 &lt;MonitorsPage&gt; 都使用 &lt;PrivateRoute&gt; 而不是 &lt;Route&gt; 或
  4. &lt;Content&gt; 使用 &lt;Route&gt; 和 &lt;MonitorsPage&gt; 使用 &lt;PrivateRoute&gt; 或
  5. this.setState({isLoaded: true}) 在 PrivateRoute 中没有前面的 delay(1000) 执行

当我知道所有孩子 Routes 也将是私有的,而不会破坏 redux 时,我该如何做到这一点,以便我可以将我的 PrivateRoute 作为父母?

更新:我已修改 MonitorLive 和 MonitorsPage 以在导出语句中包含 withRouter()。 Content 已经有了。此更改不能解决问题。示例导出语句:

export default withRouter(connect(mapStateToProps,mapDispatchToProps)(MonitorLive))

更新 2: 除了消除上述问题的 5 种情况外,还有以下情况:

如果我从Content 中删除带有“文本”或&lt;span&gt;span&lt;/span&gt; 的行:

class Content extends Component {

  render() {
    return (
      <div>
        <div>
          text
          <span>span</span>
        </div>
        <div>
          <button onClick={this.props.getMonitorLiveValues}>Update State</button>
          <Switch>
            <PrivateRoute
              path="/monitors"
              component={MonitorsPage}
            />
          </Switch>
        </div>
      </div>
    )}}

更新 3: 演示问题:https://vvmk3qorq7.codesandbox.io/monitors/ARMS-NVM-P5/live

https://codesandbox.io/s/vvmk3qorq7

【问题讨论】:

  • 如果你把delay改成普通的setTimeout()还是会导致渲染错误?
  • @DorShinar 是的,我使用 setTimeout() 得到相同的行为
  • MonitorsPage 组件在setState() 之后是否会延迟重新渲染?
  • @DorShinar 在延迟后我得到了MonitorsPage 和MonitorsLive 的第一个(初始)渲染。没有重新渲染。
  • 你能验证状态正在更新吗?根据您的回答,我认为这不是与 redux 相关的问题

标签: reactjs react-redux react-router


【解决方案1】:

通过将 react-dom 从 16.3.2 升级到 16.4.0 解决了该问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 2021-06-22
    • 2018-11-30
    • 2017-01-14
    • 2020-03-03
    • 1970-01-01
    相关资源
    最近更新 更多