회고 (220523 - 220531)

Juhwan Lee·2022년 6월 1일
0
post-thumbnail

5월 31일자로 최종 배포를 완료했다. 상대적으로 적은 시간에 다양한 오류를 맞닥드렸지만, 속시원하다.

배포를 5월 31일 화요일에는 무조건하자는 팀원들과의 약속이 있었기에 다양한 기능을 완성 + 수정했고 열심히 달렸던 한 주였다.

한 주의 기록

시연영상 보러가기 ⬇️

COPICK 이용해보기

✅ 원두 리스트 페이지 검색, 카페별 검색 기능 구현

✅ 즐겨찾기 기능 구현

✅ chart.js를 이용한 데이터 시각화

✅ swiper.js를 이용한 메인 캐러셀 작업

✅ 인증 방식 변경에 따른 axios instance 작업

✅ 웹 뷰 완성(+동영상 배경)

✅ 카카오톡 공유하기 기능 완성

✅ 에러페이지, 개인정보 처리 방침 페이지 생성

✅ 내 정보 수정 기능 구현

✅ 전역적인 Spinner 설정

리액트 18 버전의 suspense를 활용하여 Spinner를 구성했었습니다.
(lazy loading과 함께 적용)

이때 발생했던 문제점이 페이지를 불러올때는 정상적으로 Spinner가 동작하였으나, 서버와 axios 통신과정에서 생기는 딜레이는 잡아주지 못하는 상황이었습니다.

그래서 고안한 방법이 redux에 global한 상태를 하나 더 추가해주고

app.tsx 파일에 useEffect 훅 + axios의 intercepter를 사용하여 서버에 request를 할때마다 loading 상태를 true 로 바꿔주고 response가 오면 다시 false 로 상태를 변경하게 구성하였습니다.

// global.ts (redux)
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  loading: false,
};

export const globalSlice = createSlice({
  name: 'global',
  initialState,
  reducers: {
    isLoading: (state) => {
      state.loading = true;
      return state;
    },
    isLoaded: (state) => {
      state.loading = false;
      return state;
    },
  },
});

export const { isLoading, isLoaded } = globalSlice.actions;

export default globalSlice;
// App.tsx
...
useEffect(() => {
    instance.interceptors.request.use(
      function (config) {
        appDispatch(isLoading());
        return config;
      },
      function (error) {
        appDispatch(isLoaded());
        return Promise.reject(error);
      }
    );
    instance.interceptors.response.use(
      function (config) {
        appDispatch(isLoaded());
        return config;
      },
      function (error) {
        appDispatch(isLoaded());
        return Promise.reject(error);
      }
    );
  });
...

return (
    <>
      ...
      <Suspense fallback={<Spinner />}>
        <Spinner />
        <Routes>
          <Route path='/main' element={<Main />} />
          <Route path='/main/privacy' element={<Privacy />} />
          <Route path='/' element={<Login />} />
          <Route path='/api/user/login/*' element={<LoginRedirect />} />
					...
        </Routes>
      </Suspense>
    </>
...
// Spinner.tsx
import { useSelector } from 'react-redux';
import { spinnerBasic } from '../../assets/backgrounds';
import { RootState } from '../../redux/configureStore';
import { GridBox } from '../atoms';

const Spinner = () => {
  const { loading } = useSelector((state: RootState) => state.global);

  return (
    <>
      {loading ? (
        <GridBox
          className='fixed w-full  h-full z-50 touch-none'
          type='flexBasic'
        >
          <div className='bg-white absolute opacity-60 h-full w-full'>
            {/*  */}
          </div>
          <div className='m-auto z-10 bg-brownS01bg rounded-full shadow-contents'>
            <img className='w-24' src={spinnerBasic} />
          </div>
        </GridBox>
      ) : null}
    </>
  );
};

export default Spinner;

이처럼 적용을 하니 axios 통신을 할 때도 spinner가 정상적으로 작동하는 것을 확인하였습니다.

이 때 문제점이 Spinner가 loading 상태에서만 출력이 되기 때문에 lazy loading + suspense에 fallback으로 적용된 spinner가 하얀 화면으로 나오게 되었습니다.

( <Suspense fallback={<Spinner />}> )

그래서 global loading 상태에 영향을 받지 않는 SpinnerSuspense.tsx 파일을 하나 추가해 적용을 해주었습니다.

// App.tsx
...
return (
    <>
      ...
      <Suspense fallback={<SpinnerSuspense />}>
        <Spinner />
        <Routes>
          <Route path='/main' element={<Main />} />
...

✅ 설문조사 배너 구현

✅ PWA 적용

✅ 시연영상 제작

기타 버그 수정이나 사소한 부분을 많이 쳤는데도 많은 일을 했다.

자세히 보기
COPICK 브로셔 바로가기
COMMIT 내역

한 주를 보내며

배포 전 마지막 작업이다보니 만들어야할 기능도 많았고, 생각치 못한 버그에 직면하기도 했지만 잘 풀어나갔다.

어제부터 유저 피드백(설문)을 받기 시작했는데, 예상했던 것보다 훨씬 좋은 평가를 많이 받아서 뿌듯하다.
6월 1일 17시 기준으로 약 80명의 회원이 서비스를 이용했고, 평가도 28명이나 해주셨다! 따로 마케팅을 진행하지도 않고 슬랙에 올린게 전부인데 24시간만에 높은 성과라고 생각한다.

프로젝트가 끝나고 '바리스타 2급 필기' 시험에 응시하자고 장난스럽게 말했던 기억이난다.

그만큼 자료조사에 개발자 4명이서 많은 시간을 할애했고, 백엔드 분께서 알고리즘을 잘 짜주셔서 유저에게 좋은 경험도 주었다👍

프로젝트를 하면서 정말 많은 걸 배웠다.

마지막에 급해서 기능구현을 우선시 했지만, 좋은 코드를 많이보고 더욱 많이 고민해서 유지 보수성이 높은 코드를 작성하기 위해 노력해야겠다.

오늘보다 더 나은 내일의 내가 될 수 있도록 정진해야겠다.

profile
keep going

0개의 댓글