React:排序功能导致我的商店追溯副作用?

时间:2015-12-04 16:44:03

标签: javascript sorting reactjs reactjs-flux

工具:

Reactjs 0.14.0

Vanilla Flux(不确定这是否会影响这个问题的性质。

今天我遇到了一个让我挠头一段时间的小虫。 在我的商店中,我试图访问数组中的第一个元素,但它不是预期的元素。

当我进入商店时,我确实打印出了数组,甚至在它发出之后,商店已经更新,数组看起来应该如此,但是如果我访问它,例如data[0]它就不是了。打印出来了。

之后我终于发现在数据发送到商店后正在调用排序。

喜欢如此:

ServerActionCreators.receiveData(data);
data.sort(mySortingFunction);

我的问题:

为什么商店中的数据会被追溯更新? React开发人员如何确保这些追溯性副作用不会影响其商店的同步操作?

1 个答案:

答案 0 :(得分:3)

出现此问题是因为您和商店都持有对相同数组的引用,而sort方法会对其进行变更。

通过远离直接改变数组的方法(pushpopshiftunshiftreverse,可以避免此行为和sort在执行任何这些操作之前制作数组的副本。

var data = [ ... ];

// give the store a reference
MyStore.sendData(data);

// copy the reference before mutating it
var sorted = copy(data).sort(sortFn);

// continue to work with the copy
// ...

根据您使用的Javascript版本,有多种方法可以复制对象或列表。

// ES7
const copy = list => [...list]
// ES6
const copy = list => Object.assign([], list);
// ES5
function copy(list) {
  return list.map(function(item) {
    return item;
  });
}

或者,您可以使用不可变listvector来解决此问题。

// mori.js
var data = mori.vector( ... ),
    sorted = mori.sort(sortFn, data);

// immutable.js
var data = Immutable.list( ... ),
    sorted = data.sort(sortFn);

根据定义,当您调用方法时,这些数据结构不会发生变异。