2016-08-18 80 views
0

在终极版保存的对象,数组中的替换对象我有一个减速,看起来像这样一个对象数组:使用Javascript/Lodash

[ 
    {id:1, name:Mark, email:[email protected]}, 
    {id:2, name:Paul, email:[email protected]}, 
    {id:3,name:sally, email:[email protected]} 
] 

下面是我的减速器。到目前为止,我可以通过下面的currentPeople减速机添加一个新的对象:

const INITIAL_STATE = { currentPeople:[]}; 

export default function(state = INITIAL_STATE, action) { 
    switch (action.type) { 
    case ADD_PERSON: 
     return {...state, currentPeople: [ ...state.currentPeople, action.payload]}; 
    } 
    return state; 
} 

但这里是我卡住了。我可以使用lodash通过减速器更新一个人吗? 如果我发了行动有效载荷是这样的:

{id:1, name:Eric, email:[email protected]} 

我将能够以1与新领域的标识更换对象?

回答

2

是的,你可以在一个阵列完全更新对象像你想。如果你不想要,你不需要改变你的数据结构。你可以这样添加的情况下,你的减速机:

case UPDATE_PERSON: 
    return { 
     ...state, 
     currentPeople: state.currentPeople.map(person => { 
      if (person.id === action.payload.id) { 
       return action.payload; 
      } 

      return person; 
     }), 
    }; 

这可以被缩短为好,使用隐式的回报和三元:

case UPDATE_PERSON: 
    return { 
     ...state, 
     currentPeople: state.currentPeople.map(person => (person.id === action.payload.id) ? action.payload : person), 
    }; 

米希尔的关于您的数据映射到一个对象的想法normalizr当然是一种可能性,从技术上来说,使用引用更新用户而不是执行循环(初始映射完成后)会更快。但是如果你想保持你的数据结构,这种方法将起作用。另外,像这样的映射只是更新对象的许多方法之一,并且需要浏览器对Array.prototype.map()的支持。你可以使用lodash indexOf()来找到你想要的用户的索引(这很好,因为它在成功时打破了循环,而不是像.map那样继续),一旦你有索引可以覆盖对象直接使用它的索引。确保你不会改变redux状态,如果你想像这样指定你需要在克隆上工作:clonedArray[foundIndex] = action.payload;

+0

我选择这个作为我仍然需要这种格式和它的作品答案!只是一个简短的问题,我用你的映射的例子,它的工作原理是完美的,但你会建议使用lodash,因为这需要浏览器的支持? – lost9123193

+0

这确实取决于你需要支持哪些浏览器。 Array.map支持IE9 +以及Chrome/SafariFF/Opera。所以,除非你有特定的浏览器要求支持IE8,否则你应该对array.map很好。要获得完整的浏览器支持和旧版浏览器的polyfill,请参阅MDN页面:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map。 –

1

这是一个很好的候选数据规范化。如果您在将数据存储到状态树之前对数据进行规范化,则可以有效地用新数据替换数据。

这个例子是直接从Normalizr

[{ 
    id: 1, 
    title: 'Some Article', 
    author: { 
    id: 1, 
    name: 'Dan' 
    } 
}, { 
    id: 2, 
    title: 'Other Article', 
    author: { 
    id: 1, 
    name: 'Dan' 
    } 
}] 

可以归这个way-

{ 
    result: [1, 2], 
    entities: { 
    articles: { 
     1: { 
     id: 1, 
     title: 'Some Article', 
     author: 1 
     }, 
     2: { 
     id: 2, 
     title: 'Other Article', 
     author: 1 
     } 
    }, 
    users: { 
     1: { 
     id: 1, 
     name: 'Dan' 
     } 
    } 
    } 
} 

什么是标准化的优势?

你可以提取你想要的状态树的确切部分。

例如 - 您有一个包含有关文章信息的对象数组。如果你想从数组中选择一个特定的对象,你必须遍历整个数组。最糟糕的情况是所需的对象不在数组中。为了克服这个问题,我们对数据进行标准化。

要正常化数据,请将每个对象的唯一标识符存储在单独的数组中。我们称这个数组为results

result: [1, 2, 3 ..]

和对象阵列转换成与键作为id的对象(见第二片段)。将该对象称为entities

最终,要访问与id 1的对象,只需执行此操作即可 - entities.articles["1"]

如果你想用新的数据来代替旧的数据,你可以做到这 -

entities.articles["1"] = newObj;

0

阵列的使用本地拼接方法:

/*Find item index using lodash*/ 
var index = _.indexOf(currentPeople, _.find(currentPeople, {id: 1})); 

/*Replace item at index using splice*/ 
arr.splice(index, 1, {id:1, name:'Mark', email:'[email protected]'}); 
+0

对于读者来说应该注意的是,在Redux中,.splice()应该以不改变状态但返回新状态的方式在数组副本上完成。有关此处更多信息,请访问:http://redux.js.org/docs/Troubleshooting.html –