Redux normalize +处理减少的响应
Redux normalizr + dealing with reduced responses
Normalizr非常擅长创建实体的结构化JSON存储库。
我们有许多情况显示数据列表,例如posts
已被规范化。如果列出posts
,则API响应仅限于几个关键字段。
我们也有我们显示这些posts
之一的情况,尽管我们现在需要从API获取完整的JSON实体与所有字段。
如何最好地处理这个问题?
A一个单独的reducer, thunk/saga, selector和actions?
B简单地将从API获取的post
的扩展版本插入到reducer中。重用之前的选择器等?
把应用的状态想象成一个数据库。我建议您使用这个状态形状:
{
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),
});
}
在reducer中,我们需要创建entities
reducer,它将监听所有动作,如果有效载荷中有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;
}
我们还需要创建相应的reducer来处理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;
}
}
我同意你的两个选择,并且会得出相同的结论。但让我们仔细看看它们,看看其中一个比另一个有什么优势:
(B)您可以将post实体(预览和完整表示)合并为您的reducer中的一个实体,但您将跟踪result
数组(预览和完整表示),您将在API请求后从normalizr规范化数据中获得。然后你可以很容易地区分之后,如果你已经有充分的代表性的职位。您的子状态可能如下所示:
const postState = {
// merged results from PREVIEW api
previews: [1, 2, 3],
// merged results from FULL api
full: [2],
// all merged entities
entities: {
1: {
title: 'foo1'
},
2: {
title: 'foo2',
body: 'bar',
},
3: {
title: 'foo3'
}
}
};
(A)您将有两个约简器+动作,每个表示一个,以区分实体。根据PREVIEW或FULL posts API请求,您可以通过一个显式操作来服务您的一个reducer。您的子状态可能如下所示:
const previewPostState = {
// merged results from PREVIEW api
result: [1, 2, 3],
// all preview entities
entities: {
1: {
title: 'foo1'
},
2: {
title: 'foo2',
},
3: {
title: 'foo3'
}
}
};
const fullPostState = {
// merged results from FULL api
result: [2],
// all full entities
entities: {
2: {
title: 'foo2',
body: 'bar'
}
}
};
从一个非常高级的角度来看,您已经可以看到您必须保存重复的信息。具有id: 2
的post实体将使用其title属性保存两次:一次保存previewPostState
,一次保存fullPostState
。一旦你想改变全局状态中的title属性,你必须在两个地方做。这就违背了Redux唯一的真理来源。这就是我选择(B)的原因:您有一个位置用于您的帖子实体,但可以通过结果数组清楚地区分它们的表示。
- IE中的Onload()处理程序没有响应
- 如何使用Redux Thunk处理fetch()响应中的错误
- 是浏览器在AJAX响应中自动处理的HTTP标头
- Masony无法处理ajax响应
- 如何在phonegap应用程序中处理Ajax json响应
- 处理evaluate()中提交的响应
- 嵌套另一个 Ajax 请求时,Ajax 响应处理中断
- 带有响应处理的WSO2ESB(ApacheSynapse)代理
- 如何自动单击 AJAX 响应处理程序中自动生成的链接
- 对 Expressjs / Nodejs 请求 - 响应处理感到困惑
- 将信息传递到 jQuery ajax 响应处理函数中
- JQuery轮询和响应处理
- 改进AJAX响应处理功能
- 聚合铁ajax和异步请求(etag同步和响应处理)
- 如何使用Rhino中的SOAP web服务响应处理ServerSide XSLT
- 在AngularJS中参数化$http响应处理函数
- Backbone.Wreqr 请求-响应处理程序的回调响应/状态(完成后)
- Coffeescript json响应处理
- 我应该把我的响应处理程序代码的AJAX调用在Angular.js
- ajax请求响应处理程序的问题