skip to Main Content

I’m simply trying to fetch data in Next js but facing some issues between client and server components.

  import { useSearchParams } from 'next/navigation';

  const searchParams = useSearchParams();
  const searchValue = searchParams.get('query');
  const url = `${process.env.NEXT_PUBLIC_REQUEST_URL}${searchValue}`;

Here I’m grabbing from searchParams necessary value for request. Since I’m using useSearchParams it’s a client component.

And here is the main issue, how to fetch? I tried many ways, like creating custom hook:

const { data, loading, error } = useFetch(searchValue);

Or just simply fetching it, like this:

const fetchFilms = async (url) => {
  const response = await fetch(url);
  return await response.json();
} 

But I get issue that async await can’t be used in client component.

So how I should be able to de it? If I make it server component I can’t grap necessary value from query params, and can’t do request, in other side I can’t do request.
Can you suggest something or maybe bring some materials?

2

Answers


  1. I’m pretty sure that you fetch normally in client components as with useEffect with some modifications. The important thing is that you won’t be able to use them like the way you do for server components, ie:

    export default async function Page() {
      const res = await fetch('https://...', { next: { tags: ['collection'] } })
      const data = await res.json()
      // ...
    }
    

    You will have to combine the fetching with useEffect hook and manage these data with useState hook for further interacting with the client componenets.

    'use client'
    import { useState, useEffect } from "react";
    
    export default function Page() {
      /* useState hook to store fetch data */
      const [data, setData] = useState(null);
    
      /* async function to fetch data */
      const fetchData = async () => {
        const res = fetch('https://...', { next: { tags: ['collection'] } })
        const data = await res.json()
        setData(data)
      };
    
      /* useEffect to call fetch function after the page is loaded */
      useEffect(() => {
        fetchData();
      }, []);
      
    
      return(
        //...
      )
    }
    

    Hope this can help!

    Login or Signup to reply.
  2. There are 2 ways (‘m thinking of) in which you can do this.

    First, with limited code change, you can drop async/await and fetch(...).then(...) in the client component.

    Second is to use server action. i.e.: an app/action.ts like

    'use server'
     
    export async function fetchFilms(url) {
      // await ...
    }
    

    then use it in the client

    'use client'
    import { fetchFilms } from '@/app/actions'
    import { useSearchParams } from 'next/navigation'
    ...
    
    useEffect(() => {
        const getFilms = async () => {
          const searchParams = useSearchParams();
          const searchValue = searchParams.get('query');
          const url = `${process.env.NEXT_PUBLIC_REQUEST_URL}${searchValue}`;
          const films = await fetchFilms(url)
          // Put the films in a local state or whatever you need
        }
     
        getFilms()
      }, [])
    ...
    

    You could fetch your external URL in the useEffect like shown above but the server action would bypass CORS issues.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search