[TIL] 240722 (최종 프로젝트 공구템 수정 기능 완료, revalidatePath로 갱신 오류 해결)

·2024년 7월 22일

TIL

목록 보기
106/268
post-thumbnail

🥞 오늘 한 일

  • 최종 프로젝트
    • 공구템 수정 페이지 및 기능 완료
    • 리스트 카드 남은 인원 및 상세 페이지 달성률 구현
      • 로직 변경으로, 메인 공구템 리스트 로직도 같이 변경
    • 수정 시 바로 상세 페이지에 적용되지 않는 문제 해결
    • 상세 페이지 데이터 가져오는 함수 다른 경로에 따로 제작

기술면접 연습

Frontend

  • Optimistic Update에 대해 설명해주세요.
    • 사용자 경험을 개선하기 위해 서버 응답이 오기 전에 미리 응답 상태를 예측하여 화면에 적용하는 방법입니다. 네트워크가 느린 환경에서 유용하다는 장점이 있으며, 서버와의 데이터가 다를 수 있다는 단점이 있습니다.
  • 인증/인가의 관점에서 세션 방식과 JWT 방식의 차이점을 자세히 설명해주세요. 각 방식의 장단점과 실제 프로젝트 활용 경험이 있다면 공유해주세요.
    • 세션 방식은 유저가 로그인하면 서버에 유저 정보를 저장하고, 발급된 세션 ID를 쿠키를 통해 클라이언트 브라우저에 전달합니다. 유저 인증이 필요할 때 클라이언트는 쿠키에 세션 ID를 담아 전송하고, 서버는 세션 ID를 받아 유저를 확인하고 인증을 허가합니다.
      다음으로 JWT는 Json Web Token의 약자로, 유저가 로그인하면 서버는 토큰을 생성해 클라이언트에 전달합니다. 토큰에는 민감한 정보가 포함되어서는 안되며, 클라이언트는 받은 토큰을 로컬 스토리지나 쿠키에 저장하고, 인증이 필요할 때 토큰을 포함해 서버로 전송합니다. 서버는 만료되지 않은 토큰이라면 인증을 진행합니다.
      세션의 경우에는 서버에 저장하기 때문에 서버 부하가 증가할 수 있는 단점이 있고, JWT는 부하는 적지만 토큰의 서명 키가 노출되지 않도록 주의해야한다는 특징이 있습니다.
  • 쿠키, 세션, 웹스토리지의 차이를 설명해보세요.
    • 세 기술 모두 웹에서 데이터를 저장하는 방식입니다.
      먼저 쿠키는 클라이언트와 서버 간의 데이터를 저장하여 HTTP 통신에 사용합니다. 그리고 세션은 서버에서 사용자 정보를 유지하는 방법입니다. 세션이 유지되는 동안은 유저의 로그인 상태도 유지됩니다. 마지막으로 웹 스토리지는 크게 로컬 스토리지, 세션 스토리지가 많이 쓰이는데, 많은 데이터를 저장할 수 있고 서버로 전송되지 않는 장점이 있으나 정보가 유출될 수 있으므로 민감한 정보는 저장하지 않는 것이 좋습니다.

🍽️ 트러블 슈팅

공구템 게시물 수정 시 바로 상세 페이지에 적용되지 않는 문제 해결

빅 이슈가 있었다. 게시물 수정 후 바로 상세 페이지로 가도록 했는데, 문제는 상세 페이지에서 정보를 보여주는 컴포넌트가 서버 컴포넌트였기 때문에, 수정된 내용이 바로 적용되지 않았던 것. 강력 새로고침을 해야만 바뀐 부분이 비로소 보였다.
때문에 여러가지 방법을 찾아보고 생각을 해보았다.

STEP 1 - router.refresh()

// GroupEditForm.tsx
const updateMutation = useMutation({
  mutationFn: async (newGroupPost: TNewGroupPost) => {
    await updateGroupPost(newGroupPost);
  },
  onSuccess: async () => {
    router.push(`/grouppost/read/${id}`);
    router.refresh();
  },
});

