'Multiple reducers interactions

I need advice on organizing the interaction of reducers, in my project I can't combine two reducers into one. I wrote a small example in which reducers interact through a component. Is it possible to somehow call sliceCounter.caseReducers.decrement() or sliceCounter.caseReducers.increment() from fetchAsyncCounter.fulfilled which is processed in sliceExtra reducer, i.e. without using the component.

I assume that the "thunk" functions or CombineReducers will help me solve the problem, but I can't figure out how to write the code correctly yet.

This code

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { fetchAsyncCounter, selectType } from "./sliceExtra";
import { increment, decrement, selectCount } from "./slice";

export default () => {
  const counterValue = useSelector(selectCount);
  const counterType = useSelector(selectType);
  const dispatch = useDispatch();
  React.useEffect(() => {
    if (counterType.payload === "plus") {
      dispatch(increment());
    } else if (counterType.payload === "minus") {
      dispatch(decrement());
    }
  }, [counterType, dispatch]);
  return (
    <div>
      <div className="counterValuePrint">{counterValue}</div>
      <button onClick={() => dispatch(fetchAsyncCounter("plus"))}>
        Increase
      </button>
      <button onClick={() => dispatch(fetchAsyncCounter("minus"))}>
        Decrease
      </button>
    </div>
  );
};

should turn into this code

import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { fetchAsyncCounter } from "./sliceExtra";
import {  selectCount } from "./slice";

export default () => {
  const counterValue = useSelector(selectCount);

  const dispatch = useDispatch();

  return (
    <div>
      <div className="counterValuePrint">{counterValue}</div>
      <button onClick={() => dispatch(fetchAsyncCounter("plus"))}>
        Increase
      </button>
      <button onClick={() => dispatch(fetchAsyncCounter("minus"))}>
        Decrease
      </button>
    </div>
  );
};


Solution 1:[1]

I came up with this option using store.subscribe, see the example

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./features/counter/slice";
import extraReducer from "./features/counter/sliceExtra";
import App from "./App";

const store = configureStore({
  reducer: {
    counter: counterReducer,
    extra: extraReducer
  }
});

function select(state) {
  return state.extra.operation;
}

let currentState;
function handleChange() {
  let previousState = currentState;
  currentState = select(store.getState());

  if (previousState !== currentState) {
    if (currentState.payload === "plus") {
      store.dispatch({ type: "counter/increment" });
    } else if (currentState.payload === "minus") {
      store.dispatch({ type: "counter/decrement" });
    }
  }
}

store.subscribe(handleChange);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 i like Cola