Mr *_*tar 7 leaflet reactjs server-side-rendering next.js
我目前正在使用传单包构建一个网站。然而这个包需要 window 对象。这就是为什么我将使用 leaflet 制作的组件导入为关闭 ssr 的动态组件。像这样:
import dynamic from "next/dynamic";
const MapWithNoSSR = dynamic(() => import("../../map"), {
ssr: false
});
export default function faqOnly(props){
...
return (<> <MapWithNoSSR /></>)
}
Run Code Online (Sandbox Code Playgroud)
地图组件如下所示:
import React, { useEffect, useState, useRef } from "react";
import { OpenStreetMapProvider } from 'leaflet-geosearch';
import "leaflet/dist/leaflet.css";
import 'leaflet/dist/leaflet.css'
import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css'
import "leaflet-defaulticon-compatibility";
import dynamic from "next/dynamic";
const L = dynamic(() => import("leaflet"), {
ssr: false,
suspense: true,
loading: () => <p>...</p>
});
function Map(props) {
useEffect(async () => {
if(window === undefined) return
const provider = new OpenStreetMapProvider();
const results = await provider.search({ query: props.adress });
if(results.length > 0 == true){
var map = L.map('map', {
center: [results[0].y, results[0].x],
zoom: 18,
layers: [
L.tileLayer('https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png', {
attribution: ''
}),
]
})
L.marker([results[0].y, results[0].x]).addTo(map)
}else{
document.getElementById("map").style.display = "none"
}
}, [])
return <div id="map" style={{ height: "30vh"}}></div>
}
export default Map;
Run Code Online (Sandbox Code Playgroud)
当我运行时出现此错误npm run build:
ReferenceError: window is not defined
at E:\Github\Planer\rl-planer\node_modules\leaflet\dist\leaflet-src.js:230:19
at E:\Github\Planer\rl-planer\node_modules\leaflet\dist\leaflet-src.js:7:66
at Object.<anonymous> (E:\Github\Planer\rl-planer\node_modules\leaflet\dist\leaflet-src.js:10:3)
at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (E:\Github\Planer\rl-planer\node_modules\leaflet-geosearch\dist\geosearch.js:1:7) {
type: 'ReferenceError'
}
Run Code Online (Sandbox Code Playgroud)
这在开发中工作得很好,但是当我尝试构建项目(下一个构建)时,它会在传单包内抛出“窗口未定义”错误,而我之前在开发中处理它时它没有这样做过模式。
我在这里查看了其他问题,但似乎将动态导入移到组件之外为除了我之外的每个人修复了它。我只是愚蠢还是这里有什么问题?
也许你根本不需要,next/dynamic只需在内部使用简单的 js 动态导入即可useEffect即可。
(useEffect仅在客户端运行)
Nextjs 有一个看起来非常相似的示例:https ://nextjs.org/docs/advanced-features/dynamic-import。(第一个带有fuse.js的页面)
\nimport React, { useEffect, useState, useRef } from "react";\nimport { OpenStreetMapProvider } from \'leaflet-geosearch\';\nimport "leaflet/dist/leaflet.css";\nimport \'leaflet/dist/leaflet.css\'\nimport \'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css\'\nimport "leaflet-defaulticon-compatibility";\n\nfunction Map(props) {\n useEffect(async () => {\n const L = await import("leaflet")\n const provider = new OpenStreetMapProvider();\n const results = await provider.search({ query: props.adress });\n\n if(results.length > 0 == true) {\n var map = L.map(\'map\', {\n center: [results[0].y, results[0].x],\n zoom: 18,\n layers: \n [\n L.tileLayer(\n \'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png\',\n { attribution: \'\'}\n ),\n ]\n })\n L.marker([results[0].y, results[0].x]).addTo(map)\n } else {\n document.getElementById("map").style.display = "none"\n }\n }, [])\n\n\n return <div id="map" style={{ height: "30vh"}}></div>\n}\n\nexport default Map;\nRun Code Online (Sandbox Code Playgroud)\n好吧,也许尝试在 useEffect 挂钩中移动需要窗口的所有 js 有点混乱。\n仅导入整个组件客户端会更容易。\n对我来说,除了事实之外,你的示例代码看起来不错 \xe2\x80\x93您在地图文件中再次动态导入传单:
\n页面.jsx
\nimport dynamic from "next/dynamic";\nconst MapWithNoSSR = dynamic(() =>\n import("../../map"), { ssr: false });\n \nexport default function faqOnly(props){\n ...\n return <MapWithNoSSR />\n}\nRun Code Online (Sandbox Code Playgroud)\n地图.jsx
\nimport React, { useEffect, useState, useRef } from "react";\nimport { OpenStreetMapProvider } from \'leaflet-geosearch\';\nimport L from \'leaflet\'\nimport "leaflet/dist/leaflet.css";\nimport \'leaflet/dist/leaflet.css\'\nimport \'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css\'\nimport "leaflet-defaulticon-compatibility";\n\nfunction Map(props) {\n useEffect(async () => {\n const provider = new OpenStreetMapProvider();\n const results = await provider.search({ query: props.adress });\n\n if(results.length > 0 == true) {\n var map = L.map(\'map\', {\n center: [results[0].y, results[0].x],\n zoom: 18,\n layers: \n [\n L.tileLayer(\n \'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png\',\n { attribution: \'\'}\n ),\n ]\n })\n L.marker([results[0].y, results[0].x]).addTo(map)\n } else {\n document.getElementById("map").style.display = "none"\n }\n }, [])\n\n\n return <div id="map" style={{ height: "30vh"}}></div>\n}\n\nexport default Map;\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
9940 次 |
| 最近记录: |