Skate to Eat
Skate to Eat

Reputation: 2844

React render private route after redux(user authentication) is updated

PrivateRoute is rendering before Redux gets current user data from the server. What is the best way to fix this issue?

The component looks like below. userAuth.isAuthenticated eventually updates to true but it renders <Redirect to="/login" /> first before it gets updated.

const userAuth = {
  isAuthenticated: false
}

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={(props) => (
    // PROBLEM: this renders before Redux gets user authentication data from the server
    userAuth.isAuthenticated ? <Component {...props} /> : <Redirect to="/login" />
  )}/>
)

class App extends Component {
  componentDidMount() {
    // Get current user data when user refresh the browser
    // This sets isLoginSuccess: true is current user is logged-in in Redux store
    this.props.getCurrentUserSession();
  }

  render() {
    // Show loading icon while fetching current user data
    if(this.props.user.isFetchingCurrentUserSession){
      return (<div><img src={squareLogo} className="logo-loading" alt="Loading icon" /></div>);
    }

    // Set current user authentication status
    userAuth.isAuthenticated = this.props.user.isLoginSuccess

    return (
      <Router>
        <div>
          <Route path="/public" component={Public} />
          <PrivateRoute path="/private" component={Private} />
        </div>
      </Router>
    );
  }
}

function mapStateToProps(state) {
  return state
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    getCurrentUserSession
  }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(App)

Upvotes: 4

Views: 1429

Answers (1)

aravind_reddy
aravind_reddy

Reputation: 5496

You can do like this:

1.Intialize isAuthenticated to null

2.in render return use conditional rendering of the private component

const userAuth = {
 isAuthenticated: null
}

in App render return:

return (
  <Router>
    <div>
      <Route path="/public" component={Public} />
      {(userAuth.isAuthenticated!==null)?<PrivateRoute path="/private" 
      component={Private} />:null}
    </div>
  </Router>
);

Upvotes: 3

Related Questions