React Native-Redux状态正在更新,但组件视图未正确更新

时间:2019-11-27 17:34:02

标签: javascript reactjs react-redux

该应用程序具有以下功能。

  • 从主页上的服务器获取订单列表,并以Redux orders状态保存。
  • 订单的状态为“打开”,“进行中”,“待处理”,“已完成”,“已取消”。
  • 在应用程序中,有一个“订单”组件。在选项卡视图中有3个选项卡。 “打开”,“正在进行”和“历史记录”。打开显示“打开”订单,进行中显示“进行中”和“待处理”订单。历史记录显示“已完成”和“已取消”订单。
  • 每个选项卡组件都处于orders状态,并且使用if条件仅显示应该处于其之下的特定顺序。

假设在服务器端执行了一项操作,并且订单从“打开”状态变为“进行中”状态。

预期行为:

现在,用户向下滑动并刷新选项卡组件。刷新后,它应从服务器获取订单更新的数据并更新redux orders状态。 orders状态更新后,所有标签数据均应自动更新。

实际行为:

用户向下滑动并刷新选项卡组件。刷新时,它将从服务器获取订单更新的数据并更新redux orders状态。但是在更新状态后,组件视图无法正确更新。我的意思是,有些部分会更新,但有些部分不会更新。

我想,我没有在reducer中正确更新状态。以下是用于获取和放置订单有效负载的简化程序代码。

const orders = (state = {}, action)=> {
  switch(action.type){
    case 'GET_ORDERS':
      return action.payload
    case 'PUT_ORDERS':{
      let newState = state;
      if(action.payload != undefined){
        action.payload.map(function(order, index){
          if(newState[order.id] != undefined) {
            newState[order.id].order_status = order.order_status;
          } else {
            newState[order.id] = order;
          }
        });
      }
      return Object.assign({}, state, action.payload);
    }
  }
}

我通过将订单ID作为密钥来维护订单对象的密钥。这是因为,如果要重新订购时要进行刷新,则不应重新分配键。

1 个答案:

答案 0 :(得分:2)

您正在更改订单,而不是将其更改为新对象。即使减速器状态正在生成新对象,但是如果您有与订单对象绑定的组件,它们也不会将它们视为更改。例如,如果您有:

const { connect } = require('react-redux');

export function Order({ orderId, order }) {
  return (
    <div className="order">
      <span className="order-id">{order.id}</span>
      <span className="order-status">{order.order_status}</span>
    </div>
  );
}

const mapStateToProps = ({ orders }, { orderId }) => ({
  order: orders[orderId]
});

export default connect(mapStateToProps)(Order);

...然后,传递给您组件的order道具将被识别为同一对象,并且您的组件不会更新。

尝试如下更改减速器:

const orders = (state = {}, action)=> {
  switch(action.type){
    case 'GET_ORDERS':
      return action.payload
    case 'PUT_ORDERS': {
      const updates = action.payload.map((payloadOrder, index) => {
        const oldOrder = state[payloadOrder.id];
        const newOrder = oldOrder 
          ? { ...oldOrder, order_status: payloadOrder.order_status }
          : payloadOrder;
        return {
          [payloadOrder.id]: newOrder
        };
      });
      return Object.assign({}, state, ...updates);
    }
  }
}

通过此更改,您状态下已修改的每个订单对象都是一个新对象。