Search code examples
javascriptreactjsreact-routerurl-routing

React router:I don't want user to directly navigate to pages by typing urls but allow going to pages only using links inside the app.


My Routes.js

<Route path="/game-center" component={GameCenter} />
      <Route path="/game-center/pickAndWin" component={PickAndWin} />
      <Route path="/game-center/memory" component={Memory} />
      <Route path="/game-center/summary" component={GameSummary} />
    </Route>
  </Router>

On Card Click i'm routing him to the game or summary depending whther game is live or expired.

cardClick=(type, name, status, gameId) => {
    console.log(`here${type}${status}`, name);
    this.props.dispatch(GameCenterActions.setShowGame());
    if (status === LIVE) {
      this.props.dispatch(GameCenterActions.selectGame({ type, name, status, gameId }));
      this.props.dispatch(GameCenterActions.resetShowSummary());
      hashHistory.push(LIVE_GAMES[type]);
    } else if (status === EXPIRED) {
      this.props.dispatch(GameCenterActions.setShowSummary());
      console.log(`${EXPIRED_GAMES}summary page here`);
      this.props.dispatch(GameCenterActions.selectGame({ type, name, status, gameId }));
      hashHistory.push('/game-center/summary');
    }
  }

When user directly types url '/game-center/summary' he should not be allowed and should be sent back to home page. Is this possible in react router itself? I want to implement this in my entire app. I don't want user to directly navigate to pages by typing urls but going to pages only using links inside the app.


Solution

  • You can do this by using Higher Order Components. Such as you can set a flag when user is authenticated and then attach this HOC with the specified component in react router

    import React,{Component} from 'react';
    import {connect} from 'react-redux';
    export default function(ComposedComponent){
      class Authentication extends Component{
        static contextTypes = {
          router : React.PropTypes.object
        }
        componentWillMount(){
          if(!this.props.user){
            this.context.router.push('/');
          }
        }
        componentWillUpdate(nextProps){
          if(!nextProps.user){
              this.context.router.push('/');
          }
        }
        render(){
          return(<ComposedComponent {...this.props}/>);
        }
      } 
    }
    

    And then in your routes

      <Route path="home" component={requireAuth(Home)}></Route>