Next.js 게시물 등록 시 상태관리로 데이터 업데이트

김선은·2024년 7월 5일
0

리액트 쿼리 없이, 데이터를 갱신하려면?

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('/)로 홈으로 돌아왔을 때 새 게시물을 확인할 수 있습니다.

profile
기록은 기억이 된다

0개의 댓글