[너는, 나는] 6~8주차 회고

비얌·2024년 1월 20일
0
post-thumbnail

📮 개요

마지막으로 쓴 5주차 회고 후로 3주가 더 지나 8주차가 되었다. 멘토링 프로젝트 프로그램 자체는 7주차에 끝났지만, 우리 팀은 프로젝트를 더 이어나가기로 했다.

목표는 9주차에 릴리즈를 하는 것이다. 9주차에는 릴리즈 후기를 썼으면 좋겠다!

그럼 이제 6주차~8주차에 어떤 점이 어려웠고 무엇을 느꼈는지 위주로 회고를 해보려고 한다.

<지난 회고>

🤓 한 일 & 어려웠던 점

1. 초대링크 랜딩 페이지 작업

초대링크를 받은 사용자가 링크를 클릭해서 서비스에 접속했을 때 보이는 페이지를 작업했다.

어려웠던 점은 아래와 같다.

  • url에서 링크키 얻기: 링크에 키를 넣는다는 개념을 처음 알아서 구현보다는 url에서 키를 받아와야 한다는 개념을 이해하는 것이 어려웠다.

  • token: request header에 access token을 넣어서 보냈는데, 이 개념도 처음 알아서 이해하기 어려웠다. 이후에 밤밤이 작성한 토큰 처리 코드를 사용하며 axios의 interceptor에 대해서도 알게 되었다.

    import axios, {
      InternalAxiosRequestConfig,
      type AxiosResponse,
      AxiosRequestConfig,
      AxiosError,
    } from 'axios';
    import { getAccessToken, removeAccessToken } from './token';
    
    export const instance = axios.create({
      baseURL: process.env.NEXT_PUBLIC_BACKEND_URL,
      timeout: 15000,
    });
    
    const interceptorRequestFulfilled = (config: InternalAxiosRequestConfig) => {
      if (typeof window === 'undefined') return config;
    
      const accessToken = getAccessToken();
      if (!config.headers) return config;
      if (!accessToken) return config;
    
      config.headers.Authorization = `Bearer ${accessToken}`;
    
      return config;
    };
    
    instance.interceptors.request.use(interceptorRequestFulfilled);
    
    const interceptorResponseFulfilled = (res: AxiosResponse) => {
      if (200 <= res.status && res.status < 300) {
        return res;
      }
    
      return Promise.reject(res);
    };
    
    const interceptorResponseRejected = (error: AxiosError) => {
      if (error.response?.status === 401) {
        removeAccessToken();
        window.location.href = '/';
        return Promise.reject(error.response.data);
      }
      return Promise.reject(error.response?.data);
    };
    
    instance.interceptors.response.use(
      interceptorResponseFulfilled,
      interceptorResponseRejected
    );
    
    export const get = <T = any, R = AxiosResponse<T>>(
      url: string,
      config?: AxiosRequestConfig
    ) => {
      return instance.get<T, R>(url, config);
    };
    
    export const post = <T = any, D = any, R = AxiosResponse<T>>(
      url: string,
      data?: D
    ) => {
      return instance.post<T, R>(url, data);
    };

2. 대화상세페이지 데이터 패칭 오류 해결

  • 대화 상세 페이지에서 스크롤을 할 때 컴포넌트가 무한 렌더링되며 다음 페이지가 보이지 않는 오류 있었다. 이는 state를 ref로 바꿔서 해결했다. 분명히 예전에는 오류가 없었는데, 왜 같은 코드인데도 오류가 발생했는지는 잘 모르겠다. state는 리렌더링을 유발하므로 꼭 필요하지 않다면 ref를 써야겠다는 생각을 했다.
  • 무한스크롤을 하며 페이지가 한번 바뀔 때 fetchNextPage가 한번만 되어야 하는데, 1px마다 한번씩 렌더링되는 오류가 발생했다. 코드를 보면 스크롤이 450 미만이면 fetchNextPage를 계속 부르게끔 하고 있었다. 그래서 로딩중인 상태를 추가하여 로딩중인 상태에만 fetchNextPage를 하도록 했다.

3. 변경된 데이터 즉시 반영하기

서버 데이터가 변경되었는데 화면에 바로바로 반영이 되지 않는 오류를 모두 queryClient.invalidateQueries로 해결했다. 하지만 완전히 이해하고 쓴 것이 아니라서 추가적인 공부가 필요할 것 같다.

4. 새로 추가된 api 연결하기

대화 상세 페이지 api에 현재 사용자가 누구인지에 대한 정보가 추가되었다. 기존에는 메시지 두개 중 어떤 메시지가 나의 메시지인지 구분할 수 없었는데, 이 api가 추가되어 문제가 해결되었다.

5. 로그인한 사용자 라우팅 작업

기존에는 로그인 버튼을 눌렀을 때를 로그인 한 사용자, 로그인 안한 사용자 이렇게 두가지 경우로 나눴었다.

그러다가 만약 로그인은 했는데 초대링크를 보내기 전에 창이 꺼진다면? 아니면 초대링크를 보냈는데 아직 커플이 맺어지기 전에 다시 로그인한다면 어떤 화면을 보여줘야 하지? 하는 고민을 하게 되었다.

그렇게 고민하다가 아래와 같은 유저플로우를 그리게 되었다.. 생각해보면 excalidraw와 같은 툴로 처음부터 그렸으면 좋았을텐데, 처음에는 이렇게 복잡해질지 몰랐다.

이때 어려웠던 점은 아래와 같다.

  • 개발 순서는 유저플로우대로 하지 않았어서 그런지(분업하여 작업하였고, 더 쉬운 페이지를 먼저 작업하였기 때문) 유저플로우를 생각하는 것이 어려웠고 복잡하게 느껴졌다. 그런데 이 부분은 어쩔 수 없는 부분인 것 같다..
  • 기획에 없는 부분이었는데, 상상력을 동원해서 너무 앞서나가서 어려웠던 것 같다.
  • 새로운 api가 필요한 상황이었는데, 현재 존재하는 api만으로 어떻게 할 수 있을까를 너무 오랫동안 고민했다.

결국 팀원들과 회의를 했고 많은 이야기를 나눠 api를 추가하기로 했지만, 그동안 너무 고민을 많이해서 그게 최선이었을지 잘 모르겠다.

다만 프론트 팀원과 함께 이야기 해봤을 때, 밤밤도 이 고민을 오래 했고 나도 오래 했기에 회의 진도를 빠르게 나갈 수 있었던 것 같다는 이야기를 했다.

<고민>

<결론>

👏 잘한 점

몰랐는데, 정리해보니 그동안 많은 일을 한 것 같다. 오랫동안 집중하기 힘들었지만, 주3-4회 5시간씩 코어타임을 가진 것이 큰 도움이 된 것 같다. 그 시간에 집중해서 한 점을 잘했다고 칭찬해주고 싶다.

🐹 9주차에는?

9주차에는 릴리즈를 하고 싶다!!
그리고 9주차에는 로그인한 사용자 라우팅 처리를 잘 구현해보고 싶다.

profile
🐹강화하고 싶은 기억을 기록하고 공유하자🐹

0개의 댓글