javascript - redux 中的本质扩展
问题描述
我的状态如下所示:
state = {
entities: {
users: {},
articles: {},
},
pagination: {
articlesByUser: {
1: { // userId = 1
isFetching: true,
ids: [],
},
2: { // userId = 2
isFetching: true,
ids: [],
},
},
},
}
它适用于带有列表的页面,但文章模型因index
路线和路线而异get
。
index
路线回复:
$ curl http://api//articles
[{
"id": 0,
"user_id": 0,
"title": "...",
"short_description": "...",
...
}
...
]
get
路线回复:
$ curl http://api//articles/0
{
"id": 0,
"user_id": 0,
"title": "...",
"body": "...",
"meta": {...},
"view_count": 100,
...
}
实体不同。GetModel
请求扩展IndexModel
。因此pagination
reducer 的状态应该是这样的:
pagination: {
articlesByUser: {
1: { // userId = 1
isFetching: true,
ids: [],
},
2: { // userId = 2
isFetching: true,
ids: [],
},
...
},
articleByArticleId: {
1: { // articleId = 1
isFetching: true,
},
...
}
},
在这种情况下,如何更好地构造减速器以处理一篇和多篇文章的pagination
加载状态( )?isFetching = true
解决方案
我不知道您对模型的引用是什么意思;我的假设是您在谈论后端的模型,但这并不会真正影响我们,所以我将忽略它们。
在 Redux 中使用操作来获取和格式化数据
让我们从这个声明开始:
它适用于带有列表的页面,但文章模型对于索引路由和获取路由不同
这其实无所谓!路线之间的数据不同是可以的(即使它不理想)。
我不知道您目前在哪里处理您的 API 请求,但我建议将它们放入 Redux Actions。使用中间件Redux Thunk,我们可以在我们的动作创建者中拥有功能。action 的一部分工作是为 reducer 准备数据。这意味着我们可以在 action 中使用函数来格式化数据,这样当它到达 reducer 时它总是一样的。这意味着我们不需要编写许多类似的 reducer 来处理相同的实体类型,保持 DRY 并使其更易于维护。
在这种情况下,我将执行三个操作:
getAllArticles()
getArticlesById(id)
putArticles(articles)
两个获取文章操作将负责发出请求、格式化数据。然后他们获取这些数据并将其传递给putArticles
实际调度减速器正在侦听的操作。
你的方法看起来像这样:
const getAllArticles = () => {
return (dispatch, getState) => {
fetch(yourRoute).then((json) => {
const formattedData = json // format/normalize your data here
dispatch(putArticles(formattedData))
}
}
}
const getArticleById = (id) => {
return (dispatch, getState) => {
fetch(yourRoute + id).then((json) => {
const formattedData = json // format/normalize your data here
dispatch(putArticles(formattedData))
}
}
}
const putArticles = (articles) => {
return {
type: 'PUT_ARTICLES',
payload: {articles}
}
}
规范化数据
我要看的下一步是规范化您的数据。实际上,您在拆分实体并将分页信息与实际实体列表分开方面做得很好。
我会按实体类型分解您的商店。
state = {
articles: {
entities: { /* each article by ID */},
result: [/* array of ID, primary used for looping */],
pagination: { /* various pagination methods */ }
},
...
}
规范化数据可以防止您形成嵌套的资源列表(例如文章 > 用户 > 评论)。您已经完成了很多工作,使用Normalizr之类的库对其进行形式化将允许您标准化处理数据的方式。
我会将分页移动到单个实体(用户、文章)中。这样可以使事物按其类型整齐地分开,并防止拥有大量不相关的数据。
深入研究整个标准化超出了 SO 问题的范围,但请查看以下两个链接:
推荐阅读
- go - Gin-Gonic 中间件声明
- php - 在php和namevalue中显示最小值和最大值mysql?
- python - 如何将 Python RQ worker 连接到 unix 套接字上的 redis 服务器?
- javascript - 尝试将字符串分解为数组时 str.match 不起作用
- mongodb - 在 Mongodb 投影中使用 toString()
- php - laravel 5.6 中的 Response() 查找文件夹
- python - Python 函数和 TKinter GUI 的正确绑定有问题
- c++ - decltype 的参数不正确
- mysql - Spark - 通过 Zeppelin EMR 连接到 mysql
- javafx - JavaFX CSS 两像素边框