React Virtualized Masonry не изменяет размер с помощью браузера - PullRequest
0 голосов
/ 11 июня 2018

Я пытаюсь создать фид (фид в стиле Pinterest, чтобы поставить его прямо).Я использую react-virtualized Masonry компонент.

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

Однако у меня странное поведение, как вы можете видеть на этой записи экрана.

Вот соответствующая выдержка из моего кода:

export default class Feed extends Component <PropTypes, State> {
  static readonly defaultProps = {
    enableInfiniteScroll: false,
    chunkSize: 9,
  };

  private _windowScroller: WindowScroller;
  private _masonry: Masonry;
  private _columnCount: number;

  private _cache: CellMeasurerCache;
  private _cellPositioner: Positioner;

  constructor(props: PropTypes) {
    super(props);

    // ...

    this._columnCount = 3;

    this._cache = new CellMeasurerCache({
      defaultWidth: COLUMN_WIDTH,
      defaultHeight: 400,
      fixedWidth: true,
    });
    this._cellPositioner = createMasonryCellPositioner({
      cellMeasurerCache: this._cache,
      columnCount: this._columnCount,
      columnWidth: COLUMN_WIDTH,
      spacer: GUTTER,
    });
  }

  onResize({width}: Size) {
    this._cache.clearAll();
    this.calculateColumnCount(width);
    this.resetCellPositioner();
    this._masonry.recomputeCellPositions();
  }

  cellRenderer(cellProps: MasonryCellProps) {
    const {items} = this.state;
    const listing = items.get(cellProps.index);

    return (
      <CellMeasurer
        cache={this._cache}
        index={cellProps.index}
        key={cellProps.key}
        parent={cellProps.parent}
      >
        <div style={cellProps.style}>
          <ListingCard company={listing} />
        </div>
      </CellMeasurer>
    );
  }

  calculateColumnCount(width: number) {
    this._columnCount = Math.floor((width + GUTTER) / (COLUMN_WIDTH + GUTTER));
  }

  resetCellPositioner() {
    this._cellPositioner.reset({
      columnCount: this._columnCount,
      columnWidth: COLUMN_WIDTH,
      spacer: GUTTER,
    });
  }

  render() {
    const {items, isLoading, hasMore} = this.state;

    return (
      <div className={Styles['listings-feed']}>
        <WindowScroller scrollElement={window} ref={this.setRef}>
          {({height, isScrolling, onChildScroll, scrollTop, registerChild}) => (
            <div className={Styles.windowScrollerContainer}>
              <AutoSizer disableHeight onResize={this.onResize}>
                {({width}) => (
                  <div ref={registerChild as any}>
                    <Masonry
                      cellCount={items.size}
                      cellMeasurerCache={this._cache}
                      cellPositioner={this._cellPositioner}
                      cellRenderer={this.cellRenderer}
                      height={height}
                      width={width}
                      autoHeight
                      ref={(r: Masonry) => this._masonry = r}
                    />
                  </div>
                )}
              </AutoSizer>
            </div>
          )}
        </WindowScroller>
      </div>
    );
  }
}

1 Ответ

0 голосов
/ 11 июня 2018

После тестирования с различными параметрами и настройками я обнаружил, что не рендерил все элементы, потому что они были технически вне диапазона (не в поле зрения пользователя).Они не были видны при прокрутке, просто компонент <Masonry /> обновляется только при изменении свойств.

Поскольку я использую компонент <WindowScroller />, я обнаружил, что он предлагает переменную scrollTopдля функции children, поэтому я передал это непосредственно компоненту Masonry:

<WindowScroller scrollElement={window} ref={this.setRef}>
  {({height, isScrolling, onChildScroll, scrollTop, registerChild}) => (
    <div className={Styles.windowScrollerContainer}>
      <AutoSizer disableHeight onResize={this.onResize}>
        {({width}) => (
          <div ref={registerChild as any}>
            <Masonry
              cellCount={items.size}
              cellMeasurerCache={this._cache}
              cellPositioner={this._cellPositioner}
              cellRenderer={this.cellRenderer}
              height={height}
              width={width}
              autoHeight
              ref={(r: Masonry) => this._masonry = r}
              scrollTop={scrollTop}
            />
          </div>
        )}
      </AutoSizer>
    </div>
  )}
</WindowScroller>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...