Week목표 : 05/13일~05/18일 클론 프로젝트 Out Stagram : 인스타그램 클론 코딩
Out Stagram : 인스타그램 클론 프로젝트✅
오늘은 클론 프로젝트 주간에 정신이 없어서 작성하지 못했던 부분들을 다시 정리해보려고 한다.
클론 코딩 프로젝트 백엔드 Spring 4분과 프론트 React 2명, 총 6명이서 진행하였고 인스타그램 PC버을 클론 코딩하였다. 결과물은 다음과 같다.
- SA 보러 가기: https://www.notion.so/S-A-13db4f79c12e4f94a6eee28669fec243
- Github : https://github.com/17-outstagram/frontend
- Youtube 시연영상 : https://www.youtube.com/watch?v=MxVNrO2fpr4
프로젝트 기능
1. 회원가입 : 이미지 업로드, 이미지 미리보기, 이메일 인증, 유효성 검사(버튼 활성화)
2. 로그인 : Access-token과 Refresh-token을 사용한 로그인 인증, 인가 처리
3. 메인 페이지 : 인스타그램 피드 조회, 좋아요 기능
4. 사이드바 토글메뉴 : 포스팅(이미지 업로드, 미리보기)
5. 피드 상세 페이지 : 피드 수정 삭제, 댓글 조회 삭제
6. 기타 : 유저 페이지, 마이 페이지 게시물 조회, 유저 검색 기능, 팔로잉, 팔로우, 팔로잉한 유저의 게시글만 조회, 랜덤 유저의 게시물 조회, 좋아요 기능 등
시도한 점, 알게된 점 ✅
1. 로그인 페이지를 메인으로 사용 시 중첩라우팅 경로 설정 방법
로그인 페이지를 root경로로 사용하면서 중첩 라우팅으로 디자인 통일하기
문제) 기존 중첩라우팅 사용시 => /account/login으로 사용하기 때문에 로그인 페이지 경로를 /로 설정하지 못함
다음과 같이 해결 => path는 지정해 주지 않음
// Router.jsx
function Router() {
return (
<BrowserRouter>
<Routes>
<Route element={<AccountPage />}>
<Route path="/" element={<LoginPage />}></Route>
<Route path="/signup" element={<Signup />}></Route>
</Route>
<Route path="/main" element={<MainPage />}></Route>
<Route path="/main/:id" element={<DetailPage />}></Route>
<Route path="/my" element={<MyPage />}></Route>
<Route path="/user" element={<UserPage />}></Route>
</Routes>
</BrowserRouter>
);
}
//AccountPage.jsx
function AccountPage() {
return (
<div>
Account <Outlet />
</div>
);
}
2. FormData는 콘솔에 찍히지 않는다.
FormData 안의 키와 값을 확인하기 위해서는 for문을 순회하여야 한다. 이부분을 몰라서 반나절 동안 데이터가 안들어가는 줄 알고 고생했다...ㅠㅠ
formData는 특수한 객체 형태이기 때문에 formData 안의 키와 값은 console에 찍히지 않는다는 것을 깨닫고, for문으로 formData 내부를 순회하여 키와 값이 있음을 확인하고 서버에 전송할 수 있었다.
3. FormData를 이용해 서버에 이미지 파일을 업로드 하는 방법
4. 이미지 파일 업로드 미리보기
5.Queries options
import { useQuery } from 'react-query'
function App() {
const info = useQuery('todos', fetchTodoList, options)
}
- options
- enable : false로 설정하면 쿼리가 자동으로 호출되지 않는다. 즉 최초 선언시 호출을 막을 수 있다.
- retry : 요청이 실패했을시 재요청을 실행한다. 기본값은 3이다.
- refetchInterval : 일정한 간격으로 refetching이 가능하다.
- refetchOnMount : mount되었을 때 refetch 여부를 결정한다. true라면 stale 상태일 때 refetch 한다. (booelan | "always")
- staleTime : 데이터가 stale한 시점을 결정한다. 기본값은 0이다.
- cacheTime : 캐싱된 데이터가 메모리에 남아있는 시간을 결정한다. 기본값은 5분(5 * 60 * 1000)이다.
- 이 외에도 다양한 옵션들이 존재한다. 공식 문서를 확인해보자!
트러블 슈팅 ✅
1. 사용자 정보가 필요한 API요청에서 서버에 토큰을 전달할 때, headers 안에 set-cookie를 하여 전달하고자 하였는데 계속 access-token을 찾을 수 없다는 문제 발생.
해결방법
if (accessToken || refreshToken) {
config.headers["accessToken"] = accessToken;
config.headers["refreshToken"] = refreshToken;
config.headers["userId"] = userId;
}
프론트에서는 전달 받은 headers의 cookie의 정보를 읽고 저장할 수는 있지만 set-cookie를 할 수는 없다는 것을 알게 되었다. headers안에 access-token과 refresh-token 키로 값을 각각 전달하여 로그인 처리에 성공할 수 있었다.
2. intercepter response에서 액세스 토큰 만료 시 리프레쉬 토큰이 undefined가 되는 문제 발생
문제상황다음과 같이 코드에서 intercepter response를 받을 때 마다 토큰을 자동으로 저장하도록 하려고 했는데, 각각 토큰들을 서버에서 받지 못할 경우에는 undefined가 되어 저장되어 기존 토큰이 undefined되는 문제가 발생했다.
const accessToken = response.data["accessToken"];
const refreshToken = response.data["refreshToken"];
const userId = response.data["userId"];
if (accessToken || refreshToken) {
sessionStorage.setItem("accessToken", accessToken);
sessionStorage.setItem("refreshToken", refreshToken);
sessionStorage.setItem("userId", userId);
}
return response;
해결방법
const accessToken = response.data["accessToken"];
const refreshToken = response.data["refreshToken"];
const userId = response.data["userId"];
if (accessToken) {
sessionStorage.setItem("accessToken", accessToken);
}
if (refreshToken) {
sessionStorage.setItem("refreshToken", refreshToken);
}
if (userId) {
sessionStorage.setItem("userId", userId);
}
return response;
3. 검색 API에서 get 요청으로 body에 객체타입 데이터를 전송했는데, 서버에서는 계속 undefined로 뜨는 문제 발생
문제상황
get요청에서는 객체를 전달하지 못한다.
const searchUserAxios = async (value) => {
try {
const { data } = await instance.get("/api/search", { search: value });
return data;
} catch (error) {
throw error;
}
};
해결방법
쿼리문으로 변경해 데이터를 보내서 해결 하였다.
const searchUserAxios = async (value) => {
try {
const { data } = await instance.get(`/api/search/?search=${value}`);
return data;
} catch (error) {
throw error;
}
};
6. 매니저님께 질문한 부분들
'항해99 > 프로젝트' 카테고리의 다른 글
[WIL-33] 실전 프로젝트 중간 발표 - 결과 / 회고록 (1) | 2023.06.12 |
---|---|
[TIL-32] 실전 프로젝트 - 검색 기능 구현(useContext로 전역 상태, 검색 쿼리 관리하기) (0) | 2023.06.05 |
[TIL-30] 실전 프로젝트 - 카카오 지도 API 기능 구현 (0) | 2023.05.28 |
[TIL-29] 실전 프로젝트 - 카카오 로그인 기능 구현(불필요한 데이터 통신, ESLint 구문 에러들) (0) | 2023.05.26 |
[TIL-28] 실전 프로젝트 - 로그인 기능 구현(ESLint 구문 에러들) (0) | 2023.05.26 |