73

Ok, I'm fed up trying.
The onEnter method doesn't work. Any idea why is that?

// Authentication "before" filter
function requireAuth(nextState, replace){
  console.log("called"); // => Is not triggered at all 
  if (!isLoggedIn()) {
    replace({
      pathname: '/front'
    })
  }
}

// Render the app
render(
  <Provider store={store}>
      <Router history={history}>
        <App>
          <Switch>
            <Route path="/front" component={Front} />
            <Route path="/home" component={Home} onEnter={requireAuth} />
            <Route exact path="/" component={Home} onEnter={requireAuth} />
            <Route path="*" component={NoMatch} />
          </Switch>
        </App>
      </Router>
  </Provider>,
  document.getElementById("lf-app")

Edit:

The method is executed when I call onEnter={requireAuth()}, but obviously that is not the purpose, and I also won't get the desired parameters.

Brian Burns
  • 20,575
  • 8
  • 83
  • 77
html_programmer
  • 18,126
  • 18
  • 85
  • 158

3 Answers3

136

onEnter no longer exists on react-router-4. You should use <Route render={ ... } /> to get your desired functionality. I believe Redirect example has your specific scenario. I modified it below to match yours.

<Route exact path="/home" render={() => (
  isLoggedIn() ? (
    <Redirect to="/front"/>
  ) : (
    <Home />
  )
)}/>
Deividas
  • 6,437
  • 2
  • 26
  • 27
  • Although, I noticed today that this doesn't actually render the component of the new url to which is redirected. Is this desired behaviour? Doesn't seem very logical... – html_programmer Mar 14 '17 at 09:28
  • 1
    @KimGysen no, this is not the default behaviour. If you are using `Switch` component then `Redirect` should be rendered as expected. However, if you are not using `Switch`, `Redirect` will not be rendered (as I assume was your use case). – Deividas Mar 15 '17 at 06:21
  • @Deividas Karžinauskas i see there is a small issue in here , what if the user ? front content should load after authencated right ? – Mr.G Jun 20 '17 at 13:05
  • 18
    What's happen if isLoggedIn is Async function? – Ego Slayer Dec 06 '17 at 11:59
  • How does this work if you are using Redux? how do you access isLoggedIn, if it is in your state's tree? – Kermit_ice_tea Jan 10 '18 at 05:38
  • One way is to import your store and access the `getState()` method which will return the current state of the store: `import store from '../store/store.index'; // or wherever your initialized store is exported` `const { getState } = store;` `const isLoggedIn = getState().app.isLoggedIn; // Adjust according to your state tree` – Yumbelie Jan 12 '18 at 20:53
  • works, but now Home will not have "history" in its props. I don't understand why. It would normally have, if Route was defined with "component={Home}" rather than a render. – schlingel Apr 04 '19 at 13:42
  • 2
    @EgoSlayer in case of a [**Promisified**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) isLoggedIn `render={ () => { isLoggedIn().then( res => { return res ? ( ) : ( )}) }}` – Smily Apr 12 '19 at 08:40
  • @Smily Thank you. – Ego Slayer Apr 12 '19 at 14:22
  • 3
    @Smily How would that work? The render callback isn't actually returning anything. – Drazen Bjelovuk Jan 28 '20 at 20:13
  • @Smily Tested and promises don't work with `render` (had to see if React was adding any magic to enable this) – Ricky Boyce May 06 '20 at 09:25
33

From react-router-v4 onEnter, onUpdate, and onLeave is removed, according the documentation on migrating from v2/v3 to v4:

on* properties
React Router v3 provides onEnter, onUpdate, and onLeave methods. These were essentially recreating React's lifecycle methods.

With v4, you should use the lifecycle methods of the component rendered by a <Route>. Instead of onEnter, you would use componentDidMount or componentWillMount. Where you would use onUpdate, you can use componentDidUpdate or componentWillUpdate (or possibly componentWillReceiveProps). onLeave can be replaced with componentWillUnmount.

totymedli
  • 29,531
  • 22
  • 131
  • 165
Fangxing
  • 5,716
  • 2
  • 49
  • 53
1

For react-router-6 the Redirect component has been replaced with Navigate.

Below userState will be either null or populated depending upon if user is logged in or not, can be your Redux state for example.

<Route path="/protectedRoute"
            element={userState ? <protectedComponent/> : <Navigate to="/login"/>}/>
WK123
  • 620
  • 7
  • 18