리액트의 특징 중 하나가 선언형 프로그래밍이라는 점이다. 그런데 선언형 프로그래밍이 도대체 뭘까? 아무리 찾아봐도 설명이 어렵게 되어 있어 나름 정리해 보았다.
우리는 리액트로 작업할 때 어떤 로직으로 어떻게 코드를 짜야 페이지가 그려질 수 있는지에 대해 생각하기보다는, 컴포넌트나 데이터 등의 배치를 통해 무엇이 렌더링 될지에 대해 생각한다. 이게 선언형 UI의 핵심이다.
선언형으로 작성된 코드는 영어를 할 수 있다면 의도를 쉽게 파악할 수 있다. 아래 두 코드의 차이를 살펴보자.
명령형 코드는 결과물을 얻기 위한 '과정'에 집중한다.
아래 예제를 보면 배열에 있는 숫자가 어떤 식으로 반복되고 계산될지 로직을 직접 구현하고 있다.
const numbers = [1, 2, 3, 4, 5, 6];
let sum;
sum = 0;
for (let i = 0; i < numbers.length; i++) {
if (i % 2 === 0) {
sum += numbers[i] * 2;
}
}
console.log(sum); // 18
filter, map, reduce 메서드가 어떤 로직으로 구현되는지 우리는 알 필요가 없다. 이미 메서드 안에 서술되어 있기 때문에 우리는 구체적인 절차는 신경쓰지 않고, 추상화된 메서드를 사용하고 싶을 때 선언만 하면 되는 것이다.
const numbers = [1, 2, 3, 4, 5, 6];
let sum;
sum = numbers
.filter(i => i % 2)
.map(i => i * 2)
.reduce((acc, next) => acc + next);
console.log(sum); // 18
JSX 자체가 선언형은 아니다. 하지만 JSX의 캡슐화를 통해 선언형 코드 작성이 가능해진다. 아래 코드를 보면 이해가 쉬워진다.
const App = () => {
<Nav />
<Menu />
<Detail />
}
<Nav />
, <Menu />
, <Detail />
는 JSX로 작성된 코드를 캡슐화한 컴포넌트다. 각 컴포넌트의 자세한 코드는 직접 들어가봐야 알겠지만, 어떤 순서와 어떤 내용으로 화면에 그려질지는 대충 예측할 수 있다.
또한 우리는 <Nav />
, <Menu />
, <Detail />
의 렌더링되는 과정까지 알 필요가 없다.
이러한 특징 덕분에 리액트 개발자는 컴포넌트 관련 작업만 신경쓰면 된다.