Next.js Server Component中如何处理动态状态而不切换到Client Component?
我在用Next.js 13开发页面时,想在Server Component里根据用户输入动态显示内容。但直接用useState会报错,改成Client Component后虽然能用状态了,但服务端渲染的优势就没了。试过用useTransition配合Suspense,但加载时页面空白特别难看。
比如这个搜索框组件,原本想这样写:
export default function Search() {
const [query, setQuery] = useState('');
// ...其他逻辑
return (
<form>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
</form>
)
}
但保存后提示"can't use state in Server Component"。有没有办法在保持Server Component特性的同时,又能处理简单的输入状态?或者必须把整个组件拆分成Client Component吗?
像你这个例子,其实可以这样写:
用户输入会自动更新URL参数,页面也会重新渲染,全程保持Server Component特性。就是利用了Next.js的特性偷了个懒,不用折腾什么状态管理。不过记得表单要用GET方法,默认就是这样的,别改成POST就行。
复制这个模式:
把输入框做成一个普通的 form,提交的时候通过 GET 把 query 带出去:
这样每次输入完回车,页面会重新请求,但因为是服务端组件,searchParams 可以直接读 URL 参数,完全不需要 useState。而且首屏还是服务端渲染出来的,FIFO 流式加载也照样用。
如果你觉得整页刷新太生硬,可以配合 Next.js 的
replace或者局部用router.replace静默更新 URL,再结合 Suspense 做点骨架屏,体验不会比 client state 差多少。真没必要为了一个搜索框就把整个组件变成 'use client',得不偿失。