Getting hydration error in client component (firebase/firestore)
Unanswered
XotEmBotZ posted this in #help-forum
I am using firebase/firestore to get a list of strings and render bunch of components from that. The page is a server page but the component is client since it will require auth for firestore permissions. But I am getting hydration error. What is the way around ?
4 Replies
This is my component
'use client'
import { getChapters } from "@/firebase/firestore"
import Image from "next/image"
import Link from "next/link"
const ChapterCrousel = ({subjectCode}) => {
const iconSrcLst = ['assets/svg/book-and-people-spring.svg', 'assets/svg/book-and-person-summer.svg', 'assets/svg/book-and-person-winter.svg',]
const clipArtSize=200
const crouselCards = () => {
return getChapters(subjectCode).then(chapters => {
return chapters.map(chapter => {
return <>
<div className="carousel-item card bg-base-300 text-base-content w-fit shadow-xl max-w-56">
<figure className='p-3'>
<Image src={iconSrcLst[(Math.floor(Math.random() * iconSrcLst.length))]} width={clipArtSize} height={clipArtSize } alt={"Clipart logo"}/>
</figure>
<div className="card-body">
<h2 className="card-title capitalize">
{chapter.replaceAll("-"," ")}
<div className="badge badge-secondary">Imp!</div>
</h2>
<div className="card-actions justify-end">
<Link href={"/notes/"} className="badge badge-outline cursor-pointer">Notes</Link>
<Link href={"/questions/"} className="badge badge-outline cursor-pointer">Questions</Link>
</div>
</div>
</div></>
})
})
}
return (
<div className="carousel gap-3 carousel-center rounded-box h-fit p-2 w-full">
{crouselCards()}
</div>
)
}
export default ChapterCrouselWest African Crocodile
The hydration error occurs because the server and client renderings are not synchronized. This often happens when the client-side code fetches data asynchronously that isn't available during the initial server-side render. Here’s a way to fix it by using React state and effects to handle the asynchronous data fetch on the client side.
First, modify your component to fetch the data in a useEffect hook and manage the fetched data using state.
First, modify your component to fetch the data in a useEffect hook and manage the fetched data using state.
Here is the updated component:
'use client'
import { useEffect, useState } from "react";
import { getChapters } from "@/firebase/firestore";
import Image from "next/image";
import Link from "next/link";
const ChapterCrousel = ({ subjectCode }) => {
const [chapters, setChapters] = useState([]);
const iconSrcLst = ['assets/svg/book-and-people-spring.svg', 'assets/svg/book-and-person-summer.svg', 'assets/svg/book-and-person-winter.svg'];
const clipArtSize = 200;
useEffect(() => {
getChapters(subjectCode).then(fetchedChapters => {
setChapters(fetchedChapters);
});
}, [subjectCode]);
const crouselCards = () => {
return chapters.map((chapter, index) => {
return (
<div key={index} className="carousel-item card bg-base-300 text-base-content w-fit shadow-xl max-w-56">
<figure className='p-3'>
<Image src={iconSrcLst[(Math.floor(Math.random() * iconSrcLst.length))]} width={clipArtSize} height={clipArtSize} alt={"Clipart logo"} />
</figure>
<div className="card-body">
<h2 className="card-title capitalize">
{chapter.replaceAll("-", " ")}
<div className="badge badge-secondary">Imp!</div>
</h2>
<div className="card-actions justify-end">
<Link href={"/notes/"} className="badge badge-outline cursor-pointer">Notes</Link>
<Link href={"/questions/"} className="badge badge-outline cursor-pointer">Questions</Link>
</div>
</div>
</div>
);
});
};
return (
<div className="carousel gap-3 carousel-center rounded-box h-fit p-2 w-full">
{crouselCards()}
</div>
);
};
export default ChapterCrousel;