2

I am having an issue where the data from fetch was pass to a client-side component.

    'use server';
    const Page = () => {
      const data = awaits fetch(dataUrl)
      if (!res.ok) {
           throw error
      }
      return (
          <>
            <Comp1 data={data}>  //server-side 
            <Comp2 data={data}>  //client-side
          </>
      )
    }
    'use client';
    const Comp2 = (data) => {
       console.log("data", data)
       const [hero, setHero] = useState('')

       useEffect(() => {
          if (data.hero) {
             setHero(`${data.hero} - hero`)
          }
       }, [data])
    
       return (
          <div>
              <h1>data.header</h1> // makes them empty 
              <DataHero hero={hero} /> // makes them empty since first data is empty but wont render again
          </div>
       )
    }

In terminal

    "data" undefined
    "data" data: {
        header: 'Tess'
        hero: 'Mordert'
    }

I tried the following but failed:

  1. JSON.parse(JSON.stringify(data))
  2. make it into server - serverWrapper - client component //props drilling
  3. useState
  4. useMemo
  5. lazy loading - stuck up on loading and wont render anything.

The only thing work was make the client into server but I don't want this since there are still components custom hooks to be include in Comp2 in later requirements and also the results are reverse from console.log.

Result in console.log

    "data" data: {
        header: 'Tess'
        hero: 'Mordert'
    }
    "data" undefined

2 Answers 2

2

The issue is your Comp2 accept a single argument, a props object.

const Comp2 = (data) => {

This receives the entire props object as data, not the data prop itself. The correct syntax need destructuring.

const Comp2 = ({data}) => {

When using (data) instead of ({data})

  1. The parameter receives the entire props object: {data: {...}}
  2. Attempting to access data.hero actually tries to access props.data.hero
  3. Since prop doesn't have a direct hero property, it returns undefined

Also another thing is the use server directive at the top of is incorrect for a page component. Page are server components by default in Next.js App Router.

Also there is a typo awaits instead of await. Not sure whether it is caused by when you post the question here.

So the correct implementation would be (assuming it app router),

// app/page.jsx - Server Component (no 'use server' needed)
const Page = async () => {
  const res = await fetch(dataUrl)
  const data = await res.json()
  
  if (!res.ok) {
    throw new Error('Failed to fetch data')
  }
  
  return (
    <>
      <Comp1 data={data} />
      <Comp2 data={data} />
    </>
  )
}

// components/Comp2.jsx - Client Component
'use client'
import { useState, useEffect } from 'react'

const Comp2 = ({ data }) => {  // ← CRITICAL FIX: Destructure props properly
  console.log("data", data)
  const [hero, setHero] = useState('')
  
  useEffect(() => {
    if (data?.hero) {
      setHero(`${data.hero} - hero`)
    }
  }, [data])
  
  return (
    <div>
      <h1>{data?.header}</h1>
      <DataHero hero={hero} />
    </div>
  )
}
Sign up to request clarification or add additional context in comments.

Comments

0

Destructure works.

Instead using inline, I tried to use the type instead so that I can destructure the props inside component not in props because this will make it long if I add another values.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.