Подумайте о состоянии приложения как базы данных. Я предлагаю вам использовать эту государственную форму:
{
entities: {
// List of normalized posts without any nesting. No matter whether they have all fields or not.
posts: {
'1': {
id: '1',
title: 'Post 1',
},
'2': {
id: '2',
title: 'Post 2',
}
},
},
// Ids of posts, which need to displayed.
posts: ['1', '2'],
// Id of full post.
post: '2',
}
Прежде всего, мы создаем наши normalizr
схемы:
// schemas.js
import { Schema, arrayOf } from 'normalizr';
const POST = new Schema('post');
const POST_ARRAY = arrayOf(POST);
После ответа успеха, мы нормализации данных ответа и диспетчеризации действия:
// actions.js/sagas.js
function handlePostsResponse(body) {
dispatch({
type: 'FETCH_POSTS',
payload: normalize(body.result, POST_ARRAY),
});
}
function handleFullPostResponse(body) {
dispatch({
type: 'FETCH_FULL_POST',
payload: normalize(body.result, POST),
});
}
В редукторах нам необходимо создать редуктор entities
, который будет прослушивать все действия, и если у него есть entities
ключ на оплату нагрузка будет добавить эти объекты в состояние приложения:
// reducers.js
import merge from 'lodash/merge';
function entities(state = {}, action) {
const payload = action.payload;
if (payload && payload.entities) {
return merge({}, state, payload.entities);
}
return state;
}
Кроме того, мы должны создать соответствующие редукторы для обработки FETCH_BOARDS
и FETCH_FULL_BOARD
действия:
// Posts reducer will be storing only posts ids.
function posts(state = [], action) {
switch (action.type) {
case 'FETCH_POSTS':
// Post id is stored in `result` variable of normalizr output.
return [...state, action.payload.result];
default:
return state;
}
}
// Post reducer will be storing current post id.
// Further, you can replace `state` variable by object and store `isFetching` and other variables.
function post(state = null, action) {
switch (action.type) {
case 'FETCH_FULL_POST':
return action.payload.id;
default:
return state;
}
}
У меня вопрос: «Слияние ({}, state, payload.entities);« мутировать состояние? – Daskus
@Daskus Нет, поскольку мы передаем пустой объект в качестве первого аргумента, функция 'merge' вернет новый объект. – 1ven
Это, безусловно, лучший ответ, мы в конечном итоге пошли именно на этот подход. ключ заключается в написании хороших селекторов и фильтров. Также настоятельно рекомендуем использовать Immutable JS ...! – AndrewMcLagan