【问题标题】:React Router 4.x - PrivateRoute not working after connecting to ReduxReact Router 4.x - PrivateRoute 在连接到 Redux 后不起作用
【发布时间】:2017-10-09 01:51:03
【问题描述】:

示例https://reacttraining.com/react-router/web/example/auth-workflow 中可用的PrivateRoute 在与Redux 连接后不起作用。

我的 PrivateRoute 看起来与原始版本几乎相同,但只是连接到 Redux 并在原始示例中使用它而不是 fakeAuth。

const PrivateRoute = ({ component: Component, auth, ...rest }) => (
  <Route
   {...rest}
   render={props =>
   auth.isAuthenticated
    ? <Component {...props} />
    : <Redirect to={{ pathname: "/login" }} />}
  />
);

 PrivateRoute.propTypes = {
  auth: PropTypes.object.isRequired,
  component: PropTypes.func.isRequired
 }

 const mapStateToProps = (state, ownProps) => {
  return {
     auth: state.auth
  }
};

export default connect(mapStateToProps)(PrivateRoute);

用法和结果:-

  1. 不工作但希望并期望工作
    • &lt;PrivateRoute path="/member" component={MemberPage} /&gt;
  2. 工作但不希望这样使用
    • &lt;PrivateRoute path="/member" component={MemberPage} auth={auth} /&gt;
  3. 工作。只是工作,但根本不想使用。从这一点的理解是,如果您将原始 PrivateRoute 连接到 Redux,您需要传递一些额外的道具(任何道具)以使 PrivateRoute 工作,否则它不起作用。 任何人,请就这种行为给出一些提示。这是我的主要问题
    • &lt;PrivateRoute path="/member" component={MemberPage} anyprop={{a:1}} /&gt;

【问题讨论】:

    标签: reactjs redux react-router-redux react-router-v4 react-router-dom


    【解决方案1】:

    这是 react-redux 中的已知问题,您可以阅读更多关于此here 的信息。问题是connect HoC 已经实现了shouldComponentUpdate,所以如果props 没有改变,包裹的组件就不会重新渲染。由于 react-router 使用上下文来传递路由更改,因此当路由更改时,包装的组件不会重新渲染。但似乎他们将在 5.1 版本的 react-redux 中使用remove shouldComponentUpdate。目前,作为一种解决方法,我将来自路由器的道具(如this.props.match.params)传递给连接的子组件,即使我没有在内部使用它。但是每次路由改变时都会重新渲染组件。

    【讨论】:

    • 你能给我写一个 PrivateRoute 的工作使用示例吗,或者需要对 PrivateRoute 本身进行更改
    • 我想不出任何方法可以让 PrivateRoute 在您的 1 使用中按预期工作。我的建议是,如果它对你有用,就使用用法 3,直到他们解决这个问题。或者你可以像这样将params 传递给 PrivateRoute。 &lt;PrivateRoute path="/member" component={MemberPage} params={this.props.match.params}/&gt;
    • 作为另一种解决方法,我在更改历史记录之后立即使用 forceUpdate()
    • update: 我发现使用redux的父组件也必须连接到withRouter,因此不需要使用forceUpdate()
    【解决方案2】:

    作为@Tharaka 答案的补充,您可以将{pure: false} 传递给connect 方法,如react-redux troubleshooting section 中所述。

    React-redux 对 shouldComponentUpdate 钩子中的 props 进行浅层比较,以避免不必要的重新渲染。如果 context props 发生了变化(react-router),它不会检查它并假设没有任何变化。

    { pure:false } 只是禁用这种浅层比较。

    【讨论】:

    • 谢谢,我会试试的。
    • 我相信这回答了最符合预期结果的问题。为我工作
    • 请详细说明pure 的含义以及使用它的缺点是什么。基于链接的答案只有完整答案的一半;)
    【解决方案3】:

    根据react-router documentation,您可以只用withRouter 包装您的connect 函数:

    // before
    export default connect(mapStateToProps)(Something)
    
    // after
    import { withRouter } from 'react-router-dom'
    export default withRouter(connect(mapStateToProps)(Something))
    

    这对我有用。

    【讨论】:

    • 太棒了!这是最简单的解决方案。我还删除了对我有用的 shouldComponentUpdate() 函数
    猜你喜欢
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 2018-07-24
    • 2018-10-16
    • 2017-09-28
    • 2019-03-22
    相关资源
    最近更新 更多