Next.js Hydration Error求助:服务端渲染UI不匹配报错
Next.js Hydration Error 解决方案
问题描述
Hydration failed because the initial UI does not match what was rendered on the server. Expected server HTML to contain a matching
in
编写了从TMDB API获取电影数据的Next.js代码,运行时持续触发上述Hydration错误,无论在div或p标签中编写任何内容都会出现该错误。
问题代码
import Image from "next/image"; import { Inter } from "next/font/google"; import { Suspense, use } from "react"; import styles from "./page.module.css"; const inter = Inter({ subsets: ["latin"] }); async function loadMovies() { const url = `https://api.themoviedb.org/3/movie/popular?api_key=70b45bfec667a0c7cbfbad1a496bc748`; const data = await fetch(url); if (!data.ok) { // This will activate the closest `error.js` Error Boundary throw new Error('Failed to fetch data'); } const res = await data.json() let titles = [] res.results.map((data) => { titles.push(data.title) }) return titles; } export default async function Home() { const titles = await loadMovies() console.log(titles); return ( <div> <p>Movies</p> {titles.map((title, index) => { return(<p key={index}>{title}</p>); })} </div> ); }
解决方案
原因分析
在Next.js App Router的服务器组件中,直接执行console.log会触发Hydration不匹配:服务器渲染阶段会执行该日志,客户端Hydration阶段也会重复执行,这种跨端不一致的副作用会触发React的Hydration校验机制,导致错误。虽然代码中使用async/await获取数据是服务器组件的合法用法,但console.log是本次错误的核心诱因。
修复步骤
- 移除跨端不一致的副作用:删除
Home组件中的console.log(titles);,避免客户端与服务器执行逻辑出现差异。 - 简化数据处理逻辑:将手动push数组的方式改为直接利用
map返回结果,优化代码可读性(非错误根源,但属于代码优化)。
修复后的代码
import Image from "next/image"; import { Inter } from "next/font/google"; import { Suspense, use } from "react"; import styles from "./page.module.css"; const inter = Inter({ subsets: ["latin"] }); async function loadMovies() { const url = `https://api.themoviedb.org/3/movie/popular?api_key=70b45bfec667a0c7cbfbad1a496bc748`; const data = await fetch(url); if (!data.ok) { throw new Error('Failed to fetch data'); } const res = await data.json(); // 简化电影标题提取逻辑 return res.results.map((movie) => movie.title); } export default async function Home() { const titles = await loadMovies(); return ( <div> <p>Movies</p> {titles.map((title, index) => ( <p key={index}>{title}</p> ))} </div> ); }
额外注意事项
- 若需在客户端执行操作,必须用
useEffect包裹,确保仅在客户端渲染完成后执行,避免Hydration阶段出现不一致。 - 服务器组件中禁止出现任何会导致客户端与服务器行为差异的副作用(如无条件日志、全局变量修改等)。
内容的提问来源于stack exchange,提问作者Ahmed Burhan
相关产品推荐
相关产品推荐

