reducer:添加到数组数据

时间:2015-12-03 18:04:46

标签: reactjs redux

如果我从初始状态的外部源中提取一些数据,那么想要添加其他信息,比如“喜欢”? 我已经尝试添加到产品阵列,但它变得凌乱,我想我应该有一个额外的数组为喜欢的项目然后把产品ID放在这,唯一的是我需要它反映在它有的产品我很喜欢,我正在将产品数据映射到该项目。

最好的办法是什么?

const initialState = {
  isFetching: false,
  products: [],
};

我应该添加favs:[]?

当我将产品数组映射到产品组件时,我如何将喜欢的状态反映到我的产品中?而喜欢的状态现在在收藏中?

我试着这样做把它添加到产品阵列但是它真的很乱(像这样)

case ADD_LIKED:
 state.products[action.index]['liked'] = true;
 return state;

1 个答案:

答案 0 :(得分:1)

state.products[action.index]['liked'] = true;

这里的问题是你正在改变reducer里面的状态,它是things you should never do inside a reducer之一。

您会发现,如果您将数据分解为较小的部分,那么编写不会改变数据的函数会更容易。例如,您可以开始拆分您的应用程序。

function productsReducer(products = [], action) {
  // this reducer only deals with the products part of the state.
  switch(action) {
    case ADD_LIKED:
      // deal with the action
    default:
      return products;
  }
}

function app(state = {}, action) {
  return {
    isFetching: state.isFetching,
    products: productsReducer(state.products, action)
  }
}

在这种情况下,我肯定想写一点不变的助手。

function replaceAtIndex(list, index, replacer) {
  const replacement = replacer(list[index]);

  const itemsBefore = list.slice(0, index),
        itemsAfter = list.slice(index + 1);

  return [...itemsBefore, replacement, ...itemsAfter];
}

您可以使用用于更改列表中对象的通用函数来补充它。

function updateInList(list, index, props) {
  return replaceAtIndex(list, index, item => {
    return { ...props, ...item };
  });
}

然后你可以用不可变形式重写你的函数

 switch(action) {
    case ADD_LIKED:
      return updateInList(products, action.index, { liked: true });
    default:
      return products;
  }

你可以通过部分应用这个功能来获得幻想。这允许您在reducer中编写非常富有表现力的代码。

 const updateProduct = updateInList.bind(this, products, action.index);

 switch(action) {
    case ADD_LIKED:
      return updateProduct({ liked: true });
    case REMOVE_LIKED:
      return updateProduct({ liked: false });
    default:
      return products;
  }