[POB#16] Assignment 4 : wanted 기업과제. 책 찾기 프로젝트 코드 리뷰

dongwon·2021년 8월 10일
2

원티드-프리온보딩

목록 보기
11/25
post-thumbnail

Assignment 4 과제 후기 글입니다.
리팩토링 레파지토리

🎯 Assignment 4 : wanted

이번 과제는 평소 과제와 달리 급하게 개발된 프로젝트를 코드 리뷰하는 과제입니다. 동시에 확장성재사용 가능한 코드를 고려하여 리팩토링도 진행해봤습니다.

코드 리뷰 내용은 따로 정리했기 때문에 어떻게 코드 리뷰를 진행했는지 작성하려 합니다.

코드 리뷰 정리 보러 가기

코드리뷰 어떻게 하는 거지 ?

사실 같은 직군간 협업은 프리 온보딩 들어와서 거의 처음 해봤기 때문에 코드 리뷰를 제대로 해본 경험이 없습니다. 따라서 어떻게 진행해야 하나 고민하다 코드를 분석해보며 아쉬웠던 점, 개선하면 좋을 것 같은 점들을 바로바로 적어가며 분석해봤습니다.

코드 분석 방법
프로젝트의 시작인 index.js, app.js 부터 router 구현 로직을 보고 마치 DFS + BFS 알고리즘처럼 모든 컴포넌트들을 분석합니다.

기억에 남는 코드 리뷰

제가 봐도 개선이 필요하다고 알 수 있었던 것들을 정리해봤습니다.

시멘틱 태그

대놓고 제목이라고 되어있는 곳도 div 태그를 이용한 마크업 구조입니다.
검색 결과를 보여주는 메인 컴포넌트이기 때문에 main 태그를 사용했고 검색 리스트들을 ul, li 태그를 이용해 마크업 했습니다.
img 태그alt의미 있게 작성하고, 세부 내용을 section으로 감싸고 제목 부분을 h3 태그를 이용해 마크업 했습니다.

리덕스

이번 코드 리뷰의 키워드 중 하나는 확장성 고려입니다. 따라서 지금 당장은 보기 불편하지 않고 오히려 더 나은 구조이지만 확장성을 고려해 잘게 나누는데 초점을 맞춰 리팩토링했습니다.

리덕스 구조

store 폴더 안에 store 생성 로직, reducers 로직, 비동기 네트워크 통신 로직이 모두 한 폴더 안에 담겨져 있었습니다. 확장성을 고려해 이 세 가지 로직을 모두 분리했습니다.

store 폴더
reduxToolkitconfigureStore를 이용해 store 생성, middleware 설정, devTools 관리를 한 번에 구현했습니다.

const store = configureStore({
  reducer: rootReducer,
  middleware: [sagaMiddleware],
  devTools: process.env.NODE_ENV !== "production",
});

reducers 폴더
reducer는 이미 redux toolkitcreateSlice를 이용해 굉장히 깔끔하게 구현이 돼있었습니다.(아마도..?) redcuer 밑에 구현된 비동기 네트워크 통신 부분만 따로 분리했습니다.
다만 initialState를 밖에서 구현하는 걸 선호하기 때문에 밖에서 구현했고, 실패 시 상태 설정이 누락되어 있어 추가했습니다.

const initialState = {
  items: [],
  totalItems: 0,
  startIndex: 0,
  status: STATUS.Idle,
  error: null
}

const booksSlice = createSlice({
  name: 'books',
  initialState,
  reducers: {
    ...
    getItemsFailure(state, action) {
      state.status = STATUS.Failure
      state.error = action.payload
    }
  }
})

비동기 네트워크 통신 로직 ( sagas 폴더 )

export const fetchBooks =
  (search, startIndex = 0) =>
  async (dispatch) => {
    try {
      dispatch(getItemsStart(startIndex));
      const response = await getBooks(search, startIndex);
      const data = await response.json();
      dispatch(getItemsSuccess({ ...data, startIndex }));
    } catch (error) {
      dispatch(getItemsFailure(error));
    }
  };

굉장히 익숙한 구조를 보고 비동기 네트워크 통신을 하는 로직임을 알아차렸습니다. 사실 redux-thunk와 유사한 코드이지만, 역시 확장성을 고려해 다양한 effect가 있는 redux-saga로 리팩토링하기로 결정했습니다.

// redux-saga로 구현
function* fetchBooksSaga(action) {
  const { search, startIndex } = action.payload;

  try {
    const response = yield call(fetchApi.fetchBooksAPI, search, startIndex);

    yield put({
      type: getItemsSuccess.type,
      payload: { ...response.data, startIndex },
    });
  } catch (e) {
    console.log(e);
    yield put({
      type: getItemsFailure.type,
      payload: e,
    });
  }
}

코드 리뷰 후기

  • 사실 리액트에 대해 남의 코드를 보고 리뷰할 수준이 안된다고 생각돼서 내가 생각하는 게 맞는지 틀린 지 정확히 판단이 가지 않았습니다. 하지만 코드 리뷰라는 게 꼭 정답을 짚어야 코드 리뷰가 아니듯, 의견을 내는 방식으로 코드 리뷰를 진행했습니다.

  • 코드 리뷰를 하기 위해 코드를 분석하다 보니 어느 순간 왜 이렇게 코드를 구현했는지 이해를 하고 수긍하고 있었습니다. 코드 분석을 한 후 리뷰를 하는 과정을 거치면 더 좋은 코드 리뷰를 할 수 있을 거라 생각됩니다.

  • CSS는 처음 보는 구조라 검색을 해봤습니다. 검색 결과 tailwind css였고 대충 공식 문서를 보고 사용법을 봤는데 딱히 개선할 부분은 보이지 않아 CSS는 큰 신경을 쓰지 않았습니다.

  • 코드 리뷰 내용이 맞는지 확인하기 위해 오히려 더 공부를 많이 했습니다. 이 태그의 사용법이 맞는지, 커스텀 훅을 어떻게 하면 더 잘 구현하는지, redux-toolkit의 사용법 등 남의 코드를 리뷰해 주려다 제가 더 성장한 느낌이 들었습니다.

  • 서비스 기업의 기업 문화 중 코드 리뷰를 굉장히 중요시하는 기업이 많은 걸로 알고 있습니다. 비슷한 예제로 실제로 코드 리뷰를 경험할 수 있어 많은 도움이 된 것 같습니다.

profile
데이원컴퍼니 프론트엔드 개발자입니다.

0개의 댓글