항해99 4주차 WIL

오세명·2021년 10월 10일
0

주특기 주차가 쏜살같이 마무리되었다. 하루하루 최선을 다해 강의를 수강하였고, 강의에 있는 내용을 토대로 과제를 진행하였다. 개인적으로 만족스러운 일주일을 보냈으며, 얻은 것도 많았다. 아래의 내용은 내가 일주일동안 공부를 하면서 느꼈던 점을 간략하게 작성한 것이다.

코드를 쓰는 것 만큼 코드를 읽는 것도 중요하다.

인간이 급속도로 진화할 수 있었던 이유중 하나는, 언어의 등장이지 않을까 싶다. 직관적으로 다가왔던 순간의 느낌들을 시간에 구애받지 않고 표현할 수 있기 때문이다. 우리는 언어를 쓰기 전에 언어를 읽는 법부터 배운다. 정해진 규칙에 따라서 생각을 받아들일 줄 알아야, 자신의 생각을 '잘' 표현할 수 있기 때문이다. 그런데 유난히 프로그래밍 언어는 쓰는 것이 읽는 것보다 우선시되는 경향을 보이는 것 같다. 아마 재미가 없어서 그런 것일까? 흥미가 있는지 없는지 판단하기 위함일까? 이유는 여러가지여도 결국 읽는 연습을 하게된다.

나의 경우, redux가 그랬다. redux만의 철학과 그 철학을 이해하기 위해 존재하는 방대한 양의 튜토리얼을 받아들이기가 쉽지가 않았다. 그래서 강의에 있는 리덕스 '사용법'을 먼저 익히고, 개인 프로젝트를 하면서 '리덕스란 이런 느낌이구나' 하고 조금씩 리덕스와 친해졌다. 그러던 문득 리덕스가 어떻게 생긴 코드인지 궁금해지기 시작하였다. 튜토리얼에서 제공하는 문구들은 너무 추상적이기 때문에, 이 코드의 동작 원리가 궁금해진 것이었다. 그래서 본격적으로 redux를 뜯어보기 시작하였다.

처음에 깊은 인상을 받았던 파일은 compose였다. 어떤 함수의 리턴값을 다른 함수의 매개변수에 전달하기 위해 등장한 것 처럼 보였다. 이 유틸 함수는 redux에서 enhancer 또는 middlewares를 묶는 파이프라인을 만들기 위해 사용된다. 도대체 미들웨어가 어떻게 순차적으로 실행이 될 수 있는지 궁금하였는데, 이 코드를 보고 그 추상적인 생각이 몸으로 와닿을 수 있게 되었다.

두 번째로 인상을 받았던 파일은 createStore였다. redux의 모든 API가 응축된 이 함수는 redux의 기능을 나타내는 메서드들을 프로퍼티로 담은 객체를 반환한다. 이 메서드는 클로저로 state, listeners를 참조할 수 있으며, 각각의 behavior는 정말이지 무시무시할만큼 간단하였다. 이 코드를 읽고 찝찝했었던 나의 물음에 대하여 시원스럽게 답변할 수 있게 되었다.

마지막으로 인상을 받았던 파일은 applyMiddleware였다. map을 통하여 각 middleware에게 storeAPI를 주입하고, compose를 통해 next를 주입하는 이 코드는, 정말이지 이렇게 아름다울 수가 없었다. 코드를 읽으면서도 나의 멘탈모델을 교정하기도 하였다.

const store = createStore(...args)
let dispatch = () => {
  throw new Error(
    'Dispatching while constructing your middleware is not allowed. ' +
    'Other middleware would not be applied to this dispatch.'
  )
}

const middlewareAPI = {
  getState: store.getState,
  dispatch: (...args) => dispatch(...args),
}

const chain = middlewares.map((middleware) => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)

return {
  ...store,
  dispatch,
}

이 코드에서 나는 dispatch의 재할당 시점에서, middlewareAPI의 dispatch 프로퍼티에 바인딩 된 함수 caller가 바뀌지 않을 거라는 착각을 하였다. 그런데 코드를 다시 곱씹어 보니, 당연히 바뀔 수 밖에 없었다. 결국 메서드를 호출하는 시점에서의 dispatch에 바인딩 된 함수가 무엇인지에 따라 함수가 다르게 호출되는 것이니까.

정말로 코드를 읽는 것은 코드를 쓰는 것보다 중요하다. 라이브러리를 추상적으로 이해하기만 해서는 그 내부의 속사정을 절대로 알지 못한다. 그러면 그 라이브러리를 이용해서 코드를 어떻게 짤 수 있단 말인가? 물론 힘들고 어렵다. 나의 경우 react-redux와 react는 아직 먼 산 처럼 느껴진다. 그러나, 내가 잘 짜여진 코드를 읽어서 이해한다면, 그 코드를 더 잘 활용할 수 있지 않을까?

전역 상태관리에 대한 고찰

리덕스 튜토리얼을 보면서 다음과 같은 문구를 보았다. "State는 크게 2가지로 나눌 수 있다. 애플리케이션이 작동하기 위해 필요한 핵심적인 데이터(App State)와 애플리케이션이 지금 무엇을 하는지 나타내기 위한 데이터(UI State)." 전역적으로 관리해야할 상태는 애플리케이션이 동작하기 위해 반드시 필요한 핵심이어야 한다는게 이 문구의 골자다. 정말로 공감되는 내용이었다. 무한스크롤 Pagination을 위해 필요한 값들이 '전역적으로 관리되어야 할 필요성이 있는가?' 라고 자문을 해보았었다. Paging은 결국 하나의 컴포넌트(리스트가 되겠다)에서 관리되어야 하지 않을까? 이걸 단순히 전역으로 뺄 이유가 있을까? 많은 생각이 들었다.

그리고 반드시 리덕스를 써야할 필요가 있을까? 라는 생각도 해보게 되었다. RTK가 나왔다고 하더라도 코드 베이스가 너무 복잡하게 느껴지기 때문이다. 물론 리덕스의 철학은 위대하고, 본받고싶지만, 충분히 다른 대안들이 많이 나온 시점에서 리덕스가 언제까지 왕위의 자리를 가질 수 있는지 지켜보는 것도 재미있을 것 같다는 생각이 든다. 나는 리액트 쿼리 또는 Jotai를 사용해보면서 다양한 상태관리의 흐름을 느껴보고 싶다. 경직된 생각에서 벗어나고 싶다. 자유롭고싶다!

CSS 라이브러리와 리액트

나는 정말로 CSS를 못하는 것 같다. 단순히 로직만 잘 짜면 되지! 라고 생각했던 것 자체가 오만이었다. syled-components로 theme을 잡아봐도 결과물은 오징어같이 느껴지고는 했다. 요즈음 MUI와 같은 UI 라이브러리에 대해서 많은 관심을 가지고 있다. 이 라이브러리들은 어떤 식으로 컴포넌트를 만들었을까, 그런 컴포넌트 유닛에 대한 관심이 높아지면서 디자인도 눈에 가고 있다. 도대체 프론트엔드 개발자는 '스타일을 잘 만져야 하는 것'과 '로직을 잘 구현하는 것' 사이에서 어떤 것에 주안점을 두어야 하는건지 알 수가 없다. 아마 둘 다 잘하실 것이다. 지금 당장 못하더라도 조금씩 감각을 쌓아나가야겠다. 결국엔 내공차이이니까.

profile
오네명입니다.

0개의 댓글