1

Help me, please. I have got 2 reducers created with createSlice method of redux/toolkit.

user.reducer.js

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
    id: 123,
    name: 'Owner123',
    cats: [],
};

const reducer = createSlice({
    name: 'user',
    initialState,
    reducers: {
        addCat: (state, action) => {
            state = {
                ...state,
                cats: [...state.cats, action.payload],
            };

            return state;
        },
        feedCat: (state, action) => {
            // call eat method from catReducer
        },
    },
});

export const { addCat, feedCat } = reducer.actions;
export const userReducer = reducer.reducer;

cat.reducer.js

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
    id: null,
    name: null,
    age: null,
    color: null,
    foodLevel: null,
    healthLevel: null,
    weight: null,
};

const reducer = createSlice({
    name: 'cat',
    initialState,
    reducers: {
        createCat: (
            state,
            {
                payload: {
                    id,
                    name,
                    age,
                    color,
                    foodLevel,
                    healthLevel,
                    weight,
                },
            }
        ) => {
            state = {
                id: id,
                name,
                age,
                color,
                foodLevel,
                healthLevel,
                weight,
            };

            return state;
        },
        eat: (state, action) => {
            console.log('hello from cat');
        },
    },
});

export const { createCat, eat } = reducer.actions;
export const catReducer = reducer.reducer;

My question is: How can I call a method from cat reducer within user reducer?

I have already tried some guides from StackOverflow like catReducer.caseReducers.eat(), but it does not work.

  • 1
    It looks like you're misunderstanding how redux works. You don't call reducers directly, you dispatch actions which trigger reducers. I would need to know more about what you're trying to achieve to be able to help you. – wvdz Oct 09 '21 at 18:35
  • @wvdz, I am new in redux. What I want to do: I have Button Feed cat, which will dispatch feed action in user reducer, and it will trigger eat method from cat reducer. How can I call this trigger eat() in the user reducer from cat reducer? – Evgenii Komornyi Oct 09 '21 at 18:41
  • @wvdz, Every cat has got ID, user has got cats array. Feed button onClick event will pass Id cat, which will dispatch feed action in user reducer, which will find the cat by this ID and will call eat method from cat reducer. – Evgenii Komornyi Oct 09 '21 at 18:50
  • If you're in the same slice you could do this https://stackoverflow.com/a/63564625/5420070 or if you're in different slice, you can make use of `extraReducers` or redux toolkit – Md. A. Apu Aug 05 '22 at 16:36

2 Answers2

0

Doing that is an antipattern.

Check this question's anwer for the right way of achieving the desired outcome.

It refers to the usage of either of these libs:

  • redux-logic
  • redux-saga
  • redux-observable
  • redux-thunk
til
  • 832
  • 11
  • 27
-1

What you describe is not possible, but what you can do, is create a reducer on cat, which triggers on an action defined in user.

You can do this by using extraReducers on cat. It allows you to define a reducer that does not generate an action, but acts on an existing action that you import.

From the docs: https://redux-toolkit.js.org/api/createslice#extrareducers

One of the key concepts of Redux is that each slice reducer "owns" its slice of state, and that many slice reducers can independently respond to the same action type. extraReducers allows createSlice to respond to other action types besides the types it has generated.

As case reducers specified with extraReducers are meant to reference "external" actions, they will not have actions generated in slice.actions.

wvdz
  • 16,251
  • 4
  • 53
  • 90