Избегайте дублирования вложенных объектов в избыточном хранилище
Я даю попробовать redux-orm, и из того, что я могу собрать, redux-orm создает объект в хранилище, ключом которого является значение, указанное через Model.name
для каждой зарегистрированной модели.
Итак, для создания моего редуктора "сущностей" я использую объединение Reducers, передавая редукторы для всех моих сущностей, например:
import { combineReducers } from 'redux';
import City from './cityReducer';
import Poi from './pointOfInterestReducer';
const entitiesReducer = combineReducers({
City,
Poi
});
export default entitiesReducer;
И, наконец, вот как я создаю свой rootReducer
также используя combineReducers
:
Проблема в том, что,я думаю, что с помощью combineReducers
Я дублирую ключи в моем магазине, как показано здесь:
Есть ли у вас какие-либо идеи, как мне этого избежать, и чтобы все мои модели были прямыми потомками "сущностей"?
Что-то вроде entities>City
и не entities>City>City
Изменить: cityReducer.js
import orm from './../../orm/orm';
import * as types from '../../actions/actionTypes';
const loadCities = (state, action) => {
// Create a Redux-ORM session from our entities "tables"
const session = orm.session(state);
// Get a reference to the correct version of model classes for this Session
const { City } = session;
const { cities } = action.payload;
// Clear out any existing models from state so that we can avoid
// conflicts from the new data coming in if data is reloaded
City.all().toModelArray().forEach(city => city.delete());
// Immutably update the session state as we insert items
cities.forEach(city => City.parse(city));
return session.state;
};
const updateCity = (state, payload) => {
const { id, newItemAttributes } = payload;
const session = orm.session(state);
const { City } = session;
if (City.hasId(id)) {
const modelInstance = City.withId(id);
modelInstance.update(newItemAttributes);
}
return session.state;
};
const deleteCity = (state, payload) => {
const { id } = payload;
const session = orm.session(state);
const { City } = session;
if (City.hasId(id)) {
const modelInstance = City.withId(id);
// The session will immutably update its state reference
modelInstance.delete();
}
return session.state;
};
const createCity = (state, payload) => {
const { city } = payload;
const session = orm.session(state);
const { City } = session;
City.parse(city);
return session.state;
};
const citiesReducer = (dbState, action) => {
const session = orm.session(dbState);
switch (action.type) {
case types.LOAD_CITIES_SUCCESS: return loadCities(dbState, action);
case types.CREATE_CITY_SUCCESS: return createCity(dbState, action);
case types.UPDATE_CITY_SUCCESS: return updateCity(dbState, action);
case types.DELETE_CITY_SUCCESS: return deleteCity(dbState, action);
default: return session.state;
}
};
export default citiesReducer;
1 ответ
Существует два способа использования Redux-ORM для определения его структуры "таблиц" и написания логики редуктора для использования этих таблиц. Я привел примеры обоих подходов в своих сообщениях в блоге Практическое Redux, Часть 1. Основы Redux-ORM, Практическое Redux, Часть 2. Концепции и методы Redux-ORM, и Практическое Redux, Часть 5. Загрузка и отображение данных. (Обратите внимание, что эти публикации посвящены использованию Redux-ORM 0.8, а версия 0.9 имеет некоторые изменения API. Я перечислил эти изменения в Practical Redux, часть 9.)
Первый подход состоит в том, чтобы написать свою логику редуктора, привязанную к классам модели, и использовать Redux-ORM. ORM
экземпляр для создания редуктора, который создает "таблицы" и управляет ими для вас. В соответствии с примером на репозитории Redux-ORM:
import {createReducer} from "redux-orm";
import {orm} from "./models";
const rootReducer = combineReducers({
entities: createReducer(orm)
});
Другой подход заключается в написании вашей собственной функции, которая создает начальное состояние, и, возможно, других функций, которые обрабатывают обновление:
import {orm} from "./models";
const initialState = orm.getEmptyState();
export default function entitiesReducer(state = initialState, action) {
// handle other actions here if desired
return state;
}
Другими словами, не определяйте отдельные "таблицы" для каждого типа модели самостоятельно. Позвольте Redux-ORM определять их либо автоматически в своем собственном редукторе, либо используя его для генерации начального состояния для вашего редуктора сущностей.