0

I created a component called EnsureLoggedInContainer which wraps around components that only a logged in user can access:

ReactDOM.render(
  <Provider store={store}>
      <BrowserRouter>
        <div>
          <Switch>
            <Route path="/login" render={(props) => {
                if (isAuthenticated()) {
                  return <Redirect to='/' />;
                } else {
                  return <LoginForm {...props}/>
                }
              }
            } />
            <EnsureLoggedInContainer>
              <Route exact path="/api/group" component={GroupList}/>
              <Route component={Home}/>
            </EnsureLoggedInContainer>
          </Switch>
        </div>
      </BrowserRouter>
  </Provider>
  , document.querySelector('.container'));

class EnsureLoggedInContainer extends Component {
  componentDidMount() {
    if (!isAuthenticated()) {
      const redirected_from = this.props.location.state ? this.props.location.state.from.pathname : '/';

      this.props.history.push(redirected_from);

      dispatch(setRedirectUrl(currentURL))
      this.props.history.replace("/login")
    }
  }

  render() {
    if (isAuthenticated()) {
      return(
        <div>
          <AppNavBar />
          <ComponentsNavBar />
          {this.props.children}
        </div>
      );
    } else {
      return <noscript />;
    }
  }
}

export default EnsureLoggedInContainer;

Right now, Home component is always rendered. How can I make it a no-match route, such as it renders only if path doesn't match with any provided route paths ?

I added path="*" to <Route component={Home}/> and it still always renders.

Arian
  • 7,397
  • 21
  • 89
  • 177

2 Answers2

0

If you're using react-router 4 you should try:

<Route component={YourNotFoundPage}/> (without path="*")

Keep in mention that your question might be duplicated, you should see this also.

Hope that helps.

Lucaci Sergiu
  • 564
  • 5
  • 17
  • I tried it without `path="*"` and it didn't work. And I don't see how that post is related to my question, and there's no accepted answer for it. – Arian Jan 30 '18 at 21:00
0

It seems that the whole design was buggy. I followed Private Route pattern and resolved the issue:

export const PrivateRoute = ({component: Component, componentProps, ...rest }) => {
    return (<Route {...rest} render={(props) => {
        if (isAuthenticated()) {
          return (
            <div>
              <AppNavBar />
              <ComponentsNavBar />
              <Component {...props} {...componentProps}/>
            </div>
          )
        } else {
          return <Redirect to={{ pathname: '/login', state: { from: props.location } }} />;
        }
      }
    } />);
}

export default PrivateRoute;

And then used PrivateRoute like this:

  <BrowserRouter>
    <div>
      <Switch>
        <Route exact path="/login" render={props =>
            isAuthenticated() ? <Redirect to='/' /> :
            <LoginForm {...props}/>
        } />
        <Route exact path="/register" render={props =>
            isAuthenticated() ? <Redirect to='/' /> :
            <RegisterForm {...props}/>
        } />
        <PrivateRoute exact path="/group" component={GroupList}/>
        <PrivateRoute exact path="/group/new" component={GroupList} componentProps={{
          modal:{
            'content': NewGroup,
            'className': 'new-group-modal'
          }}}
        />
        <PrivateRoute exact path="/group/:id" component={ShowGroup} />
        <PrivateRoute component={Home}/>
      </Switch>
    </div>
  </BrowserRouter>
Arian
  • 7,397
  • 21
  • 89
  • 177