Безопасно ли отображать реактивный портал в другой компонент DOM? - PullRequest
0 голосов
/ 27 декабря 2018

Рассмотрим следующий пример:

class GridContainer extends React.Component {
  ...
  render (){
    return <div>
      <Pagination portalId="portal-id"></>
      <Grid ...>
    </div>
  }
}

class Grid extends React.Component {
  ...
  render (){
    return <div>
      <div id="portal-id"></>
      <table ...>
    </div>
  }
}

class Pagination extends React.Component {
  ...
  render (){
    return return ReactDOM.createPortal(<div>Paginator DOM...</div>, document.getElementById(this.props.portalId));
  }
}

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

Почему это отличается (размышляя здесь)?при обновлении родительского компонента портала в процессе согласования diff может найти несоответствие и удалить узел портала.

Из моего тестирования выше не происходит, но я не знаю, могу ли я предположить, чтоРеакция обрабатывает это.Итак, вот вопрос:

Безопасно ли переводить портал в DOM другого компонента?

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

В документе Portals упоминается, что вы можете визуализировать портал в узле DOM, но ничего о компонентах DOM

Это не упоминается, поскольку это особый случай общего правила;К DOM нельзя обращаться напрямую в React, если есть более идиоматические способы.

В DOM происходит много утечек памяти.Если компонент, на котором размещен портал (Grid), будет перерисован, а компонент портала (Pagination) - нет, это приведет к отключению DOM, т. Е. Утечке памяти.

Элемент, в котором порталприсоединен, может даже не существовать в момент рендеринга компонента портала.

0 голосов
/ 27 декабря 2018

Это безопасно?Конечно, но это, вероятно, не будет работать так, как вы ожидаете.

Во-первых, вы можете полностью сбросить dom в div, который создал React.

IМы встречались с несколькими программистами React, которые оспаривали бы этот факт, но дизайн Reacts ожидает и отчитывается за редактирование dom напрямую, когда это необходимо.Если бы они этого не сделали, не было бы componentDidUpdate или React refs.

Эта документация по интеграции с другими библиотеками , вероятно, наиболее актуальна.

Вот совок:

  • React не будет касаться внутренних частей рендеринга div, предполагая, что он всегда пуст в конце рендера.Это только:
    • Создание новых элементов, которые здесь неактуальны, пока вы оставляете их пустыми.
    • Обновите существующие элементы, которые были изначально созданы реакцией.
    • Удалите элементыкоторые были изначально созданы реакцией.

Так что просто создайте этот пустой div и оставьте его одного в render, и React не будет связываться с ним.

Вот руб;React ничего не гарантирует о сроках рендеринга.

Это означает, что вы понятия не имеете, будет ли элемент фактически присутствовать при рендеринге Pagination, что приведет к сбою запроса и не будет отображаться портал.,componentDidUpdate работает только потому, что React специально запускает его после , когда dom обновляется.Но рендер запускается за до обновления dom.Так что если Pagination отображается в том же цикле, что и Grid, то, скорее всего, div еще не подключен.

Теперь печально известный стек переполняет ответ Just-Don't-Do-That:

Только не делай этого.Цель портала - позволить вам визуализировать вне контейнера React, сохраняя при этом ваши компоненты внутри дерева визуализации Reacts.Если вы все равно выполняете рендеринг внутри дерева рендеринга React, почему бы вам просто не рендерить компоненты там?(если это утверждение сбивает с толку, я виню вас)

...