2015-12-06 4 views
0

Каков наилучший способ обработки объектов, извлеченных из магазина?ReactJs/Flux: как обрабатывать процесс редактирования объектов магазина?

E.g. скажем, у вас есть ProductStore , и у вас есть компонент EditProductComponent. Если установить государственный продукт, который вы редактировали, как показано ниже:

this.state.product = ProductStore.getProductById(1); 

Проблема заключается в том, когда пользователь отменяет редактирование уже после внесения некоторых изменений, они сохраняются в объекте хранилища, как ему присваивается государству напрямую. Например. пользователь изменяет название продукта:

this.state.product.name = value; //new value is assigned to the store object as well 

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

Я думал о возвращении клона из магазина с помощью Object.assign, чтобы гарантировать, что исходный объект останется нетронутым. Но это приведет к возврату новых объектов для каждого запроса на получение, что совсем не показательно.

+0

Вы должны взглянуть на Immutable.js, я думаю, он может вполне соответствовать вашим потребностям –

+0

Спасибо за отзыв. Обязательно проверьте это. Является ли это рекомендуемым решением для указанного варианта использования, но, следуя примеру потока? – scripton

+0

Не устанавливайте переменную состояния напрямую, но вместо этого используйте setState. Когда пользователь решит сохранить изменения, используйте действие для обновления значения хранилища. –

ответ

0

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

Копирование объекта не является особенно дорогостоящей операцией, и сборщик мусора будет очищаться, когда ваши ссылки выйдут из сферы действия, поэтому вам, вероятно, также не придется беспокоиться о памяти.

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

getProductById: function(id) { 
    var product = this.products[id]; 

    return Object.assign({}, product); 
} 

Однако вы можете пойти на один уровень дальше и сделать их неизменными вместо этого.

getProductById: function(id) { 
    var product = this.products[id]; 

    return Object.freeze(product); 
} 

Теперь уже невозможно мутировать продукты. Если другая часть вашего приложения хочет его отредактировать, вместо этого она должна создать новую копию с соответствующими изменениями.

// the immutable product that came from the store 
const product = { ... }; 

// with ES6 
const editedProduct = Object.assign({ editedProp: newValue }, product); 
// or with ES7 
const editedProduct = { editedProp: newValue, ...product }; 

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

ProductStore.edit(editedProduct.id, editedProduct); 

Это позволяет обеспечить предсказуемость в вашем приложении.

Другой альтернативой является использование библиотеки, которая реализует неизменяемые структуры данных, такие как Immutable.js.

Он поставляется с immutable map type, который может быть использован как объект, но вместо того, чтобы мутировать, когда вы пытаетесь изменить или создать свойство, оно возвращает нового непреложной карты.

var product = Immutable.Map({ name: 'product_name' }); 
var editedProduct = product.set('name', 'new_name'); 

// now tell the store that you've edited it 
// ... 

Большое преимущество в том, что Immutable.js использует метод, называемый структурный обмен, чтобы убедиться, что внутри, как большая часть объекта, как это возможно поделена между этими двумя версиями, что делает их почти так же эффективно, как регулярные изменяемым данных структур.

Эти концепции хорошо освещены в a great video от создателя библиотеки. Это стоит посмотреть.

+0

Спасибо за полное объяснение! – scripton

+0

«Теперь уже невозможно мутировать продукты». Сортировка: «Object.freeze' и' Object.assign »- это мелкие операции, и поэтому они фактически не решают проблему. Например,' o = {a: { b: 1, c: 1}}; Object.freeze (o); oab = 2; Object.assign ({}, o) .ac = 2' и теперь 'o == {a: {b: 2, c : 2}} '.Вы должны быть усердными и глубоко замораживать/копировать повсюду или просто использовать полностью неизменные структуры данных. –

+0

Андрей поднимает хороший момент, если ваши объекты продукта являются составными (они состоят из других объектов) то вам потребуются рекурсивные решения. Однако это не проблема, если ваши объекты представляют собой только одноуровневые сопоставления ключей и значений, это не проблема. –

Смежные вопросы