окно не определено - 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,
});