You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 06:01:13