Требуется руководство по инкапсуляции логики в таблице данных, основанной на реакции - PullRequest
0 голосов
/ 03 мая 2018

Я пытаюсь создать повторно используемый компонент таблицы данных реакции, используя response-virtualized , и мне нужно руководство по управлению состоянием.

Я реализовал фильтрацию / сортировку / бесконечную прокрутку на стороне сервера и использую состояние локального компонента для хранения контекста таблицы (фильтр, текущая страница, строки данных и т. Д.).

упрощенный пример:

  class DataTableWithFilter
      render() {
        return ( 
              <React.Fragment>
              <DataTableFilterBar
                   value={this.state.filter}
                   onFilterChange={this._handleFilterChange}
                   onSort={this._handleSort}
                   onScroll={this._handleScroll}
               />
              <VirtualizedDataTable
                  records={this.state.records}
              />                      
              </React.Fragment>
        )
      }
      _handleFilterChange() {
         // build up url from state (path, filter, sort index, page index, etc)
         // fetch new data
         // put new data into state
      }
      _handleSort() {...}
      _handleScroll() {...}
      etc
  }

Любой ценой, Я пытаюсь избежать необходимости дублировать любую логику, используемую в таблице, и сохранять ее полностью инкапсулированной в компоненте таблицы. Таблица будет использоваться десятки раз, и поэтому я хочу, чтобы таблица знала, как загружать свои собственные данные и обрабатывать сортировку / фильтрацию / прокрутку, и использоваться в разных контекстах.

Но это становится сложным, так как различные виды использования таблицы требуют, чтобы родительский и родственный компоненты могли сообщать таблице о перезагрузке данных. Примеры включают в себя кнопку «Добавить новую запись», которая выдает модальное окно, а затем нуждается в перезагрузке таблицы после публикации новой записи на сервере. Или кнопка «Удалить запись», для которой требуется перезагрузить таблицу данных после публикации удаления на сервере.

Я вижу несколько вариантов:

1) Создайте монолитный компонент EditableDataTableWithFilter, который содержит ВСЕ состояния и функции фильтрации / сортировки / прокрутки / модального / кнопки, а также при необходимости визуализирует некоторые подкомпоненты, такие как панель фильтрации или модальные параметры. Недостатком является наличие всего в одном компоненте и много поведения, которое будет ненужным при использовании компонента в качестве простой таблицы данных без фильтрации или контекстно-зависимых кнопок / модалов. Это кажется действительно плохим.

2) Создайте компонент EditableDataTable, который визуализирует дочерний компонент DataTableWithFilter и добавляет логику, необходимую для отображения и отправки данных из модальных объектов. Я предполагаю, что для этого снова потребуется переместить данные таблицы в локальное состояние EditableDataTable и передать их в DataTableWithFilter в качестве подпорки, чтобы таблица перезагружалась при изменении данных. ИЛИ мне нужно найти какой-нибудь способ «сообщить» дочернему объекту DataTableWithFilter перезагрузить его данные. Последнее, использование ссылок или аналогичных, кажется плохим подходом, который снова нарушает инкапсуляцию. И я не уверен, как бы я использовал свойство в качестве «триггера перезагрузки».

3) Используйте централизованного государственного провайдера, такого как Рэдекс. Я еще не ввел в проект избыточность, но мне интересно, является ли это лучшим решением.

1 Ответ

0 голосов
/ 05 мая 2018

Найти под структурой компонента (это просто псевдокод). ok_cb, cancel_cb - это обратные вызовы, передаваемые компоненту ModalThatNeedsToReloadTable и вызываемые из компонента ModalThatNeedsToReloadTable. Обратные вызовы установили бы желаемые данные в состоянии, используя метод setState (), который бы повторно отобразил весь компонент Container. Надеюсь, это поможет.

<Container>
    // in this component you can set the data shared between all
    // the components within the container in the components 'state'

    cancel_cb() {
        // this cb will call the set state
        // method which will re-render the component
    }

    ok_cb() {
        // this cb will call the set state
        // method which will re-render the component
    }


    render()

        if(this.props.showModal)
            <ModalThatNeedsToReloadTable show={this.state.showModal}
                onCancelClick={this.cancel_cb}
                onOKClick={this.ok_cb}/>

        <SmartTableComponent> <DumbTableComponent> </SmartTableComponent>

</Container>
...