1

Been at this all weekend. Upon refresh of the page, React Router keeps routing to the /login page first, then to the homepage "/".

ReactDOM.render(
<Provider store={store}>
    <Router>
        <Switch>
        <Route path="/login" component={Login} />
            <AuthenticatedComponent>
            <Header />
            <Route path="/" component={App} exact />
            </AuthenticatedComponent>
        </Switch>
    </Router>
</Provider>,
document.getElementById("root")
);

I've tried moving around the Routes but that doesn't work - no errors, it just does the same thing. One thing I'm doing is saying. "If user is logged in (no null), immediately route them to the home page "/". This is being done in the { Login } component and written below:

componentWillReceiveProps(props) {
    if(props.user !== null) {
        props.history.push('/')
    }
}

This works like a charm. The problem is, whenever I refresh my browser, the url immediately goes to /login, then to "/", which is home. I added the AuthenticatedComponent wrapper as a last resort test. I have written in this component the following:

componentWillMount(){
    if( this.props.user !== null) {
        this.props.history.push('/')
    } else {
        this.props.history.push('/login')
    }
}

I'm not receiving any errors - The functionality is just off a little

5
  • How to you authenticate the user? I assume you don't check with the remote server if the user is logged in after a browser refresh? Commented Sep 16, 2018 at 9:01
  • I am going to implement that later, adding in “isAuthenticated” when I make my DB calls. Commented Sep 16, 2018 at 9:02
  • 1
    I guess you don't persist the state? For example the authenticated user and read it back on page refresh? Currently you have the initial state of you app ( e.g user not authenticated) on every page refresh. Commented Sep 16, 2018 at 9:07
  • The Authenticated user is stored in the “user” state and I am calling getUser() on the pages. What do you suggest? Commented Sep 16, 2018 at 9:08
  • So to rephrase my previous comment: in a basic react app everything(props,state) will get reset on page refresh. This means you have to either persist data you want to keep across page refreshes to e.g. web storage, or communicate with your Backend to get initial data on page refresh (the current authenticated user, etc) Commented Sep 16, 2018 at 9:13

1 Answer 1

1

Wrap the <Switch> with your <AuthenticatedComponent> (and move the <Header /> inside of your auth component).

Or create a HOC Wrapper component (modular and useful if some routes require auth and some do not).

Working Example: https://codesandbox.io/s/5m2690nn6n

RequireAuth.js

import React, { Component, Fragment } from "react";
import { withRouter } from "react-router";
import Login from "./Login";
import Header from "./Header";

class RequireAuth extends Component {
  state = { isAuthenticated: false };

  componentDidUpdate = (prevProps, prevState) => {
    if (this.props.location.pathname !== prevProps.location.pathname && !this.state.isAuthenticated) {
      this.props.history.push("/");
    }
  };

  isAuthed = () => this.setState({ isAuthenticated: true });

  unAuth = () => this.setState({ isAuthenticated: false });

  render = () => (
    !this.state.isAuthenticated 
      ? <Login isAuthed={this.isAuthed} />
      : <Fragment>
          <Header unAuth={this.unAuth} />
          {this.props.children}
        </Fragment>
  );
}

export default withRouter(RequireAuth);

index.js

import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import Home from "../components/Home";
import Players from "../components/Players";
import Schedule from "../components/Schedule";
import RequireAuth from "./components/RequireAuth";
import "uikit/dist/css/uikit.min.css";

render(
  <BrowserRouter>
    <RequireAuth>
      <Switch>
        <Route exact path="/" component={Home} />
        <Route exact path="/players" component={Players} />
        <Route path="/schedule" component={Schedule} />
      </Switch>
    </RequireAuth>
  </BrowserRouter>,
  document.getElementById("root")
);

For anyone who is using react-router v3:

index.js

render (
  <Router>
    <Route path="/" component={RequireAuth}>
      <IndexRoute component={Home} />
      <Route path="players" component={Players} />
      <Route path="schedule" component={Schedule} />
    </Route>
  </Router>, document.getElementById("root")
);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.