REDUX без тщетных попыток притвориться иммутабельным

Чтобы библиотека REDUX работала корректно, она должен возвращать копии своего состояния. В этом плане js слабо помогает ей решать задачу генерации нового объекта из старого. И приходится писать “псевдо иммутабельный” и на мой взляд хрупкий код типа такого:

Плюс такой код неудобно типизировать в тайпскрипте (который является моим выбором по умолчанию для nodejs/frontend проектов).

Сегодня узнал о нормальной абстракции для описания мутаций REDUX стора. Сравни подход с чистым REDUX

// Redux reducer
// Shortened, based on: https://github.com/reactjs/redux/blob/master/examples/shopping-cart/src/reducers/products.js
const byId = (state, action) => {
	switch (action.type) {
		case RECEIVE_PRODUCTS:
			return {
				...state,
				...action.products.reduce((obj, product) => {
					obj[product.id] = product
					return obj
				}, {})
			}
		default:
			return state
	}
}

и библиотекой immer

import produce from "immer"

const byId = (state, action) =>
	produce(state, draft => {
		switch (action.type) {
			case RECEIVE_PRODUCTS:
				action.products.forEach(product => {
					draft[product.id] = product
				})
		}
	})

Что выдает на выходе простой код (почти такой же простой как mobx). С легкой типизацией. И без необходимости менять низлежащую библиотеку менеджмента состояния.


Статья в рамках рубрики “Today I Learned