繁体   English   中英

ReferenceError: Window 未定义 NextJS13 使用客户端不工作

[英]ReferenceError: Window is not defined NextJS13 use Client not working

我正在尝试将 NextJS 13 与 react-leaflet 一起使用。 当我运行我的组件时,我得到 window 未定义。 我尝试使用文件顶部的“使用客户端”并检查是否“typeof window.== undefined”但仍然没有运气,我没有在之前的代码片段中使用 isBrowser function。 但那是我最初使用的。

页面/censusmap.tsx

'use client';

import { type NextPage } from "next";
import { MapContainer,  TileLayer, GeoJSON } from 'react-leaflet';
// TODO: Fix this import to be from geojson and change the filename
import CensusTractData from "./data/census-tracts_min.json";
import 'leaflet/dist/leaflet.css';
import type {GeoJsonObject, Feature, Geometry} from "geojson";

const isBrowser = () => typeof window !== 'undefined';

const CensusTractMap: NextPage = () => {
  const getCensusTractFillColor = (population2020: number) => {
    if(population2020 <= 2500)
    {
      return "#bd93f9"
    }
    if(population2020 > 2500 && population2020 < 5000) {
      return "#ffb86c"
    }
    if (population2020 > 5000 && population2020 < 10000)
    {
      return "#8be9fd";
    }
    return undefined;
  }
  const censusTractStyle = (val: Feature<Geometry, {pop20: number}> | undefined) => {
    if(!val)
    {
      return {};
    }
    const pop20 = Number(val.properties.pop20);
    return {
                fillColor: getCensusTractFillColor(pop20),
                color: '#44475a',
                weight: 0.5,
                opacity: 1,
                fillOpacity: 0.4,
            }
  }
  return (
    <>
       <div id="map" className="h-180px">
      <MapContainer center={[20.5, -157.510857]} zoom={7} scrollWheelZoom={true}>
        <TileLayer
          attribution='&copy; "Map data © OpenStreetMap contributors, Esri Community Maps contributors, Map layer by Esri'
          url="https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}"
        />
        <GeoJSON data={CensusTractData as GeoJsonObject} style={(val: Feature<Geometry, {pop20: number}> | undefined) => censusTractStyle(val)}/>
      </MapContainer>
    </div>
    </>
  )
}

export default CensusTractMap
error - ReferenceError: window is not defined
    at ...\node_modules\leaflet\dist\leaflet-src.js:230:19
    at ...\node_modules\leaflet\dist\leaflet-src.js:7:66
    at Object.<anonymous> (...\node_modules\leaflet\dist\leaflet-src.js:10:3)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:170:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
    at async importModuleDynamicallyWrapper (node:internal/vm/module:437:15) {
  page: '/censusmap'

我认为 react-leaflet 使用 window 并且当你导入它时,它将使用 window (正如你在 ssr 中所知道的 window 是不安全的)

所以将所有 leaflet 相关代码添加到组件中并改用动态导入

像这样:

页面/censusmap.tsx

const CensusmapComponent = dynamic(() => import('../components/CensusmapComponent'), {
  loading: () => 'Loading...',
  ssr: false,
})

return (<CensusmapComponent/>)

Gensusmap组件:

import { MapContainer,  TileLayer, GeoJSON } from 'react-leaflet';
// TODO: Fix this import to be from geojson and change the filename
import CensusTractData from "./data/census-tracts_min.json";
import type {GeoJsonObject, Feature, Geometry} from "geojson";

const isBrowser = () => typeof window !== 'undefined';

const CensusTractMapComponent: React.FC = () => {
  const getCensusTractFillColor = (population2020: number) => {
    if(population2020 <= 2500)
    {
      return "#bd93f9"
    }
    if(population2020 > 2500 && population2020 < 5000) {
      return "#ffb86c"
    }
    if (population2020 > 5000 && population2020 < 10000)
    {
      return "#8be9fd";
    }
    return undefined;
  }
  const censusTractStyle = (val: Feature<Geometry, {pop20: number}> | undefined) => {
    if(!val)
    {
      return {};
    }
    const pop20 = Number(val.properties.pop20);
    return {
      fillColor: getCensusTractFillColor(pop20),
      color: '#44475a',
      weight: 0.5,
      opacity: 1,
      fillOpacity: 0.4,
    }
  }
  return (
      <>
        <div id="map" className="h-180px">
          <MapContainer center={[20.5, -157.510857]} zoom={7} scrollWheelZoom={true}>
            <TileLayer
                attribution='&copy; "Map data © OpenStreetMap contributors, Esri Community Maps contributors, Map layer by Esri'
                url="https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}"
            />
            <GeoJSON data={CensusTractData as GeoJsonObject} style={(val: Feature<Geometry, {pop20: number}> | undefined) => censusTractStyle(val)}/>
          </MapContainer>
        </div>
      </>
  )
}

export default CensusTractMapComponent

和 CSS 文件必须添加到 _app.js(如果它不是模块)

在 _app.js 中

 import 'leaflet/dist/leaflet.css';

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM