Привязка меню React Material-UI нарушена списком реагирующих окон

Я использую Material-UI и реагировать на окно в проекте. Моя проблема в том, что компонент menu material-ui не привязывается к элементу, предоставленному, когда этот элемент находится в виртуализированном списке реагирующего окна. Меню появится в левом верхнем углу экрана вместо привязки к кнопке, которая его открывает. При использовании всего этого в не виртуализированном списке все работает как положено. Меню правильно привязано к кнопке, которая его открывает.

Вот пример песочницы. Песочница довольно специфична для того, как я использую рассматриваемые компоненты.

Любое руководство о том, как я могу решить эту проблему?

1 ответ

Решение

Вот модифицированная версия вашей песочницы, которая исправляет это:

Редактировать меню BigList

Здесь был ваш начальный код в BigList:

const BigList = props => {
  const { height, ...others } = props;
  const importantData = Array(101 - 1)
    .fill()
    .map((_, idx) => 0 + idx);
  const rows = ({ index, style }) => (
    <FancyListItem
      index={index}
      styles={style}
      text="window'd (virtual): "
      {...others}
    />
  );

  return (
    <FixedSizeList
      height={height}
      itemCount={importantData.length}
      itemSize={46}
      outerElementType={List}
    >
      {rows}
    </FixedSizeList>
  );
};

Я изменил это на следующее:

const Row = ({ data, index, style }) => {
  return (
    <FancyListItem
      index={index}
      styles={style}
      text="window'd (virtual): "
      {...data}
    />
  );
};

const BigList = props => {
  const { height, ...others } = props;
  const importantData = Array(101 - 1)
    .fill()
    .map((_, idx) => 0 + idx);
  return (
    <FixedSizeList
      height={height}
      itemCount={importantData.length}
      itemSize={46}
      outerElementType={List}
      itemData={others}
    >
      {Row}
    </FixedSizeList>
  );
};

Важное отличие состоит в том, что Row теперь является согласованным типом компонента, а не переопределяется с каждым рендером BigList, С вашим исходным кодом каждый рендер BigList вызвало все FancyListItem элементы, которые должны быть перемонтированы, а не просто перерисованы, потому что функция вокруг него, представляющая тип строки, была новой функцией с каждым рендерингом BigList, Одним из последствий этого является то, что якорный элемент, который вы передавали Menu к тому времени больше не был установлен Menu попытался определить свою позицию, и anchorEl.getBoundingClientRect() предоставлял x,y позицию 0,0.

Вы заметите в документации окна реакции ( https://react-window.now.sh/) Row компонент определяется за пределами Example Компонент похож на то, как структурирована фиксированная версия вашего кода.

Райан, спасибо за ответ! Мне это помогло!

Есть еще одно решение: определение родительского компонента как компонента класса (а не функционального компонента).

Моя проблема заключалась в том, что я вызывал функцию "Строки" так:

 <FixedSizeList
     height={height}
     itemCount={nodes.length}
     itemSize={50}
     width={width}
     overscanCount={10}
    >
        {({ index, style }) => this.renderListItem(nodes[index], style)}
    </FixedSizeList>

Исправление было похоже на то, что предложил Райан:

render() {
 ...
 return <FixedSizeList
     height={height}
     itemCount={nodes.length}
     itemSize={50}
     width={width}
     overscanCount={10}
     itemData={nodes}
    >
        {this.renderListItem}
    </FixedSizeList>
  }

  renderListItem = ({data,index, style}) => {
    ...
  }

Я использовал itemData опора для доступа к nodes массив внутри renderListItem функция

Другие вопросы по тегам