0

In my react application I have a component currentUserMixin which I am using for managing user sign in.

I want my LoginComponent(which shows the login form) to not be visible when a user is already logged in.

After I looked here How to restrict access to routes in react-router? I created this component in currentUserMixin:

NeedsUnAuthenticatedUser: {
      statics: {
        willTransitionTo: function(transition) {
          if(this.authenticated()) {
            transition.abort();
          }
        }
      }
    }

My issue is now that I don't know where to add this component.

Should I add it in the main app component like this:

export default class App extends Component {
    mixins: [currentUserMixin.NeedsUnAuthenticatedUser]

and this:

<Route path="auth" component={AuthIndex}>
                        <Route path="login" component={LoginComponent} onEnter={willTransitionTo} />
                        <Route path="register" component={RegisterComponent} />
                    </Route>

Or should I put it in the actual login component like this:

export default class LoginComponent extends Component {
    mixins: [currentUserMixin.NeedsUnAuthenticatedUser]

So where exactly should I put this mixin?

Community
  • 1
  • 1
bsky
  • 19,326
  • 49
  • 155
  • 270

1 Answers1

0

Mixins don't work with ES6 classes. If you want to use mixins, then you should use React.createClass(). When using ES6 classes normally you can use a high order component to achieve what you want:

function getDisplayName (WrappedComponent) {
  return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}


function needsUnAuthenticatedUser (Component) {

  class WrapperComponent extends Component {
    authenticated () {
       //...
    }

    willTransitionTo (transition) {
      if(this.authenticated()) {
        transition.abort();
      }
    }

    render () {
      return <Component {...this.props} />
    }
  }
  // This is just to display nice stacktraces / inspector name for the component
  WrapperComponent.displayName = `NeedsUnAuthenticatedUser(${getDisplayName(Component)})`

  return WrapperComponent
}

// Usage example:

class ProfilePage extends Component {
  render () {
    return <div>I should be accessible only if user is not logged in...</div>
  }
}

export default needsUnAuthenticatedUser(ProfilePage)
// or const authedProfilePage = needsUnAuthenticatedUser(ProfilePage)

Check this out for a very nice explanation: https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750#.wy6wkysw8

If you prefer, you can use instead the onEnter hook of your Route to redirect the user if already logged in, but also in that case you won't use a mixin, just a plain function:

function checkUserAlreadyLoggedIn (nextState, replace) {
    // put some logic here to decide if use need to redirect
    if (alreadyLoggedIn) {
       replace(/your-redirect-url)
    }
}

const routes = (<Route path="/" component={App}>
     <Route path="/foo" onEnter={checkUserAlreadyLoggedIn} component={LoginForm} />
</Route>)
fabio.sussetto
  • 6,964
  • 3
  • 25
  • 37