Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[refactor/#193/Pagination] 페이지네이션 리팩토링 #196

Open
wants to merge 8 commits into
base: dev
Choose a base branch
from

Conversation

hellosonic-r
Copy link
Contributor

#️⃣연관된 이슈

close #193

💡 핵심적으로 구현된 사항

스크린샷 2024-04-02 오후 3 58 08
  • Context API + Tanstack Query 를 활용하여 구현했던 페이지네이션을 Tanstack Query 만을 활용하여 리팩토링 했습니다.
  • 렌더링 시 url의 쿼리스트링 tab, page를 초기 상태로서 사용하고, 탭이나 페이지네이션의 페이지를 클릭할 때 실행되는 이벤트 핸들러의 콜백함수로 데이터패칭, navigate를 수행하고, 브라우저의 뒤로가기, 앞으로가기는 location을 의존성 배열 요소로 둔 useEffect 훅을 활용했습니다.
  • 사용자 경험 개선
    • 페이지네이션 쿼리의 staleTime을 설정하여 방문한 페이지에 해당하는 데이터를 캐싱합니다. 사용자는 이전에 조회했던 페이지를 열람할 시 네트워크 요청을 하지 않고, 더 빠르게 프로젝트들을 조회할 수 있습니다.
    • 프로필 페이지에는 로그인 여부에 따라 최대 3개의 탭(내, 좋아요한, 댓글단 프로젝트)과 각 탭마다 고유한 페이지네이션이 존재합니다. Zustand 를 활용하여 각 탭의 열람중인 페이지를 저장하고 탭을 이동해도 열람중인 페이지가 유지되도록 구현했습니다.
    • url에 쿼리스트링을 추가했습니다. 사용자는 브라우저의 뒤로가기 버튼을 통해 편리하게 이전 페이지, 혹은 이전 탭으로 돌아갈 수 있습니다. 또한 각 페이지마다 고유한 url을 가지게 되어 검색 엔진 최적화 측면에서의 이점을 가지도록 개선했습니다.

➕ 그 외에 추가적으로 구현된 사항

🤔 테스트,검증 && 고민 사항

📌 PR Comment 작성 시 Prefix for Reviewers

@hellosonic-r hellosonic-r added the Refactor 리팩토링 label Apr 2, 2024
@hellosonic-r hellosonic-r self-assigned this Apr 2, 2024
@hellosonic-r hellosonic-r changed the title [refactor/#193/Pagination] [refactor/#193/Pagination] 페이지네이션 리팩토링 Apr 2, 2024
Copy link
Contributor

@wdgWon wdgWon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리펙토링 고생하셨습니다!
프로젝트 끝나고도 계속 열심히 하시는 모습 본받겠습니다!
저는 거의 풀어져서 깔짝깔짝하고 있는데
200줄 가까이 리펙토링은 ㄷㄷ
분발하겠습니다!

src/components/PaginationRQ/PaginationRQ.tsx Show resolved Hide resolved
Comment on lines +7 to +8
const searchParams = new URLSearchParams(location.search)
const paramsValue = paramsName && searchParams.get(paramsName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

react-router-domuseSearchParams를 쓰는게 이후에 변경되는 값들을 제대로 반영할 수 있을 것 같은데 어떻게 생각하시나요?

승민님도 검색 페이지를 URLSearchParams로 query string을 가져왔었는데 컴포넌트 외부에서 query string을 변경하면 그 컴포넌트는 해당 query string이 바뀌었는지 인식하지 못하는 버그가 발생하더라구요...
(헤더에서 검색 => 검색 페이지는 바뀐 query string 인식 못함)

Copy link
Contributor

@Whoknow77 Whoknow77 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰를 늦게 드렸네요..

querystring기반으로 페이지네이션을 구현하는게 어려우셨을텐데 잘 구현해주신 거 같아요. 수고하셨습니다!

@@ -18,6 +18,7 @@ export const useUserProjects = ({
const { data } = useQuery({
queryKey: ["projects", userId, type, page, size],
queryFn: () => getUserProjects({ userId, type, page, size }),
staleTime: 1000 * 60 * 5,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 staletime을 적용하는 것을 까먹고있었는데 프로젝트 끝나고 나서야 알았네요.. default가 0이라서 되도록 설정해주면 좋다고 생각했는데 꼼꼼히 설정해주셨네요!!

totalProjectsCount: number
setPage: React.Dispatch<React.SetStateAction<number>>
}
const PaginationRQ = ({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ASK : 컴포넌트명의 RQ는 Request의 약자인가요?

@@ -0,0 +1,13 @@
import { useLocation, useNavigate } from "react-router-dom"

const useQueryString = (paramsName: string) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 : hook에 맞게 기본 내보내기가 아니라 export const 내보내기로 수정해주시면 감사하겠습니다!

@@ -16,16 +21,41 @@ import ProjectsGrid from "./ProjectsGrid"
const ProjectsView = ({ userId, isMe }: UserIdProps) => {
const [isLargerThan500] = useMediaQuery("(min-width: 500px)")

// eslint-disable-next-line react-hooks/exhaustive-deps
const projectsType = isMe ? ["JOINED", "LIKED", "COMMENTED"] : ["JOINED"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ASK : usememo대신에 lint warning을 무시하는 이유가 따로 있으신가요?

const projectsType = isMe ? ["JOINED", "LIKED", "COMMENTED"] : ["JOINED"]

const { location, navigate, paramsValue: tabInfo } = useQueryString("tab")
const { paramsValue: tempPageInfo } = useQueryString("page")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 : pageInfoNumber로 변환되어 사용하는 곳이 여기서는 한 군데이므로 받을때 pageInfo로 받고 전달할때 Number를 씌워주는건 어떤가요? temp가 없으면 더 좋을 것 같아서요


const useQueryString = (paramsName: string) => {
const location = useLocation()
const navigate = useNavigate()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 : navigate를 반환하지만 사용하지 않는 곳도 존재하고, 선언후 바로 반환하는 부분이라 view에서 선언하는것이 더 자연스럽지 않나 생각했는데 여기서 선언하신 이유가 있나요?

(projectType) => projectType === tabInfo,
)
setTabIndex(newIndex >= 0 ? newIndex : 0)
}, [location, projectsType, tabInfo])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 : location을 의존성배열에 넣으신 이유가 있나요? projectsTypetabInfo만으로도 해결이 될 거 같아서요! 훅에서 location을 내려주지 않아도 된다고 생각하는데 어떤가요?

}, [location, projectsType, tabInfo])

const handleChangeTab = (index: number) => {
const storedPage = tabPageInfo[projectsType[index]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 : 뒤로가기 했을때 페이지 번호는 변하는데 화면이 그대로인 오류가 있어서 확인 한번 해주시면 감사하겠습니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Refactor 리팩토링
Projects
None yet
Development

Successfully merging this pull request may close these issues.

페이지네이션 Context API -> Tanstack Query 리팩토링
3 participants