29

こんにちは、reactJS プロジェクトで react-rte を使用しようとしています。サーバー側のレンダリングがあり、このパッケージを使用するたびに次のようになります。

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

問題は isomorphic-tools にあると思いますが、ウィンドウが既に定義されているクライアントへのパッケージのインポートを延期する方法がわかりません。

4

8 に答える 8

17

サーバー側のレンダリングを行っている場合、グローバル ウィンドウ オブジェクトが未定義になる可能性が高くなります。これは、クライアントが理解できるものにすぎないためです。

注:最初に、プロジェクトを開始すると、DOM の完全な文字列がレンダリングされます (この時点ではサーバー側であるため認識されませんがwindow、クライアント側のコードを使用して再レンダリングされます)。ウィンドウオブジェクトが利用可能になります!

この場合、私が使用している回避策があります。これは、webpack プラグイン用に用意したものです。

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

したがって、サーバー側であるかのように定義され、クライアント側でレンダリングが完了した場合process.env.BROWSERに定義されるため、私は有利に使用します。undefinedtrue

サーバー側にウィンドウ オブジェクトがない場合、すべてが機能しなくなるため、これを追加できます。

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

そうすれば、コンソールが悲鳴を上げることも、サーバー側のレンダリングを停止することもなく、輝かしい一日を続けることができます! これは少しハッキーであることは認めざるを得ませんが、やりたいことはサーバー側に最初の DOM 文字列をレンダリングさせ、クライアント側に引き継がせることだけなので、仕事は完了です。

また、注: window を空のオブジェクトとして設定することについて心配する必要はありません。クライアント側のレンダリングが完了すると、通常の状態に戻ります。

于 2016-10-09T04:04:30.173 に答える
1

サーバー側レンダリングを行う場合、グローバルな likeは未定義windowになります。documentまた、同形の方法でそれを行いたい場合は、コンポーネントをレンダリングするときの環境をテストする必要があります。

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

github には多くのサンプル コードがあります。上記のリンクはその 1 つです。お役に立てば幸いです。

于 2016-08-15T08:34:48.330 に答える