简体   繁体   中英

React Container - access state from either reducer

I'm having trouble wrapping my head around this. Basically , i have a component which pulls a isFetching boolean from the state

function mapStateToProps(state){
  const {errorMessage,isFetching} = state.signUp
  const {isAuthenticated,username} = state.login;
  return {
    isAuthenticated,
    errorMessage,
    isFetching,
    username
  }
}

i have the below reducers

export const signUp = (state={},action) => {
  switch(action.type){
    case SIGNUP_REQUEST:
      return Object.assign({},state,{
        isFetching: true
      })
    case SIGNUP_FAILURE:
      return Object.assign({},state,{
        isFetching:false,
        // isAuthenticated: false,
        errorMessage: action.message
      })
    default:
      return state
  }
}

export const login = (state={isAuthenticated:false},action) => {
  switch(action.type){
    case LOGIN_REQUEST:
      return Object.assign({},state,{
        isFetching: true,
        isAuthenticated: false
      })
    case LOGIN_SUCCESS:
      return Object.assign({},state,{
        isFetching:false,
        isAuthenticated:true,
        username: action.username
      })
    case LOGIN_FAILURE:
      return Object.assign({},state,{
        isFetching: false,
        isAuthenticated: false,
        errorMessage: action.message
      })
    default:
      return state
  }
}

when i dispatch a loginRequest - the reducer turns isFetching to true. but the component still doesnt update because its looking at the isFetching variable only from the signUp Reducer.

is there a way i can have the component look at both reducers for the isFetching variable?

There are a couple options:


Create a 3rd (loading state) reducer

Create another reducer which only has the isFetching in it's state, and listen for the same events.

export const loading = (state={}, action) => {
  switch(action.type) {
    case SIGNUP_REQUEST:
    case LOGIN_REQUEST:
      return Object.assign({},state,{
        isFetching: true
      })
    case SIGNUP_SUCCESS:
    case SIGNUP_FAILURE:
    case LOGIN_SUCCESS:
    case LOGIN_FAILURE:
      return Object.assign({},state,{
        isFetching: false
      })
    default:
      return state
  }
}

If there is any chance these two requests could overlap, then you should probably have the independent isLoading variables and just use || .


Check both isFetching variables in the view

{signup.isFetching || login.isFetching}

This is good if the requests could overlap.


Put it all in one reducer

not so good..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM