在javascript中更新对象中的值的功能方法

时间:2016-06-07 07:03:00

标签: javascript reactjs functional-programming

我试图跟随todo-app做出反应。 我正在写#34;将所有内容更新为已完成"功能,不断变化。

而在redux todomvc示例中,todos是数组

state = [{id: 1, text: "Read flux", completed: false}, ...]

所以他们使用这种方法

const areAllMarked = state.every(todo => todo.completed)
return state.map(todo => Object.assign({}, todo, {
    completed: !areAllMarked
}))

https://github.com/reactjs/redux/blob/master/examples/todomvc/reducers/todos.js

但我使用todos作为像{id:todo}

这样的对象
state = {1: {text: "Read flux", completed: false}, ...}

那么, Object.assign 获取更新对象是否有任何正确,实用的方法?

2 个答案:

答案 0 :(得分:0)

我使用名为here的酷不变性助手库。

在执行基于非突变的更新时非常有用,而无需在代码中进行太多更改(例如使用Immutable.js时)。它能很快地完成工作。

以下是使用代码示例的实现:

import timm from 'timm'; 

const updatedState = timm.setIn(state, ['1', 'completed'], true);

Immutability.js更强大,经常被推荐为JS中不变性的事实库,但它是一个非常重要的库,让你以非原生的方式访问你的对象/数组,这样你就会失去很酷的东西像解构。

我不是在敲我的Immutability.js,在我看来它可能是市场上最强劲的,但是有时候当一把简单的刀可以做的时候你不需要一个完整的电锯。从一个具有低摩擦和成本的东西开始,当你发现一个更强大的工具可以解决的问题时,就可以在堆栈中上升。

答案 1 :(得分:0)

我会推荐对象传播运算符。这是ES7规范的一部分,因此请确保安装了相应的babel plugin。 此代码使用spread运算符并调用嵌套的todo reducer,它负责更改单个todos(来自Dan Abramovs egghead tutorial的代码):

const byId = (state = {}, action) => {
  switch (action.type) {
    case 'ADD_TODO':
    case 'TOGGLE_TODO':
      return {
        ...state,
        [action.id]: todo(state[action.id], action),
      };
    default:
      return state;
  }
};

嵌套的reducer可能如下所示:

const todo = (state, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return {
        id: action.id,
        text: action.text,
        completed: false,
      };
    case 'TOGGLE_TODO':
      if (state.id !== action.id) {
        return state;
      }
      return {
        ...state,
        completed: !state.completed,
      };
    default:
      return state;
  }
};