React Router 4.x - PrivateRoute 在连接到 Redux 后不起作用

Posted

技术标签:

【中文标题】React Router 4.x - PrivateRoute 在连接到 Redux 后不起作用【英文标题】:React Router 4.x - PrivateRoute not working after connecting to 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);

用法和结果:-

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

【问题讨论】:

【参考方案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-reduxshouldComponentUpdate 钩子中的 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() 函数

以上是关于React Router 4.x - PrivateRoute 在连接到 Redux 后不起作用的主要内容,如果未能解决你的问题,请参考以下文章

react router 4.x

react-router 4.x 路由按需加载

React-Router4.x中文文档

react-router 4.x

你应该知道的react router 4

十八React react-router4.x中:实现路由模块化以及嵌套路由父子组件传值