Reputation:
I have a small problem with Redux in my state I need to be able to modify my counter property in two Reducers as it's value update to both reducers (INCREMENT, DECREMENT) sorry am new to Redux and try to understand this concept.
Counter Component
return(
<>
<div className="flex justify-center">
<div className='font-bold text-4xl text-blue-600 bg-gray-300 p-6 m-3 rounded-full'>The Result :
{this.props.counter}
</div>
</div>
<section className='flex p-5 m-3 justify-center'>
<button onClick={this.props.increment} className={`bg-green-400 ${btnDefault}`} >Increment</button>
<button onClick={() => this.props.decrement(this.props.counter)} className={`bg-red-400 ${btnDefault}`}>Decrement</button>
</section>
</>
)
}
}
const mapStateToProps = state => {
return {
counter: state.incReducer.counter,
}
};
const mapDispatchToProps = dispatch => {
return {
increment: () => dispatch(counterAction('INCREMENT')),
decrement: (counter) => dispatch(counterAction('DECREMENT',counter))
}
};
export default connect(mapStateToProps, mapDispatchToProps)(Counter)
Increment Reducer
const initialState = {
counter: 0,
};
const reducer = (state = initialState, action) => action.type === actionType.INCREMENT ?
{
...state,
counter: state.counter + 1
}
: state;
export default reducer;
Decrement Reducer
const initState = {
};
const reducer = (state = initState, action) => action.type === actionType.DECREMENT ?
{
...state,
counter: action.counter - 1
}
: state;
export default reducer;
Index.js
const reducer = combineReducers({
incReducer,
decReducer
});
const store = createStore(reducer);
ReactDOM.render(<Provider store={store}><App/></Provider> , document.getElementById('root'));
Upvotes: 2
Views: 1157
Reputation: 64687
You're just approaching it from the wrong angle, you should never have the same variable being modified in two reducers, you instead want to have a single counterReducer
that handles all actions that modify the counter:
const initialState = {
counter: 0,
};
const reducer = (state = initialState, action) => {
switch(action.type) {
case actionType.INCREMENT:
return {
...state,
counter: state.counter + 1
};
break;
case actionType.DECREMENT:
return {
...state,
counter: state.counter - 1
}
break;
default:
return state;
}
}
export default reducer;
Splitting into multiple reducers is a way to keep your code organized, but you'd never have two reducers that could each modify the same thing. Each reducer should instead handle a certain "section" of your overall state, e.g.
const totalState = {
activeUser: { /* username, email, phone, etc */ },
friends: [],
subscriptions: [],
history: [],
// etc.
}
you might then have an activeUserReducer
, friendsReducer
, subscriptonsReducer
, historyReducer
, etc. And each one would handle that portion of the state, but would never reach into another reducers state.
If you need to modify two different properties with a single action, you would just do:
const mapDispatchToProps = dispatch => {
return {
increment: () => {
dispatch(counterAction('INCREMENT'));
dispatch(someOtherAction());
}
};
};
Upvotes: 1