Получить из магазина без запуска обновления - PullRequest
0 голосов
/ 02 мая 2018

У меня есть родительский компонент, который (упрощенно) выглядит следующим образом

export default class ProductGrid extends React.PureComponent<Props, State> {
  renderProducts() {
    return this.props.products.map(product => (
      <Product {...product} />
    ));
  }

  render() {
    return <div>{this.renderProducts()}</div>;
  }
}

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

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

Хотя я мог бы реализовать пользовательский shouldComponentUpdate и опустить это свойство, он все равно запускает этот пользовательский хук жизненного цикла. На моей странице может быть более 200 товаров, поэтому это может вызвать проблемы.

Я использую эту информацию исключительно по капле, и мне было интересно, можно ли просто получить эту информацию "в тот момент" из магазина притока, не подписываясь на изменения. Например, аналогично redux-saga:

onDragStart = () => {
  const selectedCount = select(({ products: { selected } }) => selected.length);
  if (selectedCount) {
    // whatever here
  }
}

Возможно ли это?

Ответы [ 2 ]

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

В ответ на ваше «возможно ли реализовать это как HOC, не заставляя его обновляться»: вот краткий план HoC, который предоставит хранилище как свойство любому компоненту, который вы передаете.

function myHoC(WrappedComponent) {
  const classToExtend = WrappedComponent.prototype instanceof React.PureComponent
    ? React.PureComponent
    : React.Component

  class NonUpdatingStoreProvider extends classToExtend {
    static contextTypes = {
      store: PropTypes.object,
    }

    render() {
      return (
        <WrappedComponent
          store={ this.context.store }
          { ...this.props }
        />
      )
    }
  }

  NonUpdatingStoreProvider.WrappedComponent = WrappedComponent
  NonUpdatingStoreProvider.displayName = `NonUpdatingStoreProvider(${WrappedComponent.displayName || WrappedComponent.name})`

  return NonUpdatingStoreProvider
}

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

Если вы не хотите, чтобы хранилище передавалось компонентам, вы можете просто передать метод store.getState или все, что вы хотите с ним сделать.

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

Если ваш компонент ProductGrid считывает количество выбранных элементов / текущий выбор, чтобы просто перейти к Product, то альтернативным решением является подключение Product напрямую для хранения.

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

const mapStateToProps = (state, props) => ({
    productData: getProductData(state, props.productId),
    isProductSelected: isProductSelected(state, props.productId)
})

const ProductWrapper = connect(mapStateToProps)(Product)

и тогда вашему ProductGrid нужно взять только productIds для отображения списка

export default class ProductGrid extends React.PureComponent<Props, State> {
  renderProducts() {
    return this.props.productIds.map(productId => (
      <ProductWrapper productId={productId} />
    ));
  }

  render() {
    return <div>{this.renderProducts()}</div>;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...