6.17.2020

React 컴포넌트에서 많은 스타일 설정을 넘겨 주어야 할 때 쓸 수 있는 방법 1 (Feat. JavaScript Class)

최근에 클린코드에 대한 관심을 가지고 포트폴리오 프로젝트 하나를 리팩토링 중이다.

그 과정에서 하나의 컴포넌트에 너무 많은 props를 넘겨주는 상황이 있었다. 컴포넌트를 사용할 때마다 스타일 요소를 지정해서 사용할 수 있게 하려고 그렇게 작성하였다. 하지만 함수도 그렇고, 컴포넌트도 그렇고 전달인자는 되도록이면 3개를 넘지 마라는 조언이 있었다. 따라서 인자의 성질에 따라 config와 styles라는 인자로 나눴다. 가장 많이 차지하는 style요소들을 어떻게 넘겨줄까 고민했다. 객체로 만들어 일일이 호출할 때마다 부르는 것은 비효율적인 것 같았다. 함수를 만들어 조정할까 했는데, 그것도 뭔가 깔끔해보이지 않았다. 한 일주일동안 머리를 싸매면서 코드를 썼다 지우고, 썼다 지웠다. 결국 폭풍 구글링을 해보다가 class를 활용해보면 어떨까 하는 아이디어를 얻었다.


class로 구현하는 과정도 어떻게 하면 사용하는 사람이 직관적으로 쉽게 알 수 있을까 고민하며 많은 시간을 보냈다. 그리고 오늘, 그동안의 고민이 빛을 발해 어느 정도 코드로 구현할 수 있었다. 여러가지 개선할 점들이 계속 생각나지만, 우선 블로그에 기록을 먼저 남긴다.

아래는 Link라는 컴포넌트를 호출할 때 필요하던 인자의 before & after이다. 처음에는 정말 클린코드를 하나도 신경 안 쓰고 의식의 흐름대로 썼었다.

리팩토링 전과 후

컴포넌트 이름과 타입을 입력하면 스타일 객체를 반환

아래는 컴포넌트의 styles 인자로 들어갈 객체를 설정하고, 반환받는 클래스 코드이다.

import defaultSetting from "./defaultStyleSetting";

class SetProperty {
  constructor() {}

  get property() {
    return Object.keys(this.style);
  }

  set property(nameAndValue = ["", ""]) {
    this.style[nameAndValue[0]] = nameAndValue[1];
  }
}

class Property extends SetProperty {
  constructor(componentType = "none") {
    super();
    this.type = componentType;
    this.style = {};
  }

  get styles() {
    return this.style;
  }

  init(name = "null") {
    if (Object.keys(defaultSetting).includes(this.type.toLowerCase())) {
      if (Object.keys(defaultSetting[this.type.toLowerCase()]).includes(name)) {
        this.style = {
          ...defaultSetting[this.type.toLowerCase()].default,
          ...defaultSetting[this.type.toLowerCase()][name],
        };
        console.log(defaultSetting[this.type.toLowerCase()][name]);
      } else {
        this.style = defaultSetting[this.type.toLowerCase()].default;
      }
    } else {
      return console.error(
        "There are no such component style setting, please check your name"
      );
    }
    return this;
  }
}

export default Property;

우선 defaultStyleSetting이라는 파일에서 스타일 정보가 들어가 있는 객체를 가져온다. 그 후에는 class 두 가지를 만든다. 첫 번째 class SetProperty는 정해진 타입 외에 수동으로 property를 바꿔야 하는 경우를 위해 만들었다. 두 번째 객체는 SetProperty를 이어받고, type이라는 인자를 통해 어떤 컴포넌트의 스타일을 반환해야 하는지 결정한다. type이 정해지면 연달아 init 함수를 실행시켜야 한다. 이 함수는 해당 컴포넌트의 어떤 설정을 반환해야 하는지 정하는 name이라는 인자를 받는다. type과 name이 존재한다면 해당 설정을 default와 합쳐서 this.style에 대입한다. type이 없는 경우는 console.error를 반환하고, name이 없는 경우에는 해당 컴포넌트의 default 스타일을 반환한다.

지금은 컴포넌트를 호출할 때 인자로 클래스의 결과물을 넘겨준다. 하지만 글을 쓰면서 생각해보니, 인자로 매번 넘겨주면 너무 무거운 것 같아서, 위 클래스의 name string만 넘겨주면 그 컴포넌트 안에서 클래스를 호출하는 것이 더 나을 것 같기도 하다.

참고로 이야기 하자면, 이것을 함수로 구현할지, 아니면 위와 같이 class를 활용해서 구현할지 많이 고민했다. reddit이나 블로그 글들을 찾아서 읽어보면서, 어떤 방법이 더 나은 방법인지는 그 사람의 의견에 따라 의견이 분분하다는 것을 발견했다. 여러 글을 읽고 나서도 정확히 내가 처한 상황에서는 어떤 것의 적용이 좋은지 결정하기 어려웠다. 결국 기존에 시도하던 함수 방식보다 class 방식으로 접근해보면서 새로운 것을 배워보는 것이 나쁘지 않다는 판단에 이러한 방향으로 시도해 보았다.

아직도 클린 코드와는 거리가 멀다. 계속 고민하고 시도하다 보면 내일은 오늘보다 좀 더 나은 코드를 짤 수 있을 것이라 믿는다.


Share:

0 comments:

댓글 쓰기