React路由器私有路由/重定向无法正常工作

Rei*_*ein 35 reactjs react-router redux react-redux

我稍微调整了React Router示例,让私有路由与Redux一起玩得很好,但在链接或重定向到其他"页面"时没有呈现任何组件.这个例子可以在这里找到:

https://reacttraining.com/react-router/web/example/auth-workflow

他们的PrivateRoute组件如下所示:

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    fakeAuth.isAuthenticated ? (
      <Component {...props}/>
    ) : (
      <Redirect to={{
        pathname: '/login',
        state: { from: props.location }
      }}/>
    )
  )}/>
)
Run Code Online (Sandbox Code Playgroud)

但是,因为我已将它合并到Redux应用程序中,所以我不得不稍微调整一下PrivateRoute,以便我可以访问redux存储以及路径Props:

const PrivateRouteComponent = (props) => (
    <Route {...props.routeProps} render={() => (
    props.logged_in ? (
        <div>{props.children}</div>
        ) : (
        <Redirect to={{
            pathname: '/login',
            state: { from: props.location }
        }} /> )
    )} />
);

const mapStateToProps = (state, ownProps) => {
    return {
        logged_in: state.auth.logged_in,
        location: ownProps.path,
        routeProps: {
            exact: ownProps.exact,
            path: ownProps.path
        }
    };
};

const PrivateRoute = connect(mapStateToProps, null)(PrivateRouteComponent);
export default PrivateRoute
Run Code Online (Sandbox Code Playgroud)

每当我没有登录并点击PrivateRoute时,我都被正确地重定向到/ login.但是,在例如登录并使用a <Redirect .../>或单击任何<Link ...>私有路由后,URI会更新,但视图不会更新.它保留在同一个组件上.

我究竟做错了什么?


只是为了完成图片,在应用程序中index.js有一些不相关的东西,路由设置如下:

ReactDOM.render(
    <Provider store={store}>
        <App>
            <Router>
                <div>
                    <PrivateRoute exact path="/"><Home /></PrivateRoute>
                    // ... other private routes
                    <Route path="/login" component={Login} />
                </div>
            </Router>
        </App>
    </Provider>,
    document.getElementById('root')
);
Run Code Online (Sandbox Code Playgroud)

小智 11

你需要包装你Route<Switch>标签

ReactDOM.render(
<Provider store={store}>
    <App>
        <Router>
            <div>
                <Switch>
                   <PrivateRoute exact path="/"><Home /></PrivateRoute>
                   // ... other private routes
                   <Route path="/login" component={Login} />
                </Switch>
            </div>
        </Router>
    </App>
</Provider>,
document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)

  • 您必须让组件重新渲染.它也可以将PrivateRoute设置为不纯:`export default connect(mapStateToProps,null,null,{pure:false})(PrivateRoute);`也请看这个[Stack Overflow](https://stackoverflow.com/问题/ 43892050 /反应路由器-4-X-privateroute - 不工作-后连接到终极版) (2认同)

Jan*_*art 8

将私有路由设置为不纯:

export default connect(mapStateToProps, null, null, {
  pure: false,
})(PrivateRoute);
Run Code Online (Sandbox Code Playgroud)

这将让Component重新渲染.

请参阅:react-router-4-x-privateroute-not-working-after-connecting-redux.


小智 6

刚遇到同样的问题,我通过制作我的App redux容器并将isAuthenticated作为propR来传递给PrivateRoute

在这里,我希望它有所帮助

const App = (props) => {
return (
  <Provider store={store}>
    <Router>
      <div>
        <PrivateRoute path="/secured" component={Secured} isAuthenticated={props.isAuthenticated} />
      </div>
    </Router>
  </Provider>
  );
};

const mapStateToProps = state => ({
  isAuthenticated: state.isAuthenticated
});

export default connect(mapStateToProps)(App);
Run Code Online (Sandbox Code Playgroud)

然后在我的PrivateRoute中

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

export default PrivateRoute;
Run Code Online (Sandbox Code Playgroud)


New*_*ewm 6

我设法使用rest参数来访问以下数据mapStateToProps:

const PrivateRoute = ({component: Component, ...rest}) => {
  const {isAuthenticated} = rest;

  return (
    <Route {...rest} render={props => (
      isAuthenticated ? (
        <Component {...props}/>
      ) : (
        <Redirect to={{
          pathname: '/login',
          state: {from: props.location}
        }}/>
      )
    )}
    />
  );
};

PrivateRoute.propTypes = {
  isAuthenticated: PropTypes.bool.isRequired,
};

function mapStateToProps(state) {
  return {
    isAuthenticated: state.user.isAuthenticated,
  };
}

export default connect(mapStateToProps)(PrivateRoute);
Run Code Online (Sandbox Code Playgroud)