Next.js Server Component中使用useState为什么会报错?

Des.子璇 阅读 21

我在用Next.js 13的Server Component写一个搜索框,想用useState控制输入值,但一运行就报错说不能在服务器组件里使用状态钩子。我明明按照文档把组件标记成export default function Search() {...}这种形式,为啥还是不行?

尝试把组件改成客户端组件后能用了,但这样整个组件就全量客户端渲染了。有没有办法只让输入部分用客户端状态,其他部分保持服务端渲染?我试过在服务端组件里包裹suspense但没效果。


// 报错代码示例
export default function Search() {
  const [query, setQuery] = useState(''); // 这里报错
  return <input value={query} onChange={e => setQuery(e.target.value)} />;
}
我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
恩贝酱~
这个问题其实挺常见的,Next.js 13的Server Component和Client Component确实有一些区别需要注意。简单来说,Server Component是运行在服务端的,而useState是React的客户端钩子,只能在客户端组件里用,所以直接在Server Component里用useState肯定会报错。

如果你希望大部分逻辑保持在服务端渲染,只让输入框这部分用客户端状态,可以试试把输入框单独抽成一个客户端组件。比如这样:

// SearchInput.js - 客户端组件
'use client';
import { useState } from 'react';

export default function SearchInput() {
const [query, setQuery] = useState('');
return <input value={query} onChange={e => setQuery(e.target.value)} />;
}


然后在你的Server Component里引入这个客户端组件:

// Search.js - 服务端组件
import SearchInput from './SearchInput';

export default function Search() {
return (
<div>
<h1>搜索页面</h1>
<SearchInput />
<p>其他内容保持服务端渲染</p>
</div>
);
}


这样做的话,只有输入框部分会变成客户端渲染,其他部分还是服务端渲染,性能和架构上也比较合理。

其实Next.js 13的设计思路就是这样,尽量把不需要交互的部分留在服务端,只把需要状态管理或者事件处理的部分放到客户端。刚开始用可能会觉得有点麻烦,但习惯了就会发现这样分层其实挺清晰的。如果还有问题随时问,咱们一起琢磨!
点赞 1
2026-02-14 12:08