이번 프로젝트에서 내가 담당한 기능은 firebase를 이용해 도서리뷰 데이터를 추가하고 읽어들이는 부분이다.
여러번 구현해봤던 로직이라 이번에도 어렵지 않게 구현할 수 있었다.
간단한 흐름만 정리하도록 하겠다.
1. Firebase를 세팅한다.
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
const firebaseConfig = {
apiKey: process.env.REACT_APP_FB_API_KEY,
authDomain: process.env.REACT_APP_FB_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FB_PROJECT_ID,
storageBucket: process.env.REACT_APP_FB_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FB_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FB_APP_ID
};
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
2. 데이터를 전역으로 관리하기 위해 redux를 세팅한다.
(1) configStore.js
import { createStore } from 'redux';
import { combineReducers } from 'redux';
import reviewsReducer from '../modules/reviewsReducer';
import authReducer from '../modules/authReducer';
const rootReducer = combineReducers({ reviewsReducer});
const store = createStore(rootReducer);
export default store;
(2) reviewsReducer.js
const SET_REVIEW = 'SET_REVIEW';
const ADD_REVIEW = 'ADD_REVIEW';
export const setReview = (data) => {
return {
type: SET_REVIEW,
payload: data
};
};
export const addReview = (data) => {
return {
type: ADD_REVIEW,
payload: data
};
};
const initialState = {
reviews: []
};
const reviewsReducer = (state = initialState, action) => {
switch (action.type) {
case SET_REVIEW:
return {
...state,
reviews: action.payload
};
case ADD_REVIEW:
return {
...state,
reviews: [action.payload, ...state.reviews]
};
default:
return state;
}
};
export default reviewsReducer;
3. useFirestore 훅을 만든다.
import { useEffect, useState } from 'react';
import { db } from '../firebase/firebase';
import { collection, getDocs, query, addDoc, orderBy } from 'firebase/firestore';
import { setReview } from '../redux/modules/reviewsReducer';
import { useDispatch } from 'react-redux';
const useFirestore = (collectionName) => {
const [loading, setLoading] = useState(true);
const dispatch = useDispatch();
useEffect(() => {
const fetchData = async () => {
try {
const q = query(collection(db, collectionName), orderBy('createdAt', 'desc'));
const snapshot = await getDocs(q);
const fetchedData = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data() // 문서 데이터를 객체로 변환
}));
//초기값 세팅
dispatch(setReview(fetchedData));
setLoading(false);
console.log('fetchedData', fetchedData);
} catch (error) {
console.error('Error fetching Firestore data:', error);
}
};
fetchData(); // 데이터 가져오기 함수 호출
}, [collectionName, dispatch]);
const addData = async (newData) => {
try {
const collectionRef = collection(db, collectionName);
const docRef = await addDoc(collectionRef, newData);
console.log('Data added successfully!', docRef.id);
return docRef.id;
} catch (error) {
console.error('Error adding data:', error);
}
};
return { loading, addData };
};
export default useFirestore;
4. 필요한 곳에서 호출한다.
fire store와 redux에 순차적으로 값을 add하는 로직을 호출한다.
const ReviewForm = ({ selectedBook, setIsModalOpen, setSelectedBook }) => {
...
//호출함과 동시에 useFirestore에서 받아온 데이터를 state에 저장함
const { addData } = useFirestore('book-reviews');
...
const newReviewData = {
title: title,
content: content,
image: selectedBook.image,
bookAuthor: selectedBook.author,
bookTitle: selectedBook.title,
createdAt: new Date(),
genre: selectedGenre,
authorId: userInfo ? userInfo.uid : '',
};
//firestore에 저장을 하고
const docId = await addData(newReviewData);
newReviewData.id = docId;
//dispatch로 state에도 저장한다.
dispatch(addReview(newReviewData));
};
return (
...
);
};
export default ReviewForm;
5. 작성하기 테스트
6. 리스트가 잘 저장되고 출력되는 걸 확인할 수 있다.
'웹개발 > PRJ' 카테고리의 다른 글
[최종프로젝트] 1차 회의 - 그라운드룰, 주제정하기 (0) | 2024.03.30 |
---|---|
[react prj] 선물 추천 사이트 만들기 (0) | 2024.02.28 |
[React Team Project] 도서 리뷰 사이트 만들기 - 기획 (1) | 2024.02.07 |
[React] Weekly to do list 만들기 2 (0) | 2024.01.19 |
[react] weekly to-do-list 만들기1 (0) | 2024.01.18 |