'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 |
