TIL8 | 회원가입 페이지 리팩토링

hyseoseo·2021년 8월 14일
1

React

목록 보기
4/7

회원가입 페이지 회고를 하면서 제출했던 코드에서 아쉬운 부분을 많이 발견했다.

  • if else 범벅 함수
    input form html 태그 및 리액트에서 form을 제어 컴포넌트(controlled component)로 작성하는 법에 대한 이해 부족으로 인해, 사용자의 입력값을 다루는 함수가 복잡해졌다.

  • 중복된 코드
    회원가입 페이지와 관리자 페이지에서 회원정보를 입력받는 동일한 컴포넌트를 활용하려는 기획에 따라, state 관리 및 api 호출 전 입력값 validation은 각 페이지에서 진행했다. 이 부분을 따로 hook이나 함수로 분리하지 않아서 두 페이지 컴포넌트에 동일한 코드가 반복 작성되었다.

  • too many states
    회원정보의 여러 요소를 개별 state로 설정하였더니 state가 너무 많아서 가독성이 떨어졌다. 물론 state의 개수보다는 state가 얼마나 자주 갱신되어 렌더링이 일어나느냐가 성능 관련으로 중요한 요소이므로, state가 많다고 해서 무조건 객체 안으로 우겨넣는 것이 바람직한 것은 아니다.
    그러나 현재 내 코드에서 회원정보 각 요소들은 한 덩어리의 회원정보로 묶여서 POST 요청의 body로 전달되어야 한다. 결국 POST 하는 함수 내에서 따로 회원정보 객체를 만들어서 각 property의 value를 state 값으로 채워주고 있기 때문에 효율성이 떨어진다고 생각되었다.


발견한 문제점들을 아래와 같이 수정해 보았다.

1. 연관된 state들을 하나의 객체로 모으기

기존

  • 회원 정보 관련 state의 수가 너무 많고 각 state를 setting하는 함수를 개별적으로 props로 내려보내야 해서 가독성이 떨어졌다.
  • input 정보를 개별 state로 관리하였기 때문에 api 호출 직전에 각 state 값을 받는 userInfo 객체를 새로 생성해야 했다.

수정 후

  • user 관련 정보들을 한 번에 모아서 POST 하기 때문에, 기존 state들을 newUser라는 하나의 객체 state로 모아서 state의 수를 줄이고 가독성을 높였다.
  • user 관련 정보 초기 상태를 여러 개의 컴포넌트에서 공통으로 사용하므로 initialValues라는 변수로 constants에 저장하고 사용하였다.
  • newUser state 객체 property를 backend api 명세상 property와 일치시켜서 newUser 객체를 POST body로 바로 사용할 수 있게 수정하였다.

2. Input onChange 함수 변경

기존

  • input 컴포넌트들에게 공통적으로 전달되는 handleChange 함수에서 if else 분기문으로 각 정보값 setting을 했다.
  • Clean Code에서는 조건문 작성을 피하라고 권한다. 조건문을 포함하는 함수는 단 하나의 일만 수행하여야 한다는 컨셉을 위배하기 때문이다.

수정 후

  • input tag의 name attribute를 이용하여 newUser 객체의 property들을 각 input의 name으로 전달하고 handleChange 함수를 간결하게 만들었다.

사실 기존에는 event.target에서 name 값을 받으려 하니 자꾸 undefined가 나와서 결국 if else 분기문을 쓰게 되었는데, name 값이 없었던 이유는 form tag를 사용하지 않았기 때문이었다...😂

3. custom hook 사용으로 중복된 코드 삭제

기존

  • 기획상 SignUp 컴포넌트는 user 정보를 입력받는 기능까지만 수행하고, validation 및 api를 호출해서 해당 정보를 백엔드로 보내는 것은 회원가입 페이지(Register.js)와 관리자의 계정 생성 및 수정 메뉴(ManageMenu.js)에서 처리하였다. 그 결과 두 컴포넌트에서 userInfo state와 validation 함수를 중복 작성하게 되었다.
  • Clean Code에서는 중복된 코드를 작성하지 않기 위해 최선을 다하라고 권한다. 중복된 코드가 있다면 로직을 수정해야 할 때 수정해야 할 코드가 두 군데 이상이 되어, 버그를 발생시키기 쉽다.

수정 후

  • 로그인을 담당한 팀원 분이 작성한 useForm custom hook를 적용하여 코드의 중복을 피하도록 했다. useForm 안에서 userInfo 상태 관리 및 validation을 수행한다. api를 호출하는 부분은 useForm 호출시 인자(onSubmit)로 전달하기 때문에 회원가입 페이지와 관리자 페이지에서 서로 다른 작업을 할 수 있다.
  • 다음 우편번호 api를 사용하는 주소 입력창의 경우 다른 input 창과는 다르게 동작하는 부분이 있어서, useForm에 주소 부분을 처리하는 함수를 추가하였다. 또한 password confirmation의 경우 입력받은 password 값과 비교하여 validate해야 하기 때문에 useEffect를 사용하여 validation pattern을 동적으로 설정하도록 했다.
  • 만약 전역으로 상태를 관리한다면 SignUp 컴포넌트 내부에서 useForm을 사용하고 회원가입과 관리자 페이지에서는 userInfo 상태를 get하여 사용하면 되므로, 중복 코드를 더 줄일 수 있을 것 같다.



코드를 그대로 적어놓기는 너무 길어서 접기/펼치기를 쓰려고 했는데, velog 에디터시여 왜 details tag를 지원하지 않나요..? ㅠㅠ

여튼 회고 후에 가슴이 답답했는데, 내가 문제를 느꼈던 부분들만이라도 리팩토링을 하게 되니 후련하다...!

0개의 댓글