[개발일지] 리팩토링 두번째 - 기능 확장

오늘한일

  • 메신저 어플리케이션에 친구 추가 기능 구현

한다면 한다

저번에 리팩토링을 하고나서 썼던 후기 글을 기억하시는가...
보러가기

그때, 나중의 과제로서 남겨두었던 몇가지 사항들이 있었는데, 오늘 드디어 그 과제의 첫번째 스텝으로, 친구 추가하기 기능을 구현해보았다.

Flux랑 전역 상태관리 짱짱

전역으로 상태를 관리하기 때문에 각 컴포넌트에서는 상태에 대한 고민을 할 필요가 줄어드는 장점이 있다. 게다가 이를 Flux 패턴으로 상태의 변경을 관리하니, 코드의 간결성이 매우 증대헀다.

우선 기존의 UserContext는 그저 조회 기능만이 필요했기 때문에 따로 리듀서를 통한 상태변경을 관리하지 않았다. 하지만 이제 상태의 변경이 생기기 때문에 리듀서를 통해 UserContext를 관리해보자.

// userContext.tsx

const userReducer = (state: friend[], action: userReducerAction): friend[] => {
  switch (action.type) {
    case 'user/addFriend':
      return [...state, action.data];
  }
};

우선은 친구 추가 기능밖엔 없지만, 코드는 정말 명확하다. 이제 이를 지난번에 만들었던 custom hook에서 사용해보자.

// useUserContext.ts

const addNewFriend = (friend: friend) => {
    friendsDispatch({ type: 'user/addFriend', data: friend });
  };

이렇게 간단하게 새로운 친구를 추가할 수 있다.

UI는 사드세요

새로운 기능이 추가된다는 것은 또 새로운 페이지를 만들어야 한다는 것 이다. 또 디자인을 하고 배치하고 css 쓰고,,, 뭐 그러기에는 너무 귀찮았다. 난 지금 로직 구현을 하고싶은거지 퍼블리싱을 하고싶은건 아니니까..

그래서 전 부터 계속 눈여겨보았던 UI 라이브러리중 하나인 Next UI를 이번 기회에 적용해보았다. 니꼬 선생님께서 보내주는 메일에서 우연히 찾았는데, 아직 알파버전임에도 불구하고 꽤 깔끔하고 정돈된 UI를 보여준다. 이름에서도 유추가 가능하듯이, Next.js로 유명한 Vercel에서 만든 라이브러리다.

생각보다 쉽지는 않다.

난 그저 버튼이랑 인풋만 빠르게 가져다 쓸 생각이었는데, Next UI에서 제공하는 Grid 시스템이 처음에 적응하는데 꽤 힘들었다. <Container/> 에 붙는 gap 속성은 컨테이너에 padding을 부여하고, <Grid.Container/>에 붙는 gapchildren간의 간격을 설정하는 값이었다. 또, 무지하게 헷갈리는 <Row/>, <Col/> 같은 레이아웃 시스템까지... 적응하면 편하겠지만 아직은 어렵다.

폼나게 form 다루기

리액트에서 form handling 방법은 무수히 많다. 나는 새로운 친구를 추가할 때, 이름과 상태메세지를 입력받는데, 각 input에 onChange 이벤트를 각각 달아주는 폼 안나는 방식 말고 보통 multiple input을 다루는 아주 간지나는 방식을 사용했다.

<Grid xs={10}>
  <Input
    labelPlaceholder="Nickname"
    name="name"
    value={input.name}
    size="xlarge"
    color={helper.color}
    status={helper.color}
    helperColor={helper.color}
    helperText={helper.helperText}
    {...inputAttributes}
    />
    </Grid>

<Grid xs={10}>
  <Input
    labelPlaceholder="Status"
    status="default"
    name="statusMessage"
    value={input.statusMessage}
    {...inputAttributes}
    size="xlarge"
   />
</Grid>

보다시피, input이 2개인데, 이거를 onChange에서 어떻게 다루냐면,,

const handleInputChange = (e: any) => {
    setInput({ ...input, [e.target.name]: e.target.value });
  };

이런식으로 input의 name에 맞는 속성에 해당 값이 들어가도록 할 수 있다. 처음에 이거보고 굉장히 신박하다고 생각했다.

친구 추가

그래서 결국 친구는 어떻게 추가되는가 하면,

// AddFriend.tsx

const handleAddButtonClick = (e: any) => {
    addNewFriend({ ...input, id: Date.now() });
    alert("친구가 추가되었습니다.");
    history.push("/");
  };

이렇게 Flux 패턴을 적극 이용하여 친구 추가를 단 한줄에 끝~! id는 랜덤한 값으로 넣어주었다.

그래서 결과물 짜잔


자 아래의 친구추가 버튼을 누르면

이렇게 form이 짠 하고 뜬다.

친구의 정보를 입력한다.

비어있으면 이렇게 경고도 띄워준다, 하여튼 친구를 넣으면,

짜잔~ 새로운 친구가 생성되었다 친구비 낼돈이 늘었네

Retrospect

역시 확장성을 염두에 두고 어플리케이션을 작성하면 아름다운 미래가 펼쳐지는 것 같다.
다음엔, 친구 삭제, 새로운 채팅방 개설 기능을 추가해봐야 겠다.

좋은 웹페이지 즐겨찾기