La ventana no está definida en la aplicación Next.js React

Resuelto Leon Gaban asked hace 5 años • 30 respuestas

En mi aplicación Next.js parece que no puedo acceder window:

Rechazo no controlado (ReferenceError): la ventana no está definida

componentWillMount() {
    console.log('window.innerHeight', window.innerHeight);
}

Ingrese la descripción de la imagen aquí

Leon Gaban avatar Mar 14 '19 03:03 Leon Gaban
Aceptado

̶A̶n̶o̶t̶h̶e̶r̶ ̶s̶o̶l̶u̶t̶i̶o̶n̶ ̶i̶s̶ ̶b̶y̶ ̶u̶s̶i̶n̶g̶ ̶ ̶ p̶r̶o̶c̶e̶s̶s̶.̶b̶r̶o̶w̶s̶e̶r̶t̶o̶ ̶j̶u̶s̶s̶ ̶e̶x ̶e̶c̶u̶t̶e̶ ̶ ̶y̶o̶u̶r̶ ̶c̶o̶m̶m̶a̶n̶d̶ ̶d̶u̶r̶i̶n̶g̶ ̶r̶e̶n̶d̶e̶r̶i̶n̶g̶ ̶o̶n̶ ̶t̶ h̶e̶ ̶c̶l̶i̶e̶n̶t̶ ̶s̶i̶d̶e̶ ̶o̶n̶l̶y̶.

Pero processel objeto ha quedado obsoleto en Webpack5 y también en NextJS, porque es una variable de NodeJS solo para el lado backend.

Entonces tenemos que usar windowel objeto back desde el navegador.

if (typeof window !== "undefined") {
  // Client-side-only code
}
Expandir fragmento

Otra solución es utilizar el gancho de reacción para reemplazar componentDidMount:

useEffect(() => {
    // Client-side-only code
})
Expandir fragmento

Darryl RN avatar Mar 16 '2019 11:03 Darryl RN

Si usa React Hooks, puede mover el código al Effect Hook :

import * as React from "react";

export const MyComp = () => {

  React.useEffect(() => {
    // window is accessible here.
    console.log("window.innerHeight", window.innerHeight);
  }, []);

  return (<div></div>)
}

El código interno useEffectsolo se ejecuta en el cliente (en el navegador), por lo que tiene acceso a window.

Rotareti avatar Dec 19 '2019 03:12 Rotareti

Mover el código de componentWillMount()a componentDidMount():

componentDidMount() {
  console.log('window.innerHeight', window.innerHeight);
}

En Next.js, componentDidMount()se ejecuta solo en el cliente donde windowestarán disponibles otras API específicas del navegador. De la wiki de Next.js :

Next.js es universal, lo que significa que ejecuta código primero en el lado del servidor y luego en el lado del cliente. El objeto de ventana solo está presente en el lado del cliente, por lo que si es absolutamente necesario tener acceso a él en algún componente de React, debe colocar ese código en componenteDidMount. Este método de ciclo de vida solo se ejecutará en el cliente. También es posible que desees comprobar si no existe alguna biblioteca universal alternativa que pueda satisfacer tus necesidades.

En la misma línea, componentWillMount()quedará obsoleto en la versión 17 de React, por lo que efectivamente será potencialmente inseguro de usar en un futuro muy cercano.

Alexander Staroselsky avatar Mar 13 '2019 21:03 Alexander Staroselsky