mangocaptain mangocaptain - 3 months ago 16
React JSX Question

Should I organize my react redux reducer composition based on the calls made OR based on the state a reducer manages?

I'm learning to build a pokedex app that gives you info about a pokemon after you type in a name and hit submit. It has to go through 2 calls to get the right info, with the 1st getting its height and weight, and then 2nd getting its description (ex. "Charmander can usually be found in hot areas..."). Below is my action breakdown.

export const fetchPokemon = function (pokemonName) {
return function (dispatch) {
dispatch(requestPokemon(pokemonName))
const requestURL = `http://pokeapi.co/api/v2/pokemon/${pokemonName}/`
return $.ajax({
url: requestURL,
}).done(function (data) {
dispatch(receivePokemon(data))
return fetchPokemonDescription(pokemonName)
}).done(function (res) {
dispatch(receivePokemonDescription(res))
})
}
}

...

export const fetchPokemonDescription = function (pokemonName) {
return function (dispatch) {
dispatch(requestPokemonDescription(pokemonName))
const requestURL = `http://pokeapi.co/api/v2/pokemon-species/${pokemonName}/`
return $.ajax({
url: requestURL,
})
}
}


Should I have a separate reducer for each call? Looking at the docs about reducer composition I'm not sure if it would make it cleaner to have 1 reducer vs 2 reducers. The 2 calls are not dependent on each other per say, but each different pokemon input will need to make both calls and the data coming back from both belongs to one pokemon so I was thinking it should be in one reducer handling one part of the state.

Answer

I would use 1 reducer in your case.

It would be useful to see your state structure, but I think that you have something like:

currentPokemon: {
  name: ...
  height: ...
  weight: ...
  description: ...
}

If this is the case, I would use 1 reducer, because you manage just 1 branch of the state (currentPokemon).

The reducer will switch the action: in one case it will update height and weight, in the other the description:

export default function currentPokemonReducer (state = initialState, action) {
  switch(action.type) {
    case DATA_RECEIVED:
      return {
        ...state,
        height: action.payload.height,
        weight: action.payload.weight
      }
    case DESCRIPTION_RECEIVED:
      return {
        ...state,
        description: action.payload
      }

    ...

    default:
      return state;
    }
}
Comments