#javascript #zustand
Вопрос:
Я хотел бы разбить свое состояние zustand на более мелкие повторно используемые объекты; но все документированные шаблоны zustand, похоже, предполагают продвижение операций до объекта хранилища верхнего уровня. Есть ли способ разрешить мутации внутренних объектов, не обязательно повторяя каждую операцию для каждого объекта?
В качестве примера предположим, что у нас есть объект транспортного средства:
function makeVehicle() {
return { going: false };
}
function startVehicle(vehicle) {
return { ...vehicle, going: true };
}
function stopVehicle(vehicle) {
return { ...vehicle, going: false };
}
У меня может быть состояние, содержащее два названных транспортных средства
import { create } from 'zustand';
export default create(set => {
blueVehicle: makeVehicle(),
greenVehicle: makeVehicle()
});
Но, похоже, что если я хочу также экспортировать мутаторы, мне нужно повторить каждую операцию для каждого объекта с изрядным количеством шаблонов:
import { create } from 'zustand';
export default create(set => {
blueVehicle: makeVehicle(),
startBlueVehicle: () => set(
state => ({ blueVehicle: startVehicle(state.blueVehicle) })
),
stopBlueVehicle: () => set(
state => ({ blueVehicle: stopVehicle(state.blueVehicle) })
),
greenVehicle: makeVehicle(),
startGreenVehicle: () => set(
state => ({ greenVehicle: startVehicle(state.greenVehicle) })
),
stopGreenVehicle: () => set(
state => ({ greenVehicle: stopVehicle(state.greenVehicle) })
)
});
Есть ли более простой способ выразить это?
Ответ №1:
Для этого конкретного примера я бы структурировал исходное состояние следующим образом:
import { create } from 'zustand';
export default create(set => {
blueVehicle: makeVehicle(),
greenVehicle: makeVehicle(),
startVehicleByName: (vehicleName) => set(
state => ({ [vehicleName]: startVehicle(state[vehicleName]) })
),
stopVehicleByName: (vehicleName) => set(
state => ({ [vehicleName]: stopVehicle(state[vehicleName]) })
)
});
Таким образом, если вы хотите завести синий автомобиль, вы можете позвонить startVehicleByName('blueVehicle')
Или, если вы хотите остановить зеленый автомобиль, вы можете позвонить stopVehicleByName('greenVehicle')
Как указано в readme zustand, вы можете разместить в магазине все, что угодно. Таким образом, нет ничего плохого в том, чтобы поместить в него функции с (потенциально любым количеством) параметров.
Одним из самых больших преимуществ zustand (по крайней мере, для меня) является то, сколько свободы он предоставляет. Он не является открытым, поэтому вы можете реализовать там надежные шаблоны потоков, если они вам нужны, или отказаться от него и сделать его менее шаблонным для более простых приложений (или частей приложений).