본문으로 건너뛰기

01 프레임워크에 대한 이야기

인용

프레임워크는 필요 없다. 중요한 것은 그림이지 프레임(그림틀)이 아니다.

클라우스 킨스키(Klaus Kinski)

프레임워크란?

  • 무언가를 만들 수 있는 지지 구조
  • 프레임워크는 코드를 호출한다. 코드는 라이브러리를 호출한다.

프레임워크 방식

  • 프레임워크에는 제약 조건이 포함된다.
    • 프로젝트에 적합한 도구인지 평가하려면 팀이 선택한 프레임워크의 방식을 분석하는 것은 매우 중요하다

리액트

사용자 인터페이스를 만들기 위한 JavaScript 라이브러리

  • 리액트의 주요 제약 사항은 선언적 패러다임의 사용이다.
  • DOM을 직접 조작하는 대신 구성 요소의 상태를 수정한다. 그러면 리액트가 대신 DOM을 수정한다.

예제코드

사용자가 토글 버튼을 누를 때마다 애니메이션으로 사각형을 표시하거나 숨기는 것

리액트의 선언형 패턴
import React, { Component } from 'react';
import posed from 'react-pose';

/* 상태 관리 박스 */
const Box = posed.div({
hidden: { opacity: 0 },
visible: { opacity: 1 },
transition: {
ease: 'linear',
duration: 500,
},
});

class PoseExample extends Component {
constructor(props) {
super(props);
this.state = {
isVisible: true,
};

this.toggle = this.toggle.bind(this);
}

toggle() {
this.setState({
isVisible: !this.state.isVisible,
});
}

render() {
const { isVisible } = this.state;
const pose = isVisible ? 'visible' : 'hidden';
/* isVisible 상태에 따라 박스 노출이 달라짐 */
return (
<div>
<Box className="box" pose={pose} />
{/* 박스에 상태 부여 */}
<button onClick={this.toggle}>Toggle</button>
</div>
);
}
}

export default PoseExample;
  • 컴포넌트를 다룰 때 직접 조작하지 않고 상태를 맵핑하고 상태를 변경하고 있다. 이것이 리액트에서 사용되는 선언적 패턴의 핵심이다.
  • Box를 어떻게 조작되는지보다 무엇과 같은 지 그 상태 자체를 보자
리액트의 명령형 패턴
import React, { Component } from 'react';

const animationTiming = {
duration: 500,
ease: 'linear',
fill: 'forwards',
};

const showKeyframes = [{ opacity: 0 }, { opacity: 1 }];

const hideKeyframes = [...showKeyframes].reverse();

class PosedExample extends Component {
constructor(props) {
super(props);
this.state = {
isVisible: true,
};

this.toggle = this.toggle.bind(this);
}

toggle() {
this.setState({
isVisible: !this.state.isVisible,
});
}

componentDidUpdate(prevProps, prevState) {
const { isVisible } = this.state;
if (prevState.isVisible !== isVisible) {
const animation = isVisible ? showKeyframes : hideKeyframes;
this.div.animate(animation, animationTiming);
}
// 조건문으로 animate 해주고 있음
}

render() {
return (
<div>
<div
ref={(div) => {
this.div = div;
}}
// 돔에 직접 접근하고 있음
className="box"
/>
<button onClick={this.toggle}>Toggle</button>
</div>
);
}
}

export default PosedExample;
  • 웹 애니메이션 API라는 표준 API를 기반으로 한 코드
  • ref를 사용해 조건문으로 박스를 직접 animate해주고 있다.

기술부채와 기술투자

프레임워크 비용

모든 프레임워크는 기술 부채를 갖고 있다.
프레임워크는 아키텍처 자체에 이미 비용을 포함하고 있다.
시간이 지남에 따라 시장이나 다른 요인으로 인해 소프트웨어의 변경이 필요하며, 아키텍처 역시 변경돼야 한다.
대부분의 경우 이런 변경이 필요한 상황에서 프레임워크는 오히려 장애물이 된다.

하지만 기술 부채가 항상 나쁜 것만은 아니라는 사실을 명심하자.
합리적인 이유로 빠른 솔루션을 사용한다면 기술 부채가 아니라 기술 투자가 된다.
합리적인 이유로 선정된 프레임워크는 비용이 아니라 자산이다.

독후감

  • 저자는 리액트가 프레임워크로 볼 수 있다고 이야기하고 있지만, 내 생각에는 리액트라는 도구를 어떻게 쓰느냐에 따라서 다른 것 같다.
    어색하긴 하지만 명령형 프로그래밍을 쓰려면 쓸 수 있기 때문이다. 다만 이는 도구를 올바르게 쓰고 있는 것이 아닐 뿐이다.
    React를 기반으로 만들어진 Next 프레임워크는 제약사항이 많고 그 규칙에 따라 쓰지 않으면 에러부터 뿜어낸다.
    나도 한때는 React가 프레임워크인지, 라이브러리인지 혼란스러웠지만, Next를 써보니 둘의 차이를 이해할 수 있게 되었다.

    그러나,
    리액트가 라이브러리냐 프레임워크냐는 사실 중요한 게 아닌 것 같다.
    나는 어떤 도구든지간에 도구를 상황에 맞게 올바르게 사용하는 것이 더 중요하다고 생각한다. 아마 저자도 그것을 더 중요하게 생각할 것이다.