0

I use react-router and react-router-redux, I will redirect user to Login page if he tries to visit a page requiring logged in without logging in:

<Route path="/react/myprofile" component={MyProfile} onEnter={requireAuth} /></Route>


function requireAuth(nextState, replace) {
   const state_user = store.getState().auth.user;
   if (!state_user) {
     console.log('not logged in, redirect')
     replace({
       pathname: '/react/login',
       state: { nextPathname: nextState.location.pathname }
     })
   }
}

And after the user logs in, I will redirect the user to "/react/myprofile": in my redux-saga, I do the following:

const route_state = get routing state from the store;
redirectTo(route_state.locationBeforeTransitions.state.nextPathname);

As above, I have to retrieve the information from route_state.locationBeforeTransitions.state.nextPathname, it is too verbose, and it seems strange to do as this.

I wonder if there is a better way to do this? Thanks.

Luke
  • 93
  • 1
  • 6

1 Answers1

1

You can create a selector to extract the relevent piece of state and use it with the select effect from inside your saga

// for example in some file selectors
export const nextPathSelector = state => ...

// in some sagas.js file
import { nextPathSelector } from './selectors'
import { call, select, ... } from 'redux-saga/effects'

function* saga() {
  ...
  const nextPath = yield select( nextPathSelector )
  yield call(redirectTo, nextPath)
}

Using selectors makes your sagas independant from the state shape. And using the select effect you can test the logic of the saga without moking the whole store. For example

const gen = saga()

assert.deepEqual(
   gen.next().value,
  select( nextPathSelector )
)

assert.deepEqual(
   gen.next('dummy-path').value,
   call(redirectTo, 'dummy-path')
)
Yassine Elouafi
  • 6,489
  • 1
  • 16
  • 16