web-dev-qa-db-fra.com

React Problème côté serveur JS - fenêtre introuvable

Salut, j'essaie d'utiliser react-rte dans mon projet reactJS. J'ai un rendu côté serveur et chaque fois que je veux utiliser ce package, je reçois:

return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
                               ^
ReferenceError: window is not defined

Je suppose que le problème pourrait être avec les outils isomorphes mais je ne sais pas comment reporter l'importation du package au client où la fenêtre va déjà être définie.

10
Jan Omacka

Si vous effectuez un rendu côté serveur, il y a de fortes chances que l'objet de fenêtre globale ne soit pas défini car c'est seulement quelque chose que le client comprendra.

Remarque: Initialement, lorsque vous démarrez votre projet, il va afficher une chaîne complète de votre DOM (à ce stade, il ne connaît pas window car il est côté serveur, mais puis restituez avec le code côté client dans lequel votre objet fenêtre sera disponible!

Il existe une solution de contournement que j'utilise dans ce cas. Voici ce que j'ai pour mon plugin webpack:

new webpack.DefinePlugin({
  'process.env.NODE_ENV': isDevelopment ? '"development"' : '"production"',
  'process.env.BROWSER': JSON.stringify(true),
  __DEV__: isDevelopment
}),

J'utilise donc process.env.BROWSER à mon avantage car il sera défini comme undefined s'il est côté serveur, et il sera true si le côté client se fait en rendu.

Puisque tout cesse de fonctionner lorsqu'il n'y a pas d'objet fenêtre du côté serveur, nous pouvons ajouter ceci:

const mySpecialWindowFunction = () => {

  /* START HACK */
  if (!process.env.BROWSER) {
    global.window = {}; // Temporarily define window for server-side
  }
  /* END HACK */

  return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
};

De cette façon, votre console ne vous crie pas dessus et n'arrête pas le rendu côté serveur, sur lequel vous pouvez maintenant poursuivre votre glorieuse journée! Bien que je dois admettre que c'est un peu Hacky, mais cela fait le travail parce que tout ce que nous voulons faire est de laisser le côté serveur rendre la chaîne DOM initiale, puis laisser le côté client prendre plus de.

Remarque également: Ne vous inquiétez pas de définir la fenêtre comme un objet vide, elle reviendra à la normale une fois le rendu côté client terminé.

10
Tony Tai Nguyen

Voici une bibliothèque npm qui peut gérer la fenêtre, le document et l'objet global pour vous: Global .

Ensuite, vous pouvez écrire en toute sécurité:

import window from 'global'

const mySpecialWindowFunction = () => {
    return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
};
10
Natrezim

Lors du rendu côté serveur, les paramètres globaux tels que window, document ne seront pas définis. Et si vous voulez le faire de manière isomorphe, vous devez tester quel environnement est lors du rendu des composants.

https://github.com/DavidWells/isomorphic-react-example

de nombreux exemples de codes peuvent être trouvés sur github, le lien ci-dessus est l'un d'entre eux, j'espère qu'il peut être utile.

0
Littlee

J'ai essayé de le définir dans mes constantes en tant qu'importation globale:

export const GLOBAL_WINDOW = (typeof self === 'object' && self.self === self && self) || (typeof global === 'object' && global.global === global && global) || this;

Dans ce cas, il renvoie une fenêtre ou un objet global en fonction de la météo de votre exécution sur une application cliente ou un serveur.

Vous devez maintenant importer cette constante où vous voulez utiliser l'objet fenêtre.

Ex:

import { GLOBAL_WINDOW } from '../constants/Constants';

const user = JSON.parse(GLOBAL_WINDOW.localStorage.getItem('user'));
0
Vinayak humberi