Avoiding Pitfalls with Reducers in Real-Time Applications
Provide an example of a reducer that could lead to memory leaks within a real-time GPS tracking application, and refactor it for better performance using `createReducer`.
// Reducer with a potential memory leak for real-time GPS tracking
// This reducer improperly creates a new array with spread operator at every call,
// which can lead to excessive memory usage in a real-time application
const gpsReducerWithLeak = (state = { locations: [] }, action) => {
switch (action.type) {
case 'ADD_LOCATION':
// ❌ Could cause memory issues by always creating new references
return { ...state, locations: [...state.locations, action.location] };
default:
return state;
}
};
This code defines a reducer that handles GPS location updates and illustrates a potential memory leak by always creating new arrays for locations.
// Import Redux Toolkit's createReducer
import { createReducer } from '@reduxjs/toolkit';
// Refactored reducer using createReducer to handle updates immutably with better performance
const gpsReducer = createReducer({ locations: [] }, {
'ADD_LOCATION': (state, action) => {
// ✅ Immer's produce allows us to write seemingly mutable code
// that gets converted to immutable updates under the hood
state.locations.push(action.location);
}
});
This refactored code uses Redux Toolkit's createReducer function to define a reducer that handles immutable updates under the hood by leveraging the Immer library, resulting in better performance and avoiding memory leaks.