You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js页面中使用外部JavaScript变量?已尝试方案遇未定义问题

问题:外部JS变量传递到Next.js页面失败

我正在开发一个展示项目排名的网页,通过外部JavaScript文件获取数据,在Next.js页面中用<Script>标签引入该脚本。由于脚本依赖window变量,没法改成服务器端执行的API。

我想把外部JS里的items数组变量在页面中用{items.map(...)}渲染,但尝试后一直提示items未定义。


我尝试过的代码

weeklyRanking.js

let items = [item1, item2, item3];
window.items = items;

page.jsx

import Script from 'next/script'
import { useState, useEffect } from 'react'

const page = () => {
  const [items, setItems] = useState([]);
  
  useEffect(() => {
    setItems(window.items)
  }, [])
  
  return (
    <>
    {items.map((item)=>(
    <div key={item}>{item}</div>
    ))}
    <Script src="/weeklyRanking.js" />
    </>
  )
}

export default page

解决方法

问题核心是脚本加载时机不匹配:Next.js的<Script>默认加载策略可能导致脚本在useEffect执行后才完成加载,此时window.items还未被定义。下面是两种可靠的修复方案:

方案一:指定脚本提前加载(仅Pages Router支持)

把<Script>的strategy设为beforeInteractive,让脚本在页面可交互前就加载完成,确保useEffect执行时window.items已经存在:

import Script from 'next/script'
import { useState, useEffect } from 'react'

const page = () => {
  const [items, setItems] = useState([]);
  
  useEffect(() => {
    if (window.items) {
      setItems(window.items)
    }
  }, [])
  
  return (
    <>
      {items.map((item)=>(
        <div key={item}>{item}</div>
      ))}
      <Script 
        src="/weeklyRanking.js" 
        strategy="beforeInteractive" 
      />
    </>
  )
}

export default page

方案二:用脚本加载回调获取数据(通用方案)

通过<Script>的onLoad属性,在脚本完全加载后再读取变量,这个方法同时支持Pages Router和App Router:

import Script from 'next/script'
import { useState } from 'react'

const page = () => {
  const [items, setItems] = useState([]);
  
  const handleScriptLoad = () => {
    if (window.items) {
      setItems(window.items)
    }
  }
  
  return (
    <>
      {items.map((item)=>(
        <div key={item}>{item}</div>
      ))}
      <Script 
        src="/weeklyRanking.js" 
        onLoad={handleScriptLoad} 
      />
    </>
  )
}

export default page

额外检查

确保weeklyRanking.js里的数组元素是实际有效值,比如字符串:

// 修正后的weeklyRanking.js
let items = ["项目1", "项目2", "项目3"];
window.items = items;

内容的提问来源于stack exchange,提问作者boketeボケて

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 08:35:11