NextJS14 App Router中如何结合useState实现游戏描述SSR?
解决方案:拆分组件实现SEO内容SSR+客户端交互
核心思路是拆分组件,将需要SEO的游戏描述放在服务端组件中,仅把按钮交互和游戏切换逻辑保留在客户端组件里,让两者各司其职。
步骤1:创建服务端渲染的游戏描述组件
新建一个无"use client"标识的组件,默认就是服务端组件,专门渲染对SEO友好的游戏描述:
// app/game/GameDescription.jsx export default function GameDescription() { return ( <div className="game-description"> <h2>你的游戏名称</h2> <p>这里是游戏的详细介绍内容,会被服务端渲染,搜索引擎可以直接抓取到</p> {/* 其他需要SEO的文本、标签都可以放在这里 */} </div> ); }
步骤2:保留客户端组件处理交互逻辑
修改原有的StartButton组件,只负责按钮点击和游戏切换的状态管理,不再包含描述内容:
"use client"; import { useState } from "react"; import Game from "./Game"; export default function GameController() { const [gameStarted, setGameStarted] = useState(false); return ( <> {!gameStarted && ( <button onClick={() => setGameStarted(true)} className="start-game-btn" > 开始游戏 </button> )} {gameStarted && <Game />} </> ); }
步骤3:在页面组件中组合两者
页面组件默认是服务端组件,可以直接引入并组合上述两个组件,实现SEO内容SSR+客户端交互:
// app/game/page.jsx import GameDescription from "./GameDescription"; import GameController from "./GameController"; export default function GamePage() { return ( <div className="game-page-container"> {/* 游戏描述由服务端渲染,对SEO友好 */} <GameDescription /> {/* 按钮和游戏切换由客户端组件处理交互 */} <GameController /> </div> ); }
进阶:点击按钮后隐藏描述
如果需要点击开始按钮后隐藏游戏描述,可以将描述作为props传递给客户端组件,由客户端状态控制显示:
// 修改GameController组件 "use client"; import { useState } from "react"; import Game from "./Game"; export default function GameController({ description }) { const [gameStarted, setGameStarted] = useState(false); return ( <> {!gameStarted && ( <div> {description} <button onClick={() => setGameStarted(true)}>开始游戏</button> </div> )} {gameStarted && <Game />} </> ); }
// 修改页面组件 // app/game/page.jsx import GameController from "./GameController"; export default function GamePage() { // 描述内容在服务端生成,会被SSR渲染 const gameDescription = ( <div className="game-description"> <h2>你的游戏名称</h2> <p>这里是游戏的详细介绍内容,会被服务端渲染,搜索引擎可以直接抓取到</p> </div> ); return ( <div className="game-page-container"> <GameController description={gameDescription} /> </div> ); }
关键原理
Next.js 14 App Router中,服务端组件和客户端组件可以无缝组合:
- 服务端组件负责渲染静态/SEO友好内容,直接在服务端生成HTML
- 客户端组件仅处理状态、交互逻辑,不会影响服务端渲染的内容
内容的提问来源于stack exchange,提问作者Codiving
相关产品推荐
相关产品推荐

