Next.js客户端组件无法使用async/await获取Sanity CMS数据求助
解决Next.js客户端组件中Sanity数据异步查询问题
首先纠正一个关键误解:Next.js客户端组件仅禁止将组件本身定义为async函数,事件处理函数、useEffect等逻辑中完全可以使用async/await,你之前的问题并非源于客户端组件不支持异步,而是代码存在其他错误。
错误点修正与完整解决方案
1. 拆分状态与修正事件处理逻辑
输入框的内容状态和搜索结果状态需要分开,避免输入内容被查询结果覆盖;同时要正确获取input的实时输入值:
'use client'; import { useState } from "react"; import { BiSearch } from "react-icons/bi"; import { getData } from "./test"; const Navbar = () => { // 拆分输入值和搜索结果状态 const [inputValue, setInputValue] = useState(""); const [searchResults, setSearchResults] = useState([]); // 修正异步事件处理函数 const handleChange = async (e: React.ChangeEvent<HTMLInputElement>) => { const currentValue = e.target.value; setInputValue(currentValue); // 空输入时清空结果,避免无效查询 if (!currentValue.trim()) { setSearchResults([]); return; } try { const results = await getData(currentValue); setSearchResults(results); } catch (err) { console.error("搜索请求失败:", err); setSearchResults([]); } } return ( <> {/* 搜索栏 */} <BiSearch /> <input type="text" value={inputValue} onChange={handleChange} placeholder="输入标题搜索..." /> {/* 显示搜索结果 */} <div className="search-results"> {searchResults.length === 0 ? ( <p>暂无匹配结果</p> ) : ( <ul> {searchResults.map((item, index) => ( <li key={index}>{item.title}</li> ))} </ul> )} </div> </> ) }; export default Navbar;
2. 修正Sanity GROQ查询语法
字符串匹配需要用引号包裹,否则会被Sanity解析为变量而非字符串值:
import { client } from "@/lib/sanityClient"; export const getData = async (title: string) => { // 给匹配的title值添加双引号,符合GROQ语法规范 const response = await client.fetch(`*[title == "${title}"]`); return response; };
额外说明
- 客户端组件允许在事件处理、useEffect等逻辑中使用async/await,仅组件本身不能定义为async函数。
- 增加错误处理可以避免查询失败导致页面异常,提升稳定性。
- 拆分状态能保证输入框的交互逻辑正常,不会出现输入内容被结果覆盖的问题。
内容的提问来源于stack exchange,提问作者Athar Naveed
相关产品推荐
相关产品推荐

