Реагировать: функция сортировки вызывает обратную побочных эффектов моем магазине?
Инструменты:
Reactjs 0.14.0
Ванильный поток(не уверен, влияет ли это на природу этого вопроса.
Сегодня я столкнулся с жуком,который заставил меня почесать голову. в моем магазине я пытался получить доступ к первому элементу массива, но это не был ожидаемый элемент.
Я распечатал массив, когда он вошел в магазин, и даже после того, как он выдал, что магазин был обновлен, и массив выглядел так, как должен, но если я обращался к нему, например data[0]
это было не то, что показывала распечатка.
Позже я, наконец, обнаружил, что сортировка вызывается после того, как данные были отправлены в магазин.
Вот Так:
ServerActionCreators.receiveData(data);
data.sort(mySortingFunction);
Мой Вопрос:
Почему данные в магазине обновляются задним числом? Как разработчики React гарантируют, что эти ретроактивные побочные эффекты не повлияют на синхронное управление их магазинами?
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);
По определению эти структуры данных не будут мутировать при вызове их методов.