찾아보았을 때 제일 먼저 나온 방법은 router.refresh() 를 사용하는 방법이었다. 같은 문제에서 이렇게 해결한 사람이 많다고 해서 적용을 시도해보았고, 해결이 되지 않았다. 튜터님께 질문을 드렸는데 튜터님도 이해가 잘 안 되신다고 하셔서(?) 일단 다른 방법을 찾아보기로 했다.

STEP 2 - revalidate

// page.tsx
export const revalidate = 0;

function GroupReadPage({ params }: Props) {
  return (
    <Page>
      <GroupDetail params={params} />
    </Page>
  );
}

export default GroupReadPage;

그 다음은 강제로 revalidate를 0으로 지정하여 무조건 해당 페이지에 들어올 때마다 새로운 데이터를 가지고 오는 방식을 사용해보았다. 이렇게 하니 수정 시 바로 갱신은 잘 되었으나, 꼭 수정을 하지 않더라도 매번 새로 가져오기 때문에 좋은 방법이 아니므로 다른 방법을 생각해보았다.
그렇게 계속 방법을 찾아보던 중 튜터님께서 한 가지 방법을 알려주셨는데, 바로 form 내 action을 사용하여 revalidatePath를 해주는 방법이었다.

STEP 3 - action, revalidatePath

우선 form 태그 내의 action이 들어갈 수 있다는 걸 배웠고, action에 기존 업데이트 로직 함수를 넣어주었다.
그 다음 revalidatePath에 대해 배웠다. 해당 함수는 인자로 넣어준 경로를 서버에서 강제로 다시 가져오는 기능을 가지고 있었다. 그러나 클라이언트 컴포넌트에서는 작동하지 않아, 새로운 파일을 만들어 해당 파일에서 revalidatePath 기능을 가진 함수를 만들고, 업데이트 onSuccess 시 해당 함수를 가져와 호출해주는 방식을 사용했다.

// revalidate.ts
"use server";

import { revalidatePath } from "next/cache";

export async function groupPostRevalidate(id: string) {
  revalidatePath(`/grouppost/read/${id}`);
}
// GroupEditForm.tsx
const updateMutation = useMutation({
  mutationFn: async (newGroupPost: TNewGroupPost) => {
    await updateGroupPost(newGroupPost);
  },
  onSuccess: async () => {
    groupPostRevalidate(id);
    router.push(`/grouppost/read/${id}`);
  },
});

이렇게 진행하니 수정 시에만 성공적으로 갱신을 할 수 있었다. 새로운 개념을 알게 되어서 좋았다.
한가지 의문점은, 꼭 action을 쓰지 않아도 revalidatePath는 잘 동작하는데, action을 사용한 이유에 대해서는 익일 질문을 드려야겠다.

🍴 돌아보기

오후를 통으로 수정 시 바로 갱신 기능에 써버려서 생각보다 많이 진행을 못해 아쉬운 날이었다. 하지만 그 시간이 결코 무의미하지 않았고 성장했다고 생각하기 때문에 긍정적으로 생각하려고 한다. 또한 내가 프로젝트에서 맡은 부분이 기능적으로는 거의 다 끝났기에 결코 느리지는 않다고 생각한다. 그럴 내가 아니긴 하지만 안일하게 생각 말고 프로젝트에 도움이 될 수 있는 부분은 최대한으로 도움이 되자.

🍳 내일 목표

  • 최종 프로젝트
    • 무한 스크롤
    • 공구템 전체적으로 디테일한 부분 잡기
    • 공구템 로그인 필요한 기능 제외하고 기능 완성
profile
웹 프론트엔드 개발자

2개의 댓글

comment-user-thumbnail
2024년 7월 23일

그러실 솔님이 아니죠~!!!

1개의 답글