로직을 공유하는 5가지 방법 (feat. React Class Component)

NinjaJuunzzi·2022년 5월 25일
6

우아한테크코스

목록 보기
16/21
post-thumbnail

👻쥬니어가 제안하는 로직을 공유하는 5가지 방법👻

리액트 개발자신가요? 당신은 어떻게 로직을 공유하고 있나요?

(???: 커스텀 훅이요!)

당신은 Modal UI를 개발해야하는 프론트 개발자입니다. 이 때 최신 리액트 개발자라면... 모달을 사용하는 컴포넌트에서 사용되는 로직들은 대게 다음과 같이 useModal 스러운 커스텀 훅을 만들어 로직들을 뭉쳐놓고 재사용하게 할 것 같아요.

export const useModal = () => {
  const [isShowModal, setIsShowModal] = useState(false);

  const openModal = useCallback(() => {
    setIsShowModal(true);
  }, [setIsShowModal]);

  const closeModal = useCallback(() => {
    setIsShowModal(false);
  }, [setIsShowModal]);

  const toggleModal = useCallback(() => {
    setIsShowModal(prev => !prev);
  }, [setIsShowModal]);

  return {isShowModal, openModal, closeModal, toggleModal};
};

(극단적 커스텀 훅 파이기에... 너무나 사랑스러워보인다는..)

하지만 훅이 없던 그 시절이라면 ?! 혹은 리액트가 아닌 바닐라 코드를 짜고 있다면 당신은 어떻게 로직을 공유하게 할 것인가요!? 저는 5가지 방법을 제안하고 싶습니다.

1. 탐스러운 확장

빨간 자동차, 파란 자동차 모두 move라는 공통 로직을 수행할 수 있어야 합니다. 이 경우 가장 먼저 떠오르는 방법은 확장이 아닐까 싶어요. (YO! 다른 말로는 상속)

class Car {
  move() {
    console.log("move");
  }
}

class RedCar extends Car {
  color = "red";
}

class BlueCar extends Car {
  color = "blue";
}

const redCar = new RedCar();
const blueCar = new BlueCar();

redCar.move();
blueCar.move();

2. 기능만을 입혀주는 클래스

전화기던 패드던 전화가 될 수 있으면 참 좋겠죠? 다음은 call 기능을 공유하게 해줍니다.

class Callable {
  constructor(device) {
    this.device = device;
  }

  call() {
    console.log(this.device.name);
  }
}

class Phone {
  name = "phone";
}

class Pad {
  name = "pad";
}

const phone = new Phone();
const pad = new Pad();

const callablePhone = new Callable(phone);
const callablePad = new Callable(pad);

callablePhone.call();
callablePad.call();

3. 고차 컴포넌트 (feat. React)

log를 찍는 공통 로직을 컴포넌트에 입혀주고 싶어요! 그렇다면 다음과 같이 로직을 공유하게 할 수 있을 것 같아요!!

import React from "react";
import ReactDOM from "react-dom";

// 1. 단순한 고차함수
const withLog = (Component) => {
  return class extends React.Component {
    componentDidMount() {
      console.log("mount");
    }

    render() {
      return <Component />;
    }
  };
};

// 2. 발가벗은 컴포넌트
class Component extends React.Component {
  render() {
    return <div>hi</div>;
  }
}

// 3. 고차함수로 인해 옷을 입어버린 고차컴포넌트
const WrappedComponent = withLog(Component);


class App extends React.Component {
  render() {
    return <WrappedComponent />;
  }
}

ReactDOM.render(<App />, document.getElementById("container"));

4. 단순한 함수 분리 (feat. React)

log 함수를 외부 스코프에 선언, 정의해두고 여러 컴포넌트에서 로그를 찍을 일이 있을 때 사용하게 한다면? 사실상 이 또한 공통 로직을 공유하게 하는 셈이겠죠!! (순수하게 작성해준다면 더욱 좋은 기능 분리가 아닐까 싶어요)

const log = (state) => console.log(state);

class Component extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: 10
    };
  }

  componentDidUpdate() {
    // 공통 로직을 함수로 분리
    log(this.state.data);
  }

  render() {
    return (
      <div>
        <div>{this.state.data}</div>
       
        <div onClick={() => this.setState({ data: this.state.data + 1 })}>
          button
        </div>
      </div>
    );
  }
}

class App extends React.Component {
  render() {
    return <Component />;
  }
}

ReactDOM.render(<App />, document.getElementById("container"));

5. 상위 컴포넌트에서 제어 (feat. React)

간단해요!! 하위 컴포넌트들에서 공유하는 로직이 있다면 하위 컴포넌트 단에서 이를 작성해줄게 아니라 상위 컴포넌트에서 함수를 만들어 하위 컴포넌트로 뿌려주게 하는거죠!!

import React from "react";
import ReactDOM from "react-dom";

class ComponentA extends React.Component {
  constructor(props) {
    super(props);
    this.props = props;
  }

  componentDidMount() {
    this.props.log("A");
  }

  render() {
    return <div>A</div>;
  }
}

class ComponentB extends React.Component {
  constructor(props) {
    super(props);
    this.props = props;
  }

  componentDidMount() {
    this.props.log("B");
  }

  render() {
    return <div>B</div>;
  }
}
// 공통 로그 로직을 위에서 만들어 내려준다.
class App extends React.Component {
  log(data) {
    console.log(data);
  }

  render() {
    return (
      <>
        <ComponentA log={this.log} />
        <ComponentB log={this.log} />
      </>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));

정리

로직을 공유할 수 있는 5가지 방법에 대해 알아보았어요!! 당신은 공유하는 로직을 하위 컴포넌트 각각 코드를 작성하며 처리하고 있나요? 자세히 바라보면 트레이드 오프가 있겠지만, 한 번쯤은 코드를 되돌아보는 것도 나쁘지 않을 것 같네요 🐸🐸🐸

(유지보수 무한루프에 빠지지 맙시다!)

profile
Frontend Ninja

1개의 댓글

comment-user-thumbnail
2022년 9월 25일

이 분 저희 회사에서 채용하고 싶은데 갠톡주세요ㅋ

답글 달기