简体   繁体   中英

Private Route with Redux

I am trying to create a private route which checks user authentication. But the Private route renders before data from redux Is updated. The component has like isauthenticated variable which eventually updates to true but the component renders first before it gets updated. As the redux has its value as false at 1st render.

import React, { Component } from 'react'
import {connect} from 'react-redux'
import {Route, Redirect } from 'react-router-dom'

const PrivateRoute = ({component: Component, isAuthenticated, ...rest}) =>{
    return(
        <Route {...rest} render={
            (props) => {
                if(isAuthenticated) { 
                    return <Component {...props}/>
                }else{
                    return <Redirect to="/login"/>
                }

            }
        }/>
    )
}

const mapStateToProps = state =>{
    return{
        isAuthenticated: state.token !== null
    }
}

export default connect(mapStateToProps, null)(PrivateRoute)

You can wrap your router inside an auth-is-loaded component:

import React from "react";
import { useSelector } from "react-redux";
import { isLoaded } from "react-redux-firebase";

export default function AuthIsLoaded({ children }) {
  const auth = useSelector(state => state.firebase.auth);

  if (isLoaded(auth)) return children;
  return <div>Loading...</div>;
}

So App.js will be like this:

  return (
    <Provider store={store}>
        <BrowserRouter>
          <AuthIsLoaded>
            <NavBar />
              <Switch>
                <Route exact path="/" component={Home} />
                <PrivateRoute path="/about" component={About} />
                <PrivateRoute path="/profile" component={Profile} />
                <Route path="/login" component={Login} />
                <Route path="/signup" component={SignUp} />
                <Route path="/logout" component={Logout} />
              </Switch>
            </AuthIsLoaded>
        </BrowserRouter>
    </Provider>
  );

So after auth loaded your switch will be rendered PrivateRoutes wont get isAuthenticated before redux load it.

Sorry about some extra code, I copied from my app, but you should get the idea.

simply add option {pure:false} to connect. and you should be good to go.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM