Использование одного хранилища для нескольких элементов одного типа

Допустим, у меня есть два контроллера-представления - ItemsContainer, Item и хранилище ItemsStore, в котором хранится список элементов. Когда список элементов изменяется из-за какого-либо действия, хранилище выдает изменение, и оба представления получают свое состояние из ItemsStore.

ItemsContainer вызывает getItems и перерисовывает список элементов. Item вызывает метод getItem со своим идентификатором и перерисовывает себя.

Итак, как проще всего вывести на экран несколько ItemsContainer?

Я могу переписать ItemsStore так, чтобы он хранил свои данные в карте id -> storeData, но это означало бы, что каждому методу ItemsStore потребуется еще один параметр storeId, также передаваемый ему. getItems() становится getItems(storeId), getItem(itemId) становится getItem(storeId, itemId), что выглядит слишком уродливо. Действия также потребуют прохождения storeId.

Другой способ, как я понял, это создание хранилища, которое бы управляло данными ItemsStore, и повторно инициализировало бы его, вызывая действие STORE_UPDATE.

Проблема с этим методом заключается в том, что если у нас есть два (A и B) ItemsContainer, и активным контейнером является A, так что ItemsStore содержит элементы, которые отображаются в A, контейнер B все равно будет прослушивать ItemsStore изменения. Я могу добавить проверку, если это активный контейнер в методе ItemsContainer.onChange, но я не уверен, что это нужно делать.


person user3445165    schedule 25.07.2015    source источник


Ответы (1)


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

Если бы мне нужно было создать приложение для реагирования/потока, в котором было бы несколько списков, содержащих элементы, каждый из которых имел бы отдельные элементы, я бы сделал что-то вроде этого:

Компонент представления контроллера верхнего уровня: ItemsApp Дочерний элемент ItemsApp: ItemsList Дочерний элемент ItemsList: Items

ItemsApp будет компонентом, который извлекает состояние из хранилища. В магазине у меня был бы listOfItems, который представляет собой массив объектов, каждый объект представляет собой отдельный элемент с «именем» и «категорией». Допустим, некоторые предметы имеют категорию «красный», а другие — «синий».

Итак, itemsApp получает свое состояние из хранилища и передает все элементы отдельным компонентам ItemsList, например так:

render: function() {
   var red = "red";
   var blue = "blue";

     return (
        <div>
          <ItemsList items={this.state.listofItems} category={red} />
          <ItemsList items={this.state.listofItems} category={blue} />
        </div>
     )
 }

Затем каждый ItemsList будет брать список элементов и фильтровать его, чтобы искать только те элементы, которые соответствуют категории, которую он передаст, например так:

render: function() {
     var category = this.props.category;
     var itemsToRender = this.props.items.filter(function(item) {
        return (
             item.category = category
        )
     });

     return (
          <div>
            <Items items={itemsToRender}/>
          </div>
     )
  }

Затем в компоненте Items:

render: function() {
     var displayedItems = this.props.items.map(function(item) {
        return (
               <li className={item.category}>{item.name}</li>
        )
      });

     return (
         <ul>
          {displayedItems}
         </ul>
     )
   }

В зависимости от того, как вы хотите структурировать свой код, вы также можете использовать карту внутри ItemsList в своем недавно отфильтрованном списке, возвращая некоторый JSX для каждого элемента, передавая имя и категорию элемента, а затем ваш компонент Item не будет делать ничего, кроме визуализировать <li className={this.props.category}>{this.props.name}</li> или то, что вы хотите, чтобы ваша разметка была.

Надеюсь это поможет.

person hmlee    schedule 25.07.2015
comment
Спасибо, но в моем случае я не могу хранить элементы разных категорий в одном массиве. Я искал решение, с помощью которого я смогу использовать свой ItemsStore с небольшими изменениями. - person user3445165; 27.07.2015