admin管理员组

文章数量:1279183

Let's say I have the next reducer:

export default (state = [], { type, payload }) => {
    switch (type) {

        case FETCH_POKEMONS:
            const objeto = {};
            payload.forEach((conexion) => {
                objeto[conexion.name] = conexion
            });
            return objeto;

        case FETCH_POKEMON:
        return { ...state, ...payload }

        default:
            return state
    }
}

And I will have a bineReducers like this:

export default bineReducers({
    pokemons: pokemonReducers,
});

But I want to have pokemons state for the FETCH_POKEMONS actions and another state called pokemon for the FETCH_POKEMON acton. How can I derivate two states in the bineReducers from one reducer file?

Let's say I have the next reducer:

export default (state = [], { type, payload }) => {
    switch (type) {

        case FETCH_POKEMONS:
            const objeto = {};
            payload.forEach((conexion) => {
                objeto[conexion.name] = conexion
            });
            return objeto;

        case FETCH_POKEMON:
        return { ...state, ...payload }

        default:
            return state
    }
}

And I will have a bineReducers like this:

export default bineReducers({
    pokemons: pokemonReducers,
});

But I want to have pokemons state for the FETCH_POKEMONS actions and another state called pokemon for the FETCH_POKEMON acton. How can I derivate two states in the bineReducers from one reducer file?

Share Improve this question edited Jul 19, 2019 at 16:52 Dupocas 21.4k7 gold badges41 silver badges57 bronze badges asked Jul 19, 2019 at 16:36 Paul MirandaPaul Miranda 74820 silver badges47 bronze badges 1
  • there shouldn't be a foreach in a reducer. Your forEach should happen in the actionCreator and pass data into the reducer. The reducer should not do a lot of logic. – tcoulson Commented Jul 19, 2019 at 20:44
Add a ment  | 

3 Answers 3

Reset to default 4

This is anti pattern, the closest thing to do here would be export 2 reducers from your file, one for each use case

export const reducer1 = (state = [], { type, payload }) => {
    switch (type) {

        case FETCH_POKEMONS:
            const objeto = {};
            payload.forEach((conexion) => {
                objeto[conexion.name] = conexion
            });
            return objeto;

        default:
            return state
    }
}

export const reducer2 = (state = [], { type, payload }) => {
    switch (type) {

        case FETCH_POKEMON:
            return { ...state, ...payload }

        default:
            return state
    }
}

If I'm understanding your question correctly, you have two actions, FETCH_POKEMONS and FETCH_POKEMON, and you want them to update two different states, pokemons and pokemon, respectively.

  1. If these are separate states that don't affect one-another, you'll want to create 2 reducer functions, which I'll call pokemon and pokemons, which each manage their own state and then pass those reducers into bineReducers to bine them into a single application-level reducer. I think this is more likely what you're looking for.
  2. If they are not separate states but instead interconnected properties, then use a single reducer, and give the state 2 properties, pokemon and pokemons, and only update the property you are trying to update in each action (i.e. leave state.pokemon with its previous value when performing FETCH_POKEMONS.

Your action creator seems fine. I am going to post one of my reducers to show how I do it.

import {ONIX_LOGIN_LOADING,ONIX_LOGIN_SUCCESS,ONIX_LOGIN_FAILURE,
    ONIX_CONNECTIONS_LOADING,ONIX_CONNECTIONS_SUCCESS,ONIX_CONNECTIONS_FAILURE,
    ONIX_PRODUCT_LOADING,ONIX_PRODUCT_SUCCESS,ONIX_PRODUCT_FAILURE
    } from "../actions/onix-actions";

const defaultState = {
    login:[],
    connections: [],
    product: []
};

export default function(state = defaultState, action){
    switch(action.type){
        case ONIX_LOGIN_LOADING:
            return {...state, loginLoading:true};
        case ONIX_LOGIN_FAILURE:
            return {...state, loginLoading:action.isLoaded};
        case ONIX_LOGIN_SUCCESS:
            return {...state, loginLoading:false, login:action.data};
        case ONIX_CONNECTIONS_LOADING:
            return {...state, connectionsLoading:true};
        case ONIX_CONNECTIONS_FAILURE:
            return {...state, connectionsLoading:false};
        case ONIX_CONNECTIONS_SUCCESS:
            return {...state, connectionsLoading:false, connections:action.data};
        case ONIX_PRODUCT_LOADING:
            return {...state, productLoading:true};
        case ONIX_PRODUCT_FAILURE:
            return {...state, productLoading:false, productTitle:false};
        case ONIX_PRODUCT_SUCCESS:
            return {...state, productLoading:false, product:action.data};
    }
    return state
}

I like this format, because I can call my own variables off of the state for that part of my reducer. Then in the bine reducers I have the following:

import books from './books';
import onix from './onix';
const rootReducer = bineReducers({
    books,
    onix
});

export default rootReducer;

Now for all things onix I can call: this.props.onix.login or this.props.onix.productTitle and it will return the data I want for that part of my project. Did that answer your question?

EDIT: Here is the screenshot of my file structure for reducers

本文标签: javascriptCan I have multiple states from one reducer in ReduxStack Overflow