React: Advertencia inesperada al hidratarse con portal y SSR

Creado en 15 abr. 2018  ·  24Comentarios  ·  Fuente: facebook/react

¿Quieres solicitar una función o informar de un error ?

insecto

¿Cuál es el comportamiento actual?

Dado el siguiente fragmento (simplificado):

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>
    )
  }
} 

donde div#root es un div válido que existe, se muestra el siguiente error al hidratar después de SSR:

Warning: Expected server HTML to contain a matching <div> in <span>

La advertencia desaparece si actualizo la definición de HoverMenu a:

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)
  }
}

Preferiría no hacer eso debido al doble renderizado causado por setState en componentDidMount .

No entiendo muy bien qué me dice ese error. No se representa <div /> del lado del servidor en ningún caso. El error es particularmente confuso, ya que el HoverMenu DOM div ni siquiera se representa dentro de un DOM span . (Me pregunto si esto está sucediendo porque HoverMenu está anidado dentro de un React span .)

¿Cuál es el comportamiento esperado?

No se lanza ningún error. O, al menos, que el mensaje de error sea más claro.

¿Qué versiones de React y qué navegador / sistema operativo se ven afectados por este problema?

Cromo 65
Reaccionar 16.2
(SSR hasta Next 5.1)

medium Bug good first issue

Comentario más útil

Si bien los portales de hidratación no son compatibles (https://github.com/facebook/react/issues/13097), el mensaje en sí no tiene sentido. Tendremos que investigar y solucionarlo.

Todos 24 comentarios

Tengo un problema similar, que también se puede resolver volviendo a renderizar en el cliente a través de setState.
En mi caso, trato de renderizar un modal dentro de un portal. El componente Modal devuelve null cuando se procesa en el servidor y crea un portal en el cliente. Sin embargo, el DOM se estropea después de la hidratación.

Por ejemplo, si lo uso así dentro de mi componente principal:

<Modal>
This is a test
</Modal>

<div className="some-div-after-the-modal">
</div>

En lugar de obtener esto después de la hidratación:

<!-- 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>

Entiendo esto:

<!-- 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>

Y la advertencia es la misma ( Expected server HTML to contain a matching <div> in <div> ). Utilizo React 16.3 con un método SSR personalizado.

No estoy seguro de si este es el comportamiento previsto.

Si bien los portales de hidratación no son compatibles (https://github.com/facebook/react/issues/13097), el mensaje en sí no tiene sentido. Tendremos que investigar y solucionarlo.

@gaearon El propósito de arreglar es

  • [] Detecta que el Portal se está utilizando en hydrate () y luego arroja más correctamente un mensaje de error por invariante.
    por ejemplo, invariant violation: Portal is not support on SSR. For more detail, please refer https://github.com/facebook/react/issues/13097
  • [] Agregar prueba

    • [] Si el Portal se usa con hydrate (), debería arrojar el mensaje de error anterior

¿derecho?
Estoy dispuesto si no es urgente.

Estoy planeando el borrador de SSR Doc para el repositorio del sitio web, así que tengo que estar familiarizado con el mecanismo de hidratación.
Creo que esta investigación será útil para mi plan.
https://github.com/facebook/react/pull/13379

¿Por qué los portales no son compatibles con SSR, incluso para representar "nada"?

No parece que renderizar nada sea lo mejor; no veo qué hace que el contenido del portal sea diferente y no consideramos que valga la pena renderizarlo en el servidor.

Es probable que volvamos a esto junto con la renovación del renderizador del servidor para el suspenso.

Los portales son, conceptualmente, componentes exclusivos para el cliente; se utilizan para cosas como modales que uno generalmente no querría renderizar en el servidor; también toman un elemento dom, que renderToString no lo hace porque no hay dom. No veo cómo se puede hacer algo significativo con ellos en el servidor, simplemente no veo nada valioso por lanzar.

usado para cosas como modales

Ese es un caso de uso, pero también hay otros como barras laterales y similares que no son necesariamente solo para el cliente.

también toman un elemento dom

Correcto, en el diseño actual. Podría cambiar. https://github.com/facebook/react/pull/8386#issuecomment -262375265

Tampoco veo nada valioso en el lanzamiento.

El valor de lanzar es reconocer explícitamente que el portal no funcionará. Puede solucionarlo fácilmente con {domNode && ReactDOM.createPortal(stuff, domNode)} o similar. Debido a que ya tuvo que hacer algún tipo de verificación para determinar si puede obtener el nodo DOM, por lo que en este punto debe tener suficientes datos para elegir no emitir el portal.

Me gustaría solucionar este problema como mi "buen primer problema".

+1

¿Puedo trabajar en este problema?

Por supuesto. Supongo que puedes. ¿Qué tan lejos has ido? De hecho, estoy pensando en recogerlo también.

  • 2

Hola amigos, cualquier idea de cómo puedo encontrar el archivo donde está el problema, puedo conseguirlo, por favor, ayuda.

Hola, aquí está la solicitud de extracción parcial para este problema
https://github.com/facebook/react/pull/15473

¿Alguien todavía está en esto? Me encantaría asumirlo.

¿Cuál es el estado de esto? ¿Cómo podría reproducirlo?

¿Sigue siendo un problema?

Tampoco he recibido una respuesta sobre este tema.

Creo que el estado de este problema aún está abierto.

¿Puedo ocuparme de este problema?

Hola, ¿alguien está trabajando en este problema? Si no, me gustaría tomarlo.

si nadie está trabajando en eso, puedo

¿Sigue siendo un problema? Parece que se hicieron intentos para solucionarlo, pero el problema subyacente es que algunas personas realmente quieren que los portales funcionen en la representación del lado del servidor. Si ese es el caso, ¿se puede cerrar este problema?

Agregar un elemento div debería funcionar bien

`class Para extiende React.Component {
render () {
regreso (

Algún texto
)

}
} `

¿Fue útil esta página
0 / 5 - 0 calificaciones