如何在读取数据时在React Redux应用程序中显示加载指示器?
我是React / Redux的新手。 我在Redux应用程序中使用fetch api中间件来处理这些API。 它是https://github.com/agraboso/redux-api-middleware。 我认为这是处理异步API行为的好方法。 但是我发现了一些我自己无法解决的情况。
正如主页https://github.com/agraboso/redux-api-middleware#lifecycle所言,抓取API生命周期始于调度CALL_API操作,并以调度FSA操作结束。
所以我的第一个案例是在提取API时显示/隐藏预加载器。 中间件将在开始时发送FSA操作并在最后发送FSA操作。 这两个操作都是由reducer接收的,应该只是进行一些正常的数据处理。 没有UI操作,没有更多的操作。 也许我应该保存状态的处理状态,然后在商店更新时渲染它们。
但如何做到这一点? 一个反应组件在整个页面上流动? 从其他操作更新商店会发生什么? 我的意思是他们更像事件而不是国家!
即使是更糟糕的情况,当我必须使用redux / react应用程序中的本机确认对话框或警报对话框时,我应该怎么做? 他们应该放在哪里,行动还是减少?
最好的祝愿! 希望回复。
我的意思是他们更像事件而不是国家!
我不会这么说。 我认为加载指标是UI的一个很好的例子,很容易描述为状态的函数:在这种情况下,是一个布尔变量。 虽然这个答案是正确的,但我想提供一些代码以配合它。
在Redux repo的async
示例中,reducer更新一个名为isFetching
的字段:
case REQUEST_POSTS:
return Object.assign({}, state, {
isFetching: true,
didInvalidate: false
})
case RECEIVE_POSTS:
return Object.assign({}, state, {
isFetching: false,
didInvalidate: false,
items: action.posts,
lastUpdated: action.receivedAt
该组件使用React Redux中的connect()
来订阅商店的状态,并返回isFetching
作为mapStateToProps()
返回值的一部分,以便它可以在连接组件的道具中使用:
function mapStateToProps(state) {
const { selectedReddit, postsByReddit } = state
const {
isFetching,
lastUpdated,
items: posts
} = postsByReddit[selectedReddit] || {
isFetching: true,
items: []
}
return {
selectedReddit,
posts,
isFetching,
lastUpdated
}
}
最后,组件在render()
函数中使用isFetching
prop来呈现“加载...”标签(可以想象它是一个微调器):
{isEmpty
? (isFetching ? <h2>Loading...</h2> : <h2>Empty.</h2>)
: <div style={{ opacity: isFetching ? 0.5 : 1 }}>
<Posts posts={posts} />
</div>
}
即使是更糟糕的情况,当我必须使用redux / react应用程序中的本机确认对话框或警报对话框时,我应该怎么做? 他们应该放在哪里,行动还是减少?
任何副作用(并且显示对话肯定是副作用)不属于还原剂。 将减速器视为被动的“国家建设者”。 他们并不真正“做”事情。
如果您希望显示警报,请在分派动作之前从组件执行此操作,或者从动作创建者执行此操作。 在发布行动的时候,为响应它而执行副作用为时已晚。
对于每一条规则,都有一个例外。 有时候你的副作用逻辑如此复杂,你实际上想要将它们耦合到特定的动作类型或特定的缩减器。 在这种情况下,请查看Redux Saga和Redux Loop等高级项目。 只有当你对香草Redux感到舒适时才能做到这一点,并有一个真正的问题,你想要更容易管理的零散副作用。
很好的答案丹阿布拉莫夫! 只是想补充一点,我在我的一个应用程序中做了或多或少的事情(保持为一个布尔值),最后不得不使其成为一个整数(最终读取的未完成请求数),以支持多个同时要求。
用布尔值:
请求1开始 - >微调开启 - >请求2开始 - >请求1结束 - >微调关闭 - >请求2结束
与整数:
请求1开始 - >微调开启 - >请求2开始 - >请求1结束 - >请求2结束 - >微调关闭
case REQUEST_POSTS:
return Object.assign({}, state, {
isFetching: state.isFetching + 1,
didInvalidate: false
})
case RECEIVE_POSTS:
return Object.assign({}, state, {
isFetching: state.isFetching - 1,
didInvalidate: false,
items: action.posts,
lastUpdated: action.receivedAt
我想补充一些东西。 现实世界中的示例使用商店中的字段isFetching
来表示何时获取项目集合。 任何集合都可以推广到pagination
器,它可以连接到组件以跟踪状态并显示集合是否正在加载。
我碰巧想要获取不适合分页模式的特定实体的详细信息。 我想拥有一个状态来表示是否从服务器获取细节,但我也不想只为此使用reducer。
为了解决这个问题,我添加了另一个通用缩减器,名为fetching
它的工作方式与分页缩减器类似,只是监视一组操作并生成新的状态[entity, isFetching]
。 这允许connect
reducer connect
到任何组件,并知道该应用程序当前是否正在提取数据,而不仅仅是针对集合,而是针对特定实体。
上一篇: How to show a loading indicator in React Redux app while fetching the data?