🔼 클릭시 사이트 이동
- 2023.03.29 ~ 2023.04.27
- Home
- Product Detail Page
- My Cart
- New Product ( admin권한이 있는 사용자만 보이는 페이지 ) 관리자만 새상품 등록
- Login, Logout ( 구글계정 로그인 )
❗ 오류 사항
Navbar에서 useState
등록 | useEffect
을 통해 user정보를 Component에 등록하였더니, 페이지 리로딩시 정보 초기화 유저정보를 가지고있지 못하는 오류가 발생하였습니다.
- 수정 내용
Context Api 이용해 user를 등록 Navbar에서useAuthContext
로 <AuthContext.Provider/>로 감싼 컴포넌트에서 데이터를 받을 수 있도록 설정 하였고, 리로딩시에도 유저정보 보관
💬코드보기
/**로그인, 로그아웃 결과값받는함수 */
export function onUserStateChange(callback) {
onAuthStateChanged(auth, async (user) => {
const updatedUser = user ? await adminUser(user) : null;
callback(updatedUser);
});
}
* login(), logout()
은 명령형 함수로만 이용
- 어드민 사용자 경로보호 index.js
<ProtectedRoute/>
사용하여 ProtectedRoute.jsx Component에서 조건을 체크한뒤 route를이용해 새상품등록페이지로 이동할 수 있게하였습니다.( 로그인한 사용자확인, 어드민권한체크 )
💬코드보기
import React from 'react';
import { useAuthContext } from '../context/AuthContext';
import { Navigate } from 'react-router-dom';
export default function ProtectedRoute({children, requireAdmin}){
const { user } = useAuthContext();
console.log(user,'나 라우터페이지임 유저정보 뜨는지 좀')
if(user===undefined){
return <>로딩중</>;
} else if (user === null || (requireAdmin && user.isAdmin===false)) {
return <Navigate to={"/"} replace={true} />;
} else {
return children;
}
}
//로그인한 사용자가 있는지확인
//사용자가 어드민 권한이 있는지 확인
//requireAdmin이 true인 경우에는 로그인도 되어있어야하고, 어드민 권한도 가지고 있어야함\
//조건이 불충족할경우 / 상위 경로로 이동
//조건이 충족된경우 전달된 chidren을 보여줌
💬상품관리 권한 코드보기
/**상품관리 권한 체크 */
//firebase/admins에 미리 권한을줄 uid를 등록
async function adminUser(user) {
return get(ref(database, "admins")).then((snapshot) => {
if (snapshot.exists()) {
const admins = snapshot.val();
console.log(admins);
const isAdmin = admins.includes(user.uid);
return { ...user, isAdmin };
}
return user;
});
}
📝 (수정전) 데이터 가져오기
const {
isLoading,
error,
data: products,
} = useQuey(["products"], getProducts, { staleTime: 1000 * 60 });
- (수정후)
custom hook
사용 후 코드리팩토링 ✨
const {
productsQuery: { isLoading, error, data: products },
} = useProducts();
reactQuery
유지보수 용이, UI/business 로직 분리하기 위해 custom hook
을 이용해 요청/ 업데이트를 한곳에서 관리하게 수정하였습니다.
장바구니에 담긴 개수를 바로 확인하지 못하였으나, firebase파일함수를 component에서 사용하지않고
custom hook에서 함수를 받아와 mutate(정보)
를 이용해 전달 -> 서버에서 데이터를 재호출해 최신상태로 업데이트
cart custom hook 코드
💬자세히보기
export default function useCart() {
const queryClient = useQueryClient();
const { uid } = useAuthContext();
/**사용자별로 캐시 사용자가 있는경우에만 apiquery사용 */
const cartQuery = useQuery(["carts", uid || ""], () => getCart(uid), {
enabled: !!uid,
});
const addOrUpdateItem = useMutation(
(product) => addOrUpdateToCart(uid, product),
{
onSuccess: () => {
queryClient.invalidateQueries(["carts", uid]);
},
}
);
const removeItem = useMutation((id) => removeFromCart(uid, id), {
onSuccess: () => {
queryClient.invalidateQueries(["carts", uid]);
},
});
return { cartQuery, addOrUpdateItem, removeItem };
}
export async function uploadImage(file) {
const data = new FormData();
data.append("file", file);
//secret key => .env
data.append("upload_preset", process.env.REACT_APP_CLOUDINARY_PRESET);
return fetch(process.env.REACT_APP_CLOUDINARY_URL, {
method: "POST",
body: data,
})
.then((res) => res.json())
.then((data) => data.url);
}
- 여기서 이미지URL을 받아와 firbase에 파일형태 X => url형태로 추가하였습니다.