React Router 4.x - 连接到Redux后PrivateRoute无法正常工作

Pre*_*ngh 13 reactjs redux react-router-redux react-router-v4 react-router-dom

与Redux连接后,示例https://reacttraining.com/react-router/web/example/auth-workflow中的 PrivateRoute无效.

我的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);
Run Code Online (Sandbox Code Playgroud)

用法和结果: -

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

Tom*_*zyk 12

作为@Tharaka答案的补充,您可以传递{pure: false}react-reducingx故障排除部分中connect描述的方法.

React-reduxshouldComponentUpdate钩子中的道具进行浅层比较,以避免不必要的重新渲染.如果上下文道具发生了变化(react-router),它就不会检查它并假设没有任何变化.

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


Ole*_*leb 8

根据react-router文档,您可以使用以下命令包装您的connect函数withRouter:

// before
export default connect(mapStateToProps)(Something)

// after
import { withRouter } from 'react-router-dom'
export default withRouter(connect(mapStateToProps)(Something))
Run Code Online (Sandbox Code Playgroud)

这对我有用.


Tha*_*ara 7

这是react-redux中的已知问题,您可以在此处阅读更多相关信息.问题是connectHoC已实现shouldComponentUpdate,因此如果props未更改,则包装组件不会重新呈现.由于react-router使用上下文来传递路由更改,因此包装的组件在路由更改时不会重新呈现.但似乎他们shouldComponentUpdate在5.1版本的react-redux中删除.目前,作为一种解决方法,我将来自路由器的道具传递this.props.match.params给连接子组件,即使我不在内部使用它.但是每当路线发生变化时,它都会重新渲染组件.