Search code examples
reactjsnext.jssupabasenext.js13

Rendering fetched data from supabase in Nextjs13 App Directory


I successfully fetched data from supabase but I am unable to render them in my component , I tried implemented a component to hold the fetched data but i was unable to as it arose to other errors then I decided to just render the fetched data in the same component which fetches data but also I was unable to render them . Any help would be greatly appreciated. Below is the source code I am using:

"use client"

import { useCallback, useEffect, useState } from "react"
import Search from "../search"
import { supabase } from "@/app/libs/supabase"
import { useRouter, useSearchParams } from "next/navigation"
import toast from "react-hot-toast"
import Profile from "@/components/profile/Profile"
import {NextResponse} from 'next/server'

// interface Array{
//    name:string;
// }

interface UserData{
  name:string;
  phone:string;
  email:string;
  prevState:null
}



export default function profile(){
 
  const [profiles,setProfile] = useState<any | null>(null)

    const router = useRouter()

    const res = NextResponse.next()

    useEffect(()=>{
     User()
    },[])

    const User =useCallback(async()=>{
      const {data:{user}} =  await supabase.auth.getUser()



      if(user){
        const{data} = await supabase.from("profiles").select().eq('email',user.email)
        if(data){
           setProfile(data)
          console.log(data)
        }
       
      }
      else{
        const load = toast.loading("Redirecting to Login Page")
           setTimeout(()=>{
            toast.dismiss(load)
           },500)
            router.push('/')
      }
    },[])

    return(
        <>
        <aside className='md:py-5'>
    <Search/>
    </aside>
        
        <section >
            <h4 className='text-bra text-2xl text-center md:text-3xl lg:text-3xl'>My Profile</h4>
            <div className="flex items-center justify-center">
             {profiles && profiles.map((profile: any)=>(<Profile key={profile._id} profile={profile}  />))}
           
            </div>
        </section>
        </>
    )
}

below is my Profile.tsx component

import React from 'react'
interface ProfileProps{
   name?:string;
   email?:string;
   phone?: string;
}

const profile: ProfileProps={}

const Profile:React.FC<ProfileProps> = () => {
 return (
   <div className='justify-center items-center flex flex-col bg-green-100'>
       <p>Name:{profile.name}</p>
       <p>Email:{profile.email}</p>
       <p>Phone:{profile.phone}</p>
   </div>
 )
}

export default Profile

Fetched data and render them in my component


Solution

  • I successfully fixed it by doing the following changes:

    "use client"
    
    import { useCallback, useEffect, useState } from "react"
    import Search from "../search"
    import { supabase } from "@/app/libs/supabase"
    import { useRouter, useSearchParams } from "next/navigation"
    import toast from "react-hot-toast"
    import Profile from "@/components/profile/Profile"
    import {NextResponse} from 'next/server'
    
    // interface Array{
    //    name:string;
    // }
    
    interface UserData{
      name:string;
      phone:string;
      email:string;
      prevState:null
    }
    
    
    
    export default function profile(){
      // const [profiles,setProfile] = useState<Record<string, any>[] | null>(null)
      // const [profiles,setProfile] = useState<UserData | null>(null)
      const [profiles,setProfile] = useState<any | null>(null)
    
        const router = useRouter()
    
        useEffect(()=>{
         User()
        },[])
    
        const User =useCallback(async()=>{
          const {data:{user}} =  await supabase.auth.getUser()
    
          if(user){
            const{data} = await supabase.from("profiles").select().eq('email',user.email)
            if(data){
               setProfile(data)
              console.log(data)
            }
           
          }
          else{
            const load = toast.loading("Redirecting to Login Page")
               setTimeout(()=>{
                toast.dismiss(load)
               },500)
                router.push('/')
          }
        },[])
    
        return(
            <>
            <aside className='md:py-5'>
        <Search/>
        </aside>
            
            <section  >
              <section className="flex items-center py-4 lg:py-0 justify-center">
              <div className=" rounded-full bg-bra px-3 w-48">
                <h4 className='text-white text-2xl text-center md:text-3xl lg:text-3xl'>My Profile</h4>
                </div>
                </section>
                <div className="flex items-center justify-center lg:py-4">
                {profiles && profiles.map((profile: any)=>(<Profile key={profile.id} profile={profile}  />))}
      
                </div>
            </section>
            </>
        )
    }
    
    

    And my Profile.tsx component

    import React from 'react'
    interface ProfileProps{
        name?:string;
        email?:string;
        phone?: string;
    }
    
    
    const Profile = ({profile}: {profile: ProfileProps}) => {
      return (
        <div className='justify-center items-center rounded-md shadow-md px-4 flex flex-col bg-teal-100'>
            <p>Name:{profile.name}</p>
            <p>Email:{profile.email}</p>
            <p>Phone:{profile.phone}</p>
        </div>
      )
    }
    
    export default Profile