45
Event Driven Architecture for Redux
This article elaborates one of the Redux best practices. This best practice has helped me a ton in writing better code and avoiding problems. Many thanks to the Redux team!
Redux provides powerful way to store state data for client-side applications. Any part of application can send data, through actions, to be stored in redux then data becomes available to entire application.

However, with great power comes great responsibilities! Poorly designed actions/reducers give away most of redux advantages, and application becomes difficult to understand and debug. While well designed actions/reducers helps in keeping the store logic maintainable and scalable.
We have been told that storage is cheap. However, we still cannot store everything. Additionally, memory is actually very expensive.
While designing data storage systems we need to be mindful of what data is worth storing to solve our problems. Generally relevant events result in creation of valuable data. While absence of events does not generate any useful data.
While designing data storage systems we need to be mindful of what data is worth storing to solve our problems. Generally relevant events result in creation of valuable data. While absence of events does not generate any useful data.
Example: There is no point in keep recording footages of a football stadium when no game is being played.
Similarly, in the world of client-side applications. Useful data, which is required throughout a session of application, is generated when events (user, Web-API, Web-Sockets, etc.) occur. Therefore, designing state tracking system based out of important events result in more maintainable, intuitive, and scalable system.
This a very prevalent approach in many redux applications. Developers create many actions to set state in redux store.

This architecture results in following problems:
Objective: For a food ordering application:
For setter actions: reducer logic look like (1) and action creators like (2)
const orderSlice = createSlice({
name: "order",
initialState: { pizzaOrdered: 0, cokeOrdered: 0 },
reducers: { // (1) Reducer logic
setPizzaOrdered: (state, action) => {
state.pizzaOrdered = action.payload;
},
setCokeOrdered: (state, action) => {
state.cokeOrdered = action.payload;
}
}
});
const {
actions: { setPizzaOrdered, setCokeOrdered }, // (2) Action creators
reducer: orderReducer
} = orderSlice;
Send order event handler looks like (3)
const sendOrder = () => { // (3) Send Order event handler
dispatch(setPizzaOrdered(pizza));
dispatch(setCokeOrdered(coke));
};
(3) is another bad practice
And action log looks like (4)

In sizable application setters action log explodes
Problem 1: Adding fries to menu
Problem 2: Removing coke from menu
Deriving actions/reducers based out of application events improves the design of redux store significantly. Primarily, due to the fact that data worth storing originates from events.

This architecture has following advantages:
Play around with code here.
For food order example: reducer logic looks like (5) and action creator looks like (6)
const orderSlice = createSlice({
name: "order",
initialState: { pizzaOrdered: 0, cokeOrdered: 0 },
reducers: { // (5) Reducer logic
orderPlaced: (state, action) => {
state.pizzaOrdered = action.payload.pizza;
state.cokeOrdered = action.payload.coke;
}
}
});
const {
actions: { orderPlaced }, // (6) Action creator
reducer: orderReducer
} = orderSlice;
Send order event handler looks like (7)
const sendOrder = () => { // (7) Send Order event handler
dispatch(orderPlaced({pizza, coke}));
};
And action log looks like (8)

Problem 1: Adding fries to menu
Problem 2: Removing coke from menu
When I started using redux I used to create setter type actions. Upon reading this best practice I had following apprehensions:
Resolution: Actions are only required when events, important to the application, occur.
Resolution: Setters are actually tedious because you need to import actions, add them in event handlers and update reducers per changing logic. Managing state changes in event based reducer is easier because you only need to adjust reducer logic and payload.
45