Reactjs React和Redux中处理关系的惯用方法

Reactjs React和Redux中处理关系的惯用方法,reactjs,react-redux,Reactjs,React Redux,我想知道React/Redux中处理返回关系数据的API响应的惯用方法是什么(以及如何更新Redux存储)。例如,当用户登录时,我们发出如下API请求以检索用户数据: GET/users/[:id] 返回: { "id": 14, "first_name": "Bob", "last_name": "Smith", "appointments": [ { "id": 234, "time": "morning" }, {

我想知道React/Redux中处理返回关系数据的API响应的惯用方法是什么(以及如何更新Redux存储)。例如,当用户登录时,我们发出如下API请求以检索用户数据:

GET/users/[:id]

返回:

{
  "id": 14,
  "first_name": "Bob",
  "last_name": "Smith",
  "appointments": [
    {
      "id": 234,
      "time": "morning"
    },
    {
      "id": 456,
      "time": "afternoon"
    }
  ],
  "roles": [
    {
      "id": 789,
      "description": "EYE_DOCTOR"
    },
    {
      "id": 654,
      "description": "EAR_DOCTOR"
    }
  ]
}
我不清楚这两种方法中哪一种“更好”(或者如果有另一种)

方法1:将关系操作(rolesFetched、appointmentsFetched)导入
userActions.js
并从中分派。适当的减速器将处理他们感兴趣的操作。将roleActions导入userActions文件是一种“好”做法吗

// userActions.js

export function login(data) {
  return dispatch =>
    usersApi.fetch(data).then(user => {
      dispatch(userFetched(user));
      dispatch(rolesFetched(user.roles));
      dispatch(appointmentsFetched(user.appointments));
    });
}
方法2:仅分派userFetched操作,并让rolesReducer和AppointsReducer侦听该操作(如果您是角色缩减器,侦听用户操作是否是“好”做法?)


对于这个场景,假设角色基本上是静态的。它们只需要在登录时刷新。但是,约会数据的刷新频率要高得多,并且有一个单独的操作/缩减器来仅获取约会数据(而不必获取用户/角色数据)

很难说你的应用程序实际上有多复杂,但这里有一些注释:

  • 你不需要几个减速器。只需要一个reducer和一个reducer函数就可以将API的整个响应保存到您的状态。(如果您的状态结构稍有不同,您可以在减速机内进行修改)

  • 我认为你只需要把你的主状态结构弄对,然后从一个处理所有不同动作的大减速机开始。如果它变得太大,您可以开始将它切片到不同的文件中,但从架构的角度来看,它仍然是一个缩减器

  • 例如,如果以后有一个不同的API只获取约会,那么也可以为此添加一个reducer函数(而不是新的reducer),并在状态中更新该用户

  • 在我看来,让一个角色还原者来倾听用户的动作并没有什么错。但在您的例子中,它们应该是相同的减速器,因为它们访问相同的状态

  • 在设计您的状态时,请尽量使其保持平坦(在以后从React访问时非常有用),并尽量避免重复数据


祝您好运

在我看来,您的简化程序和操作需要基于工作流,而不是基于实体


在你的情况下,不是有用户减速器、滚轮减速器和约会减速器,而是可以有一个Login减速器来处理与用户相关的所有状态更新。我想我的问题是,你会推荐这家商店的样子吗?我使用combinereducer创建一个类似于

{user:{},roles:[],appointments:[]}
的存储。我这样分解它是因为我认为它在订阅“子”实体的组件方面会更有效-即,您不必订阅
用户
状态,而可以订阅
角色
状态,并且只在角色更改时更新/重新呈现组件,而不必订阅用户中的任何内容。您能否进一步展开可以“展平”的内容?我将保持原样,因为角色和约会与一个用户相关:
{user:{roles:[],appointments:[]}
。当从React组件订阅时,这很好,因为您可以执行以下操作:
const-mapStateToProps=(state)=>{return{roles:state.user.roles};}在这种情况下,您的组件只会在角色发生更改时更新。好吧-但这不会让reducer变得庞大,需要处理大量的操作吗?由于应用程序中的所有数据基本上都与用户相关,因此我们似乎将所有数据都塞进了一个文件中。而通过这种方法,您可以获得更细粒度和更有条理的结果。i、 一个userActions文件,一个userReducer,一个userApi。RoleActions文件、rolesReducer和rolesApi,以及约会和任何其他数据。如何组织应用程序中的大型文件?如果将应用程序分成多个还原程序,当一个还原程序需要从另一个还原程序访问数据或需要同时向多个还原程序写入数据时,您将遇到问题。如果您的文件太大,请随意导出其自身文件中的每个函数:
export default function mainReducer(state,action){switch(action.type){case USER_FETCHED:return userFetched(state,action);default:return state;}
和您的
userFetched()
这里的函数是从
/userFetched
文件导入的。我正在为具有数百个操作的项目执行此操作,它的工作效果非常好。我只在这些还原器的状态完全隔离(没有共享ID或信息)的情况下使用几个还原器。我想我想说的是,可以随意将代码拆分为尽可能多的文件,但只保留一个state对象。
// userActions.js

export function login(data) {
  return dispatch =>
    usersApi.fetch(data).then(user => {
      dispatch(userFetched(user));
    });
}

// rolesReducer.js

export default function rolesReducer(state = initialState, action = {}) {
    switch (action.type) {
        case USER_FETCHED:
            return action.user.roles;
        default:
            return state;
    }
}