Search code examples
reactjsreduxreact-redux

Reducers and the switch statement


I am a little new to redux and I am still not totally understanding the connection of the type and the actionCreator. I have the following code in a test class I created:

import {GET_AGE_APPROPRIATE_OPTIONS, GET_AGE_OPTIONS, GET_BINDING_TYPE_OPTIONS} from "../actions/options-actions"

export default function(state = [], action){
    switch(action.type){
        case GET_AGE_APPROPRIATE_OPTIONS:
            return action.payload.data;
        case GET_AGE_OPTIONS:
            return action.payload.data;
        case GET_BINDING_TYPE_OPTIONS:
            return action.payload.data;
    }
    return state
}

In my action creator though I have the following code:

import axios from 'axios';
const ROOT_URL = `http://localhost:8080/`;
const ROOT_OPTIONS_URL = `${ROOT_URL}options`;

export const GET_AGE_OPTIONS = 'GET_AGE_OPTIONS';
export const GET_AGE_APPROPRIATE_OPTIONS = 'GET_AGE_APPROPRIATE_OPTIONS';
export const GET_BINDING_TYPE_OPTIONS = 'GET_BINDING_TYPE_OPTIONS';

export function getAgeOptions() {
    const url = `${ROOT_OPTIONS_URL}/age`;
    const request = axios.get(url);
    return {
        type: GET_AGE_OPTIONS,
        payload: request

    }
}

export function getAgeAppropriateOptions() {
    const url = `${ROOT_OPTIONS_URL}/ageappropriate`;
    const request = axios.get(url);
    return {
        type: GET_AGE_APPROPRIATE_OPTIONS,
        payload: request

    }
}

export function getBindingTypeOptions() {
    const url = `${ROOT_OPTIONS_URL}/bindingtype`;
    const request = axios.get(url);
    return {
        type: GET_BINDING_TYPE_OPTIONS,
        payload: request

    }
}

The problem is when I call one of these functions it only calls the first part of the case statement of the reducer. I would have thought since my actionCreator had different types being passed, that it would switch the detail. But upon thinking about it, I cannot see how the reducer is called on different actions, because I am calling the action directly after using mapDispatchToProps. But the mapStateToProps in this scenario would all be calling the same case statement, and thus taking the same value for mapStateToProps. So how can I get the reducer to call the type that I need when I call my action? The only way I have found to get this to work, is to separate out all of the options into separate reducer files, then in combine reducers it is calling the correct part of the reducer case. But it is a LOT of files, and have to call multiple files in my combineReducers. I am only trying to get options, I am looking for ways to combine it manually.


Solution

  • A single reducer can have multiple options.

    const defaultState = {
      ageAppropriateOptions: [],
      ageOptions: [],
      bindingTypeOptions: []
    };
    
    export default function(state = defaultState, action){
        switch(action.type){
            case GET_AGE_APPROPRIATE_OPTIONS:
                return {
                   ...state,
                   ageAppropriateOptions: action.payload.data
                };
            case GET_AGE_OPTIONS:
                return {
                    ...state,
                    ageOptions: action.payload.data
                };
            case GET_BINDING_TYPE_OPTIONS:
                return {
                    ...state,
                    bindingTypeOptions: action.payload.data
                };
        }
        return state
    }