리액트 쿼리 없이, 데이터를 갱신하려면?
Next.js의 App Router와 Firebase를 백엔드로 사용하여 서버 컴포넌트 환경에서 게시물을 등록한 후, 새로운 게시물이 실시간으로 홈 페이지에 반영되도록 하는 방법입니다.
import { db } from '@root/firebase'
import { collection, getDocs, query, orderBy } from 'firebase/firestore'
import { HoneyPlace } from '@/interfaces/IPlace'
export const getHoneyPlaces = async () => {
const placesCol = collection(db, 'honey_place')
const q = query(placesCol, orderBy('createdAt', 'desc'))
const querySnapshot = await getDocs(q)
const places = querySnapshot.docs.map((doc) => {
const data = doc.data()
return {
...data,
createdAt: data.createdAt.toDate().toISOString(), // Timestamp를 ISO 문자열로 변환
id: doc.id,
}
}) as HoneyPlace[]
return places
}
서버 컴포넌트에서 위에서 정의한 데이터 가져오기 함수를 사용하여 데이터를 클라이언트 컴포넌트에 전달합니다.
export default function Home() {
return (
<main>
<Header />
<HoneyPlaceListServer />
<Footer />
</main>
);
}
const HoneyPlaceListServer = async () => {
const places = await getHoneyPlaces();
return <HoneyPlaceListClient initialPlaces={places} />;
};
클라이언트 컴포넌트에서 서버 컴포넌트로부터 전달받은 데이터를 상태로 관리하고, 라우터가 변경될 때마다 데이터를 다시 불러옵니다.
'use client';
const HoneyPlaceListClient = ({ initialPlaces }: { initialPlaces: HoneyPlace[] }) => {
const [places, setPlaces] = useState(initialPlaces);
const router = useRouter();
useEffect(() => {
const fetchPlaces = async () => {
const updatedPlaces = await getHoneyPlaces();
setPlaces(updatedPlaces);
};
fetchPlaces();
}, [router]);
return (
<section>
{places.map((place) => (
<HoneyPlaceCard key={place.id} place={place} />
))}
</section>
);
};
initialPlaces
를 상태로 저장useEffect
훅을 사용하여 라우터 변경 감지getHoneyPlaces
함수를 호출하여 새로운 데이터로 상태를 업데이트리액트 쿼리를 당장 안써도 되는 상황이라면, 이런 방법을 사용할 수 있습니다.
업로드 페이지에서 게시물을 등록해서 router.push('/)로 홈으로 돌아왔을 때 새 게시물을 확인할 수 있습니다.