在 react-redux 应用程序中获取详细 api 数据的良好做法

Posted

技术标签:

【中文标题】在 react-redux 应用程序中获取详细 api 数据的良好做法【英文标题】:Good practice to fetch detail api data in react-redux app 【发布时间】:2018-01-28 15:44:10 【问题描述】:

当您处理多个主详细信息视图时,在 React 应用中获取详细信息数据的最佳做法是什么?

例如,如果您有 - /rest/departments api 返回部门列表 - /rest/departments/:departmentId/employees api 返回部门内的所有员工。

要获取我使用的所有部门:

componentDidMount() 
  this.props.dispatch(fetchDepartments());

但随后需要一个逻辑来获取每个部门的所有员工。在部门缩减器逻辑中为每个部门调用员工操作创建者是个好主意吗?

在我看来,在渲染方法中调度员工操作不是一个好主意。

【问题讨论】:

部门列表和明细可以用两种不同的路由渲染? 您可以在商店中存储某种活动部门,以便动态创建新请求,例如activeDepartment:"sales"。然后在一般员工减速器中使用它:this.props.getEmployees(this.props.activeDepartment)。这就是我会尝试的 【参考方案1】:

在部门 reducer 中调用员工操作创建者当然是个坏主意,因为 reducer 应该是纯函数;您应该在您的 fetchDepartments 操作创建器中执行此操作。

无论如何,如果您需要获取每个部门的所有员工(不仅仅是选定的部门),那么进行多次 API 调用并不理想:如果可能,我会要求后端开发人员有一个返回的端点部门数组,以及每个部门的嵌入式员工数组,当然如果数字不是太大的话......

【讨论】:

【参考方案2】:

老大“看情况”

最终,您需要选择一种方法,看看它如何满足您的特定数据和用户需求。这在某种程度上也解决了网络问题,例如延迟。在一个非常好的网络环境中,比如我担任网络管理员的前三名保险公司,你可以实现超低延迟的网络调用。在这种情况下,多个网络请求将与基于互联网的房主环境有很大不同。即便如此,您也必须考虑各种可能性。你总是需要考虑你的最终目标。

(不要在技术方面太过分,但延迟可以相当准确地定义为“您等待网络请求实际开始发送数据的时间”。这可能很重要的一个经典示例是在线第一人称射击游戏。您单击射击,由于网络正在等待发送数据,因此数据传输速度不如您希望的那样快,然后您就死了。带宽比延迟更有用的经典示例是下载或上传大量文件。如果您必须等待一两秒钟才能移动实际数据,但是当它移动时,您可以在几秒钟内下载一个 GB,那么好吧,我会接受它。)

目前,我的网站多次调用以加载动态菜单和动态内容。这是非常小的数据。它在三个单独的调用中完成。在互联网上。它“好”,但我不会说它“好”。由于用户正在等待所有这些都开始,所以我不妨将它们全部放在一个网络调用中。此外,如果两个调用都正常,那么第三个调用有点阻塞,用户可能会开始导航,然后会弹出更多菜单,这并不理想。这就是为什么无论如何,您都必须考虑您的特定需求,以及可能适用的可能用例范围。 (我目前正在重写整个网站)

正如之前(我认为“好”)的回答所说,一口气将整个数据集拍摄给您可能是有意义的。在我看来,这是一个内部应用程序,或者至少是商业应用程序,具有良好的网络,更重要的是,没有因为您的东西加载速度不快而失去客户的风险。

也就是说,如果事情进展不顺利,尤其是当您谈论的是大型数据集时,那么请考虑延迟加载架构。例如,您的用户在看到部门之前无法联系到员工。因此,根据您的网络和大数据大小,加载部门可能是可以的,然后在它返回后启动员工数据的异步加载。当您的用户浏览部门名称时,现在正在加载员工数据。

您可能想要澄清的一个大问题是,是否有任何员工列表数据与部门一起呈现。在我的一个案例中,我有一个工作订单系统,我在登录后加载,但很懒惰,当它加载时,它会在工作订单菜单上抛出一个徽章,以显示有多少未完成。由于我的订单不多,基本上就是一秒钟的等待。没什么大不了的。这不像用户必须等待它加载才能开始工作。如果您想要每个部门都有一个徽章,那么它可能会变得很奇怪。如果按部门加载,您可以随机弹出多个徽章。在这种情况下,它可能会导致用户混淆,将其加载到一大块中可能是一个不错的选择。如果用户无论如何都必须等待,它可能会产生更少的呼叫,用户询问“这样做可以吗?”。尤其是对于工作场所的软件,在工作日开始时等待初始加载是更容易接受的。

需要明确的是,考虑到所有这些复杂因素,您必须尽可能地使用良好的软件编码实践进行开发。这样,您可以编写一个解决方案,如果它不能满足您的性能或用户需求,那么进行更改并不是一场噩梦。在小数据的一般情况下,我只需一大口加载它即可开始,如果加载时间存在问题,则从那里开始使其复杂化。没有明确需要的理由从一开始就使代码复杂化是一种很好的方式,可以使您的代码混乱到使其完全难以维护的程度。

第三点,如果您处理的是企业规模的数据集,那就完全不同了。然后你必须处理分页,是的,它变得有点复杂。

问候,

数据库

【讨论】:

【参考方案3】:

我不确定 fetchDepartments 究竟做了什么,但我会确保实际的 fetch 请求是从 Redux 中间件执行的。通过从中间件执行此操作,您可以对所有请求进行指纹/缓存/去抖动处理,并在整个应用程序中创建一个请求,无论有多少组件请求该事物。

一般来说,中间件是处理异步副作用的最佳场所。

【讨论】:

以上是关于在 react-redux 应用程序中获取详细 api 数据的良好做法的主要内容,如果未能解决你的问题,请参考以下文章

使用 react-redux 子应用?

在 React-redux 和 Redux-Thunk 中从 API 获取数据的问题

React-Redux 中的倒数计时器功能

react 中的 redux 和react-redux的区别分析

react-redux:在 API 调用后渲染组件

foreach 如何在 react-redux 中工作