Вы хотите запросить функцию или сообщить об ошибке ?
ошибка
Каково текущее поведение?
Учитывая следующий (упрощенный) фрагмент:
class HoverMenu extends React.Component {
render() {
if (typeof document === 'undefined') return null
const root = document.getElementById('root')
return ReactDOM.createPortal(<div>Hello World</div>, root)
}
}
class Para extends React.Component {
render() {
return (
<span>
Some Text
<HoverMenu />
</span>
)
}
}
где div#root
- действительный существующий div
, при гидратации после SSR отображается следующая ошибка:
Warning: Expected server HTML to contain a matching <div> in <span>
Предупреждение исчезнет, если я обновлю определение HoverMenu
до:
class HoverMenu extends React.Component {
componentDidMount() {
this.setState({ isActive: true })
}
render() {
const { isActive} = this.state
if (!isActive) return null
const root = document.getElementById('root')
return ReactDOM.createPortal(<div>Hello World</div>, root)
}
}
Я бы предпочел не делать этого из-за двойного рендеринга, вызванного setState
в componentDidMount
.
Я не совсем понимаю, о чем мне говорит эта ошибка. В любом случае <div />
не отображается на стороне сервера. Ошибка особенно сбивает с толку, поскольку HoverMenu
DOM div
даже не отображается внутри DOM span
. (Интересно, происходит ли это из- HoverMenu
что span
.)
Какое поведение ожидается?
Ошибка не возникает. Или, по крайней мере, сообщение об ошибке яснее.
Какие версии React и какой браузер / ОС подвержены этой проблеме?
Хром 65
Реагировать 16.2
(SSR через Next 5.1)
У меня аналогичная проблема, которую также можно решить повторным рендерингом на клиенте через setState.
В моем случае я пытаюсь визуализировать модальное окно внутри портала. Компонент Modal
возвращает null
при визуализации на сервере и создает портал на клиенте. Однако после гидратации DOM портится.
Например, если я использую его так внутри своего основного компонента:
<Modal>
This is a test
</Modal>
<div className="some-div-after-the-modal">
</div>
Вместо того, чтобы получать это после гидратации:
<!-- Inside the portal container -->
<div class="modal-wrapper">
<div class="modal-content">This is a test</div>
</div>
<!-- In the main component -->
<div class="some-div-after-the-modal">
</div>
Я получаю это:
<!-- Inside the portal container -->
<div class="some-div-after-the-modal">
<div class="modal-content">This is a test</div>
</div>
<!-- In the main component -->
<div class="some-div-after-the-modal">
</div>
И предупреждение такое же ( Expected server HTML to contain a matching <div> in <div>
). Я использую React 16.3 с настраиваемым методом SSR.
Я не уверен, что это предполагаемое поведение.
Хотя гидратирующие порталы не поддерживаются (https://github.com/facebook/react/issues/13097), само сообщение не имеет смысла. Нам нужно будет исследовать и исправить это.
@gaearon Цель исправления:
invariant violation: Portal is not support on SSR. For more detail, please refer https://github.com/facebook/react/issues/13097
правильно?
Я готов, если это не срочно.
Я планирую черновик SSR Doc для репозитория веб-сайта, поэтому я должен быть знаком с механизмом гидратации.
Думаю, это расследование поможет моему плану.
https://github.com/facebook/react/pull/13379
Почему порталы не поддерживаются в SSR даже для отображения «ничего»?
Не похоже, что рендеринг ничего лучше - я не вижу, что отличает содержимое портала от других, если мы не считаем его стоящим рендеринга на сервере.
Мы, вероятно, вернемся к этому вместе с обновлением серверного рендерера для неопределенности.
Порталы концептуально являются клиентскими компонентами; используются для таких вещей, как модальные окна, которые обычно не хотят отображать на сервере - они также принимают элемент dom, которого renderToString не делает, потому что нет dom. Я не вижу, что с ними можно делать на сервере что-нибудь значимое - я просто также не вижу ничего ценного в бросании.
используется для таких вещей, как модальные окна
Это один вариант использования, но есть и другие, такие как боковые панели и тому подобное, которые не обязательно предназначены только для клиента.
они также принимают элемент dom
Справа - в текущем дизайне. Это могло измениться. https://github.com/facebook/react/pull/8386#issuecomment -262375265
я просто тоже не вижу ничего ценного от метания.
Ценность метания заключается в явном подтверждении того, что портал не будет работать. Вы можете легко обойти это с помощью {domNode && ReactDOM.createPortal(stuff, domNode)}
или аналогичного. Потому что вам уже нужно было выполнить какую-то проверку, чтобы определить, можете ли вы получить узел DOM - так что на этом этапе у вас должно быть достаточно данных, чтобы отказаться от создания портала.
Я хотел бы исправить это как свою "первую хорошую проблему"
+1
Могу я поработать над этим вопросом?
Конечно. Я думаю, ты сможешь. Итак, как далеко вы зашли? Я тоже подумываю забрать его.
Привет, ребята, есть идеи, как найти файл, в котором проблема, я могу его получить, пожалуйста, помогите.
Привет, вот частичный запрос на перенос для этой проблемы
https://github.com/facebook/react/pull/15473
Кто-нибудь еще занимается этим? Я бы с радостью взялся за это.
Какой у этого статус? Как я мог воспроизвести это?
Это все еще проблема?
Я тоже не получил ответа по этому поводу.
Я считаю, что статус этого вопроса все еще открыт.
Могу я заняться этим вопросом?
Здравствуйте, кто-нибудь работает над этим вопросом? Если нет, я бы взял.
если над этим никто не работает, я могу
Это все еще проблема? Кажется, что были попытки исправить это, но основная проблема в том, что некоторые люди действительно хотят, чтобы порталы работали над рендерингом на стороне сервера? Если это так, можно ли закрыть этот вопрос?
Добавление элемента div должно работать нормально
`class Para extends React.Component {
render () {
возвращение (
)
}
} `
Самый полезный комментарий
Хотя гидратирующие порталы не поддерживаются (https://github.com/facebook/react/issues/13097), само сообщение не имеет смысла. Нам нужно будет исследовать и исправить это.