Реагировать: функция сортировки вызывает обратную побочных эффектов моем магазине?


Инструменты:

Reactjs 0.14.0

Ванильный поток(не уверен, влияет ли это на природу этого вопроса.


Сегодня я столкнулся с жуком,который заставил меня почесать голову. в моем магазине я пытался получить доступ к первому элементу массива, но это не был ожидаемый элемент.

Я распечатал массив, когда он вошел в магазин, и даже после того, как он выдал, что магазин был обновлен, и массив выглядел так, как должен, но если я обращался к нему, например data[0] это было не то, что показывала распечатка.

Позже я, наконец, обнаружил, что сортировка вызывается после того, как данные были отправлены в магазин.

Вот Так:

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

Мой Вопрос:

Почему данные в магазине обновляются задним числом? Как разработчики React гарантируют, что эти ретроактивные побочные эффекты не повлияют на синхронное управление их магазинами?

1 2

1 ответ:

Проблема возникает из-за того, что и вы, и хранилище содержат ссылки на один и тот же массив иsort метод мутирует его.

Можно избежать такого поведения, держась подальше от методов, которые непосредственно мутируют массивы.(push, pop, shift, unshift, reverse и еще 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;
  });
}

В качестве альтернативы, вы могли бы использовать неизменяемые перечень и вектор, чтобы решить эту проблему.

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

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

По определению эти структуры данных не будут мутировать при вызове их методов.