React router private routes / redirect not working

后端 未结 9 1227
轮回少年
轮回少年 2020-12-07 16:57

I have slightly adjusted the React Router example for the private routes to play nice with Redux, but no components are rendered when Linking or Redirecting to other \'pages

相关标签:
9条回答
  • 2020-12-07 17:06

    Set the private route to not be pure:

    export default connect(mapStateToProps, null, null, {
      pure: false,
    })(PrivateRoute);
    

    This will let the Component re-render.

    Please see: react-router-4-x-privateroute-not-working-after-connecting-to-redux.

    0 讨论(0)
  • 2020-12-07 17:08

    Just had same problem, I solved it by making my App redux container and passing isAuthenticated as a prop to PrivateRoute

    Here it is, I hope it helps

    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);
    

    Then in my 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;
    
    0 讨论(0)
  • 2020-12-07 17:12

    According to react-router documentation you may just wrap your connect function with withRouter:

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

    This worked for me and my views started to be updated along with routes in this case.

    0 讨论(0)
  • 2020-12-07 17:18

    I have the similar issue like @Rein. In my case, PrivateRoute looks almost same to the original version but only connected to Redux and used it instead of fakeAuth in the original example.

    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);
    

    Usage and result:-

    1. NOT working but expecting to work
      • <PrivateRoute path="/member" component={MemberPage} />
    2. working but NOT desired to used like this
      • <PrivateRoute path="/member" component={MemberPage} auth={auth} />
    3. working. JUST to work but NOT desired to used at all. An understanding from this point is that, if you connect original PrivateRoute to Redux, you need to pass some additional props (any prop)to make PrivateRoute working otherwise it does not work. Anyone, please give some hint on this behavior. This is my main concern. As a New Question at
      • <PrivateRoute path="/member" component={MemberPage} anyprop={{a:1}} />
    0 讨论(0)
  • 2020-12-07 17:19

    You need to wrap your Route with <Switch> tag

    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'));
    
    0 讨论(0)
  • 2020-12-07 17:21

    I have struggled with this issue as well, and here is my solution.

    Instead of passing isAuthenticated to every < PrivateRoute> component, you just need to get isAuthenticated from state in < PrivateRoute> itself.

    import React from 'react';
    import {Route, Redirect, withRouter} from 'react-router-dom';
    import {connect} from 'react-redux';
    
    // isAuthenticated is passed as prop here
    const PrivateRoute = ({component: Component, isAuthenticated , ...rest}) => {
        return <Route
            {...rest}
            render={
                props => {
                    return isAuthenticated ?
                        (
                            <Component {...props} />
                        )
                        :
                        (
                            <Redirect
                                to={{
                                    pathname: "/login",
                                    state: {from: props.location}
                                }}
                            />
                        )
                }
            }
        />
    };
    
    const mapStateToProps = state => (
        {
            // isAuthenticated  value is get from here
            isAuthenticated : state.auth.isAuthenticated 
        }
    );
    
    export default withRouter(connect(
        mapStateToProps, null, null, {pure: false}
    )(PrivateRoute));
    
    0 讨论(0)
提交回复
热议问题