【问题标题】:Redux single state updateRedux 单状态更新
【发布时间】:2019-05-12 07:35:14
【问题描述】:

在一个请求中收到所有灯的数据。 (但是,我可以单独从服务器接收每个灯数据)。

我从服务器收到的数据是这样的:

[
    {
        "id": "1",
        "state": 'ON'
    },
    {
        "id": "2",
        "state": 'OFF'  
    },
    {
        ...
    },
    ...
]

在我的应用中,这些数据将存储在 single redux 状态。我使用 FlatList 和一个简单的 Switch 来呈现这些数据,以便用户可以打开或关闭每个灯。

当用户更改灯的状态时,将调度 LOADING 动作,整个灯将显示一个微调器。

当从服务器接收到更新的数据时,将调度 SUCCESS action,更新 redux 状态,spinner 将消失,最后显示更新的数据。 p>

问题1:当用户只与一个灯交互时,我不希望所有灯进入LOADING状态!

问题 2:我不知道在我的请求中会收到多少盏灯。

期望的行为:只有与用户交互的灯必须显示一个微调器并抛出更新过程。

我在处理 redux 状态方面需要帮助。

我希望这些信息对您有所帮助。您可以在下面找到我用于 lightingInitReducer(获取所有灯的数据)和 lightingChangeStateReducer(更改灯的状态)的舵。 isLoading 用于显示微调器。此外,当更改状态过程成功时(LIGHTING_CHANGE_STATUS_SUCCESS 被调度),新数据将通过 init 请求从服务器请求:

export const lightingInitReducer = (state = {
  isLoading: false,
  errMess: null,
  info: {},
}, action) => {
  switch (action.type) {
    case ActionTypes.LIGHTING_INIT_SUCCESS:
      return {
        ...state, isLoading: false, errMess: null, info: action.payload,
      };
    case ActionTypes.LIGHTING_INIT_FAILED:
      return {
        ...state, isLoading: false, errMess: action.payload, info: {},
      };
    case ActionTypes.LIGHTING_INIT_LOADING:
      return {
        ...state, isLoading: true, errMess: null, info: {},
      };
    default:
      return state;
  }
};

export const lightingChangeStateReducer = (state = {
  isLoading: false,
  errMess: null,
  info: {},
}, action) => {
  switch (action.type) {
    case ActionTypes.LIGHTING_CHANGE_STATUS_SUCCESS:
      return {
        ...state, isLoading: false, errMess: null, info: action.payload,
      };
    case ActionTypes.LIGHTING_CHANGE_STATUS_FAILED:
      return {
        ...state, isLoading: false, errMess: action.payload, info: {},
      };
    case ActionTypes.LIGHTING_CHANGE_STATUS_LOADING:
      return {
        ...state, isLoading: true, errMess: null, info: {},
      };
    default:
      return state;
  }
};

【问题讨论】:

  • 您能否分享在 RECIEVE_SUCCESS 操作中更新状态的代码
  • @MukarramAli 我认为您需要 Reducer 功能。我为你更新了问题。

标签: reactjs react-native redux state


【解决方案1】:

查看 immutability-helper:https://github.com/kolodny/immutability-helper

太神奇了。 Reducers 可能会因为深度嵌套的状态而变得非常混乱,这个库有助于整理很多东西。

对于问题 1,以下是关于如何更新单个灯并显示该项目的加载状态的想法:

您可以使用 FlatList 中按下的列表项的索引,并将其传递给调度服务器请求的 LOADING 操作。然后,您可以在减速器中使用此索引来更新您所在州的特定灯。使用 immutability-helper 库,reducer 可能如下所示:

import update from 'immutability-helper';     

case UPDATE_LAMP_REQUEST:
   let newState = update(state, {
     lamps: {
       [action.index]: {
         loading: { $set: true }, // turns on loading state for lamp at index
       }
     }    
   })
   return newState;

一旦网络请求完成,并且您的 SUCCESS 操作已调度,您就可以将同一索引从您的 FlatList 传递给您的减速器,并使用来自服务器的更新后的灯更新您所在状态的灯:

import update from 'immutability-helper';     

case UPDATE_LAMP_SUCCESS:
   let newState = update(state, {
     lamps: {
       [action.index]: {
         loading: { $set: false }, // turn off loading
         $set: action.lamp // set the new lamp state
       }
     }    
   })
   return newState;

然后,您将“加载”字段连接到负责 FlatList 中单个列表视图项的组件,并使用该值隐藏/显示加载状态。

至于问题2,我不确定我是否理解问题。

【讨论】:

  • 你没有理解我的问题。我使用了两个完全独立的 reducer:一个用于获取灯数据,另一个用于更新灯的状态。即使我将这两者结合在一起,灯的数量也总是会发生变化(用户可以购买新产品,问题 2)。在您的回答中:请记住 action.lamp 包含整个灯数据。
  • @kasra 对不起,如果我误解了,但在我的例子中我在哪里结合减速器?第一个用于在初始请求时更新您的状态中的单个灯(打开加载状态),第二个用于在 Web 请求完成后更新您的状态中的单个灯(关闭加载并从服务器更新灯)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-11
  • 2019-07-28
  • 2019-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多