在redux还原器中对对象数组进行排序



我正在尝试对这样的数组(我的状态)进行分类:

[
  {
    name:"Aenean in justo ante"
  },
  {
    name:"Phasellus viverra mattis dolor"
  }
]

我向还原器派遣一个动作:(还原器的一部分)

case 'SORT_COLLECTION':
  return state.sort(function(a, b) {
    var nameA = a.name.toLowerCase(), nameB = b.name.toLowerCase();
    if (nameA < nameB) {
      return -1;
    }
    if (nameA > nameB) {
      return 1;
    }
    return 0;
  })

但它行不通。有人可以告诉我错误在哪里吗?

排序函数应正常工作。但是您不应在还原器中突变原始状态。您可以通过在排序之前调用state.slice()来创建state数组的副本。

case 'SORT_COLLECTION':
  return state.slice().sort(function(a, b) {
    var nameA = a.name.toLowerCase(),
      nameB = b.name.toLowerCase()
    if (nameA < nameB)
      return -1
    if (nameA > nameB)
      return 1
    return 0
  })

当然,您也可以定义更简单的排序功能。

const state = [{name:'foo'},{name:'bar'},{name:'baz'}]
const sortByKey = key => (a, b) => a[key] > b[key] ? 1 : -1
const sorted = state.slice().sort(sortByKey('name'))
console.log(`state=${JSON.stringify(state)}nsorted=${JSON.stringify(sorted)}`)

您需要做:

state.slice().sort(...

sort()通过重新排序引用(突变)更改原始数组,这是Redux Store的" No Go"。 slice()首先进行浅副本,含义仅复制引用,并且很快(除非它包含原始图,否则在这种情况下它们将被复制,但仍然会很快),然后这些新的参考文献被sort()移动。

注意:您仍然无法更改数组中的对象,但幸运的是,排序不会更改它们。

如果您正在使用ES6,则可以尝试这样 state.sort((a,b) => a.name - b.name);

Array.prototype.sort方法要求您返回integerboolean

以下显示了如何沿任一方向订购。

var arr = [
        {
            name:"Aenean jon justo ante"
        },
        {
            name:"Aenean in justo ante"
        },
        {
            name:"Phasellus viverra mattis dolor"
        }
]
console.log("Alphabetical:", arr.sort((a,b) => a.name > b.name));
console.log("Reversed:", arr.sort((a,b) => a.name < b.name));

最新更新