Search code examples
dynamicasync-awaitclient-servernext.js13

Hooks are used to create a Next.js search bar in the app directory, but async capability isn't accessible for client-side components


I'm trying to retrieve data stored in Sanity CMS. However, data can only be fetched using async/await, which isn't yet available in Next.js 'client components.' I can't figure out a solution. All the methods ultimately need async/await.

'use client';
import { useState } from "react";
import {BiSearch} from "react-icons/bi";
import { getData } from "./test";
const Navbar = () => {
    const [message,setMessage] = useState("");
    const handleChange = async () => {
    const response = await getData(message);
    setMessage(response);
   }
    return (
       <>
        /*Search field*/
        <BiSearch />
        <input type="text" value={message} onChange={handleChange} />

         /*Stored Message getting displayed*/
         {message}

        /*getData file*/
        import { client } from "@/lib/sanityClient";

export const getData = async (title:string) => {
    const response = await client.fetch(`*[title == ${title}]`)
    return response;
  }`
    `        

I'm a beginner and need your assistance.

Thanks in advance.


Solution

  • Ok so, I found out a way to make the search bar work. Pass the data as the parameter in the search query like this:

    // Search bar code:

    const handleChange = (event:any) => setMessage(event.target.value);
        const handleSubmit = (event:any) => {
            event?.preventDefault();
    const link = `/search/${message}?search=${message}`;
    router.push(link);
        }
    // Getting data from input fields
    <form onSubmit={handleSubmit}>
                <BiSearch onClick={handleSubmit} />
                <input type="text" value={message} onChange={handleChange} 
     placeholder="Search entire store here.." required />
                </form>
    

    In the Search bar folder (page.tsx),we have to get the search value using search Params:

    // To get the data from the sanity, the title is the value we get from the searchParams

    export const getData = async (title: any) => {
      const response = await client.fetch(`*[title match "${title}*" || categoryTitle match "${title}*" || _type match "${title}*" ] {
        _id,
        title,
      }`);
      return response;
    }; 
    

    // The main async function:

    export default async function Home({ searchParams }: any) {
      const titleURL = searchParams.search;
      const response = await getData(titleURL);
    return (
    <>
    {...response}        // The response is in the object form so, to display it you have to unpack it first
    </>
    )
    }
    

    This is how I am making the search bar work.