Firebase
- Firebase는 인증 상태를 관리하고, 사용자의 정보를 Firebase Authentication 및 Firestore에서 가져옵니다.
- onAuthStateChanged 메서드를 사용하여 인증 상태(로그인, 로그아웃)를 감지합니다.
Redux
- Redux는 인증 상태와 사용자 데이터를 전역적으로 관리하여 다른 컴포넌트에서 쉽게 접근할 수 있게 합니다.
- Firebase에서 가져온 데이터를 Redux 상태로 업데이트합니다.
흐름으로는
Step 1. Firebase Authentication 상태 감지
Firebase의 onAuthStateChanged를 사용하여 사용자의 로그인 상태를 확인합니다.
- 로그인된 사용자가 있다면 user.uid를 가져옵니다.
- uid를 사용하여 Firestore에서 사용자 정보를 가져옵니다.
Step 2. Redux 상태 업데이트
Firebase에서 가져온 사용자 정보를 Redux의 setUserInfo 액션을 사용해 Redux 상태에 저장합니다.
- 사용자 정보에는 uid, email, name 등 필요한 데이터가 포함됩니다.
Step 3. Redux 상태를 컴포넌트에서 사용
Redux의 useSelector를 사용하여 전역 상태(userInfo)에 접근합니다.
- 다른 페이지나 컴포넌트에서도 Redux 상태에서 uid 및 사용자 정보를 사용할 수 있습니다.
1. listenAuthChanges: Firebase 인증 상태 감지
listenAuthChanges 함수는 Firebase에서 로그인 상태를 감지하고, 데이터를 Redux로 전달합니다.
import { setLoading, setUserInfo } from "@/store/slices/userInfoSlice";
import { AppDispatch } from "@/types/store";
import { getUserData } from "@/services/getDatas";
import { auth } from "@/firebase";
import { onAuthStateChanged } from "firebase/auth";
export const listenAuthChanges = (dispatch: AppDispatch) => {
dispatch(setLoading(true)); // 로딩 상태 시작
onAuthStateChanged(auth, async (user) => {
if (user) {
const userUid = user.uid; // Firebase Authentication에서 uid 가져오기
console.log("User UID:", userUid);
const userData = await getUserData(userUid); // Firestore에서 사용자 데이터 가져오기
console.log("User Data:", userData);
if (userData) {
dispatch(
setUserInfo({
uid: userUid,
email: userData.email,
name: userData.name,
team: userData.team,
grade: userData.grade,
photoURL: userData.photoURL,
}),
);
} else {
dispatch(setUserInfo(null)); // 사용자 정보가 없을 때 null 처리
}
} else {
dispatch(setUserInfo(null)); // 로그아웃 상태
}
dispatch(setLoading(false)); // 로딩 상태 종료
});
};
2. Redux 상태 정의
userInfoSlice는 사용자 정보를 Redux 상태로 관리합니다. Firebase에서 가져온 데이터를 저장합니다.
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { UserInfoState, AuthState } from "@/types/store";
const initialState: AuthState = {
user: {
uid: null,
email: null,
name: null,
grade: null,
team: null,
photoURL: null,
},
isLoading: false,
};
const userInfoSlice = createSlice({
name: "userInfo",
initialState,
reducers: {
setUserInfo: (state, action: PayloadAction<UserInfoState | null>) => {
state.user = action.payload; // 사용자 정보 업데이트
state.isLoading = false; // 로딩 상태 종료
},
setLoading: (state, action: PayloadAction<boolean>) => {
state.isLoading = action.payload; // 로딩 상태 업데이트
},
},
});
export const { setUserInfo, setLoading } = userInfoSlice.actions;
export default userInfoSlice.reducer;
3. Redux 상태를 사용하는 컴포넌트
SalaryPage 컴포넌트에서 Redux 상태에 저장된 uid를 사용하여 데이터를 가져옵니다.
import React, { useState, useEffect } from "react";
import { useSelector } from "react-redux";
import { RootState } from "@/types/store";
import { doc, getDoc } from "firebase/firestore";
import { db } from "@/firebase";
const SalaryPage = () => {
const [isLoading, setIsLoading] = useState(false);
const [userName, setUserName] = useState<string | null>(null);
const uid = useSelector((state: RootState) => state.userInfo.user?.uid);
useEffect(() => {
if (uid) {
fetchUserData();
}
}, [uid]);
const fetchUserData = async () => {
setIsLoading(true);
try {
const userDocRef = doc(db, `user/${uid}`);
const userDocSnap = await getDoc(userDocRef);
if (userDocSnap.exists()) {
setUserName(userDocSnap.data().name || null);
} else {
setUserName(null);
}
} catch (error) {
console.error("Error fetching data:", error);
} finally {
setIsLoading(false);
}
};
return (
<div>
<h1>Salary Page</h1>
{isLoading ? <p>Loading...</p> : <p>User Name: {userName}</p>}
</div>
);
};
- Firebase:
- onAuthStateChanged로 로그인 상태를 확인.
- 사용자 uid를 가져오고, Firestore에서 사용자 데이터를 조회.
- Redux:
- uid와 사용자 정보를 setUserInfo로 Redux 상태에 저장.
- 전역 상태로 관리하여 모든 컴포넌트에서 접근 가능.
- React 컴포넌트:
- useSelector로 Redux 상태(userInfo)에서 uid를 가져옴.
- uid를 사용하여 Firestore에서 추가 데이터를 가져옴.
'⚛️ React' 카테고리의 다른 글
[ Context API ] React Context , redux와의 차이점 (1) | 2024.12.18 |
---|---|
Firebase uid 로 리덕스 저장해서 해당user의 데이터 불러오기 (0) | 2024.12.11 |
드롭박스를 만들어보자.. +외부클릭으로 드롭다운 닫히는 동작 (0) | 2024.11.28 |
React-Portal로 Modal 구현하기 (0) | 2024.11.27 |
[React] React-Hook-Form에 대해 알아보기 (1) | 2024.11.12 |