окно не определено - Next.js 13 - Клиентский компонент в серверном компоненте -

Листовка импортируется в файл, который импортируется в клиентский компонент, так почему же сервер запускает ее и выдает эту ошибку?

Это действительно работает после повторной попытки и в конечном итоге отображает сайт нормально.

Я попытался использовать динамический импорт внутриuseEffect... без игральных костей.

      
ReferenceError: window is not defined
    at eval (webpack-internal:///(sc_client)/./node_modules/leaflet/dist/leaflet-src.esm.js:305:17)
    at Object.(sc_client)/./node_modules/leaflet/dist/leaflet-src.esm.js (path/to/app.next/server/app/page.js:473:1)
    at __webpack_require__ (path/to/app.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///(sc_client)/./src/js/index.js:5:89)
    at Object.(sc_client)/./src/js/index.js (path/to/app.next/server/app/page.js:1845:1)
    at __webpack_require__ (path/to/app.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///(sc_client)/./src/components/Foo.jsx:9:70)
    at Object.(sc_client)/./src/components/Foo.jsx (path/to/app.next/server/app/page.js:1834:1)

# more logs ...
      // app/page.js

import Foo from '@components/Foo';

export default function Base() {
  return (
    <main>
      <Foo />
    </main>
  );
}
      // components/Foo.jsx

'use client';

import { useEffect } from 'react';
import { test } from '../js/index.js';

export default function Foo() {
  useEffect(() => {
    test();
  }, []);
  return <div>foo</div>;
}


      // js/index.js

// Error thrown here cause calling window
import * as L from 'leaflet/dist/leaflet-src.esm.js';

const test = () => {
  console.log(L);
};

export { test };


1 ответ

Причина ошибки сервера в клиентском компоненте хорошо описана в комментарии в обсуждении репозитория Next.js:

Существует путаница в отношении директивы клиента. Это означает, что этот компонент также работает на клиенте. Я видел много материалов, в которых говорится только. Скорее клиентские компоненты похожи на компоненты, которые мы написали ранее. Чтобы отправить полный HTML-фрейм с сервера, на сервере также запускаются клиентские компоненты!

Когда вы пробовали динамический импорт, вы указалиssr: falseвариант? Вот исключение из главы документации Next.js «Без SSR»:

Чтобы динамически загружать компонент на стороне клиента, вы можете использовать опцию ssr, чтобы отключить рендеринг на сервере. Это полезно, если внешняя зависимость или компонент зависит от API-интерфейсов браузера, таких какwindow.

      import dynamic from 'next/dynamic';
 
const DynamicHeader = dynamic(() => import('../components/header'), {
  ssr: false,
});
Другие вопросы по тегам