3

So, I'm trying to use some piece of state from one reducer in another reducer, and I looked for a solution and seems the package reduce-reducers does exactly that, buth here's my question ...

I have the following rootReducer.js file where I import all my reducers and combine them with combineReducers like this ...

import { combineReducers } from "redux";
import globalReducer from "./globalReducer";
import booksReducer from "../features/books/booksReducer";
import categriesReducer from "../features/categories/categoriesReducer";
import authorsReducer from "../features/authors/authorsReducer";

const rootReducer = combineReducers({
    global: globalReducer,
    books: booksReducer,
    categories: categriesReducer,
    authors: authorsReducer
});

export default rootReducer;

Now I want to use some state from the authors reducer in the books reducer, how can I achieve that with reduce-reducers package?

iofjuupasli
  • 3,818
  • 1
  • 16
  • 17
Ruby
  • 2,207
  • 12
  • 42
  • 71
  • Does this answer your question? [correct usage of reduce-reducers](https://stackoverflow.com/questions/38652789/correct-usage-of-reduce-reducers) – challet Dec 23 '19 at 12:12

1 Answers1

2

reduce-reducers works like "merge" of reducers:

const reducer = (state = 0, action) => {
    switch (action.type) {
        case 'ADD':
            return state + action.value;
        case 'MULTIPLE':
            return state * action.value;
        default:
            return state;
    }
};

The same can be written with reduce-reducers:

const addReducer = (state = 0, action) => {
    switch (action.type) {
        case 'ADD':
            return state + action.value;
        default:
            return state;
    }
};
const multipleReducer = (state = 0, action) => {
    switch (action.type) {
        case 'MULTIPLE':
            return state * action.value;
        default:
            return state;
    }
};

const reducer = reduceReducers(addReducer, multipleReducer, 0);

So on your task, it means, that you should rewrite your authorsReducer and booksReducer so it gets entire state as first argument, not only its own authors part:

const before = (state = [], action) => {
    switch (action.type) {
        case `NEW_BOOK`:
            return state.concat([action.book]);
        default:
            return state;
    }
}

const now = (state = {}, action) => {
    switch (action.type) {
        case `NEW_BOOK`:
            return {
                ...state,
                books: state.books.concat([action.book]),
            };
        default:
            return state;
    }
}

BUT! I think this is not what you're actually want.

There is another package that does exactly what you need combine-section-reducers

It allows you to access root state from any other reducer:

const before = (state = [], action) => {
    switch (action.type) {
        case `NEW_BOOK`:
            return state.concat([action.book]);
        default:
            return state;
    }
}

const now = (state = [], action, rootState) => {
    switch (action.type) {
        case `NEW_BOOK`:
            return state.concat([{
                ...action.book,
                author: rootState.authors[action.book.authorId],
            }]);
        default:
            return state;
    }
}
iofjuupasli
  • 3,818
  • 1
  • 16
  • 17
  • I can't really wrap my head around it, could you please add to the code I posted to show how it would look after using combine-section-reducers? – Ruby Oct 24 '18 at 12:37