Next.js 13集成Sanity预览模式报错:useReducer仅支持客户端组件
解决Next.js 13 + Sanity预览模式useReducer报错问题
核心原因:Next.js 13 App Router下默认所有组件都是服务器组件,而
useReducer属于React客户端钩子,只能在标记了"use client"的客户端组件中使用。具体修复步骤:
- 定位使用
useReducer的文件:找到预览功能里用到useReducer的组件(比如预览状态控制、预览内容渲染组件),在文件最顶部添加"use client";指令,注意要放在所有导入语句之前。 - 拆分逻辑:如果预览逻辑混合在服务器组件里,把需要客户端交互/状态管理的部分抽离到单独的客户端组件中,服务器组件只负责获取Sanity数据(包括预览模式下的draft数据)和渲染静态结构。
- 检查API路由:
/api/preview是服务器端API路由,本身不需要加"use client",但要确保该路由里没有直接调用使用客户端钩子的组件——如果有,把那部分组件改为客户端组件。
- 定位使用
示例客户端组件代码:
"use client"; import { useReducer } from 'react'; const previewStateReducer = (state, action) => { switch (action.type) { case 'ENABLE_PREVIEW': return { ...state, active: true }; case 'DISABLE_PREVIEW': return { ...state, active: false }; default: return state; } }; export function PreviewController() { const [previewState, dispatch] = useReducer(previewStateReducer, { active: false }); const handleTogglePreview = async () => { if (previewState.active) { // 调用关闭预览的API逻辑 dispatch({ type: 'DISABLE_PREVIEW' }); } else { // 调用开启预览的API逻辑 dispatch({ type: 'ENABLE_PREVIEW' }); } }; return ( <button onClick={handleTogglePreview}> {previewState.active ? '关闭预览' : '开启实时预览'} </button> ); }
内容的提问来源于stack exchange,提问作者abelamos
相关产品推荐
相关产品推荐

