Next.js开发正常但生产构建时useAddress()返回undefined如何修复
问题根因
这个异常由两个核心原因导致:
- 开发环境下控制台先后打印两次
undefined属于正常现象:React严格模式默认会双执行组件渲染逻辑,加上thirdweb SDK的钱包状态初始化是异步流程,前两次渲染时SDK还没完成连接状态同步,等初始化完成后就能正常返回钱包地址。 - 生产环境下
useAddress()始终返回undefined,本质是Next.js生产构建默认开启静态预渲染(SSG)/服务端渲染(SSR),而thirdweb的钱包连接逻辑只能在浏览器客户端环境运行——构建阶段没有window对象、没有钱包实例,如果你没有做客户端渲染适配、也没有正确配置ThirdwebProvider的全局包裹,生产环境页面水合后不会正常同步钱包状态,就会一直返回undefined。
修复方案
第一步:检查全局Provider配置
打开pages/_app.js(或pages/_app.tsx),确保ThirdwebProvider包裹在所有页面组件的最外层,不要在单个页面内单独声明Provider,参考配置:
import { ThirdwebProvider } from "@thirdweb-dev/react"; import "../styles/globals.css"; // 替换为你项目实际使用的链 const activeChain = "ethereum"; function MyApp({ Component, pageProps }) { return ( <ThirdwebProvider activeChain={activeChain}> <Component {...pageProps} /> </ThirdwebProvider> ); } export default MyApp;
注意:如果自定义了supportedWallets参数,确保你项目中用到的钱包已经加入配置列表,否则SDK不会识别对应钱包的连接状态。
第二步:强制首页组件客户端渲染
钱包状态属于纯客户端态,不需要做服务端预渲染,直接关闭对应页面的SSR即可,根据你用的Next.js路由模式二选一:
Pages Router 适配方案
修改首页代码,用next/dynamic动态导出组件,关闭ssr:
import { useAddress } from "@thirdweb-dev/react"; import Head from 'next/head'; import Link from 'next/link'; import Username from '../components/Username'; import React from "react"; import dynamic from "next/dynamic"; const Home = () => { const address = useAddress(); console.log(address) return address ? ( <> <Head> <title>home</title> <link rel="icon" href="/drum.svg" /> </Head> <Username address={address} /> </> ) : ( <> <Head> <title>home</title> <link rel="icon" href="/drum.svg" /> </Head> <Link href="/"> <a className="absolute pt-1 text-xl font-semibold transform -translate-x-1/2 top-1/2 left-1/2">click here to log in</a> </Link> </> ) } // 关键配置:关闭SSR,强制组件仅在客户端渲染 export default dynamic(() => Promise.resolve(Home), { ssr: false });
App Router(Next.js 13+)适配方案
如果用的是app目录下的页面,直接在文件最顶部加客户端指令即可,不需要动态导入:
'use client'; // 加在文件第一行 import { useAddress } from "@thirdweb-dev/react"; // 其余业务代码不变
额外排查项
如果完成上面两步后问题仍存在,逐一检查以下配置:
- 确认
@thirdweb-dev/react和Next.js的版本兼容,不要跨大版本混用依赖 - 生产环境如果部署在非localhost域名,必须配置HTTPS,否则钱包插件会拒绝连接请求,SDK拿不到授权后的地址
- 不要在服务端组件/服务端执行逻辑里调用
useAddress等钱包相关钩子
内容的提问来源于stack exchange,提问作者user19333414
相关产品推荐
相关产品推荐

