// 명령형으로 짠 DOM 명령어
const greeting = "Hello, Imperative!";
const p = document.createElement("p");
p.textContent = greeting;
const app = document.getElementById("app");
app.appendChild(p);
// 선언형(Declarative) 코드 예시 (React/JSX)
function Greeting() {
const greeting = "Hello, Declarative!";
return <p>{greeting}</p>;
}
React가 어떻게 를 내부적으로 처리합니다.
우리는 지시를 내리지 않음
그저 최종적으로 UI가 무엇이어야 하는지 선언할 뿐
즉 "인사말을 담고 있는 p태그가 필요하다"고 말하는 것.
복잡한 DOM조작 과정, 즉 '어떻게'에 해당하는 부분은 React라이브러리가 완전히 추상화하여 대신 처리해줌.
'관신삼의 분리'기준이 바뀐다. 기술이 아닌 기능으로
과저에는 관심사 분리는 역할에 따라 HTML, CSS, Javascript 로 나뉘었음
이는 각 기술의 역할과 문법이 명확히 달랐기에 자연스러운 기준.
하지만 React의 JSX와 같은 선언형 UI패턴이 등장하면서 이 기준은 근본적으로 바뀌었음
자바스크립트를 마크업처럼 작성할 수 있게 되면서 기술 간의 경계가 허물어졌기 떄문.
이제 기술이 아닌 '하나의 기능' 또는 '하나의 컴포넌트'를 기준으로 관련된 모든 코드(구조, 스타일, 동작)을 한 곳에 묶는 방식이 더 효율적인 '관심사의 분리'로 여겨짐
이러한 변화가 더 논리적인 이유는?
"우리가 보통 앱에서 표현하고자 하는 것이 트리 구조가 아니기 때문"
우리가 표현하고자 하는 것은 바로 정보이다.
과거의 방식은 코드를 기술 중심으로 구성했지만, 새로운 방식ㅇ느 사용자가 마주하는 정보 쪼는 기능을 중심으로 코드를 구성합니다.
'프로필 카드'라는 하나의 기능을 구현하는 데 필요한 모든 코드가 한 파일에 모여 있다면, 울니느 제품의 구조와 코드의 구조를 일치시킬 수 있습니다.
이는 코드 응집도를 높여 이해와 유지보수를 훨씬 용이하게 합니다.
하지만 그 기능의 가장 큰 관심사가 복잡한 데이터를 가져오고 관리하는 것이라면 어떻게 해야하나? 선언적 사고방식의 다음 진화는 이 문제를 해결한다.
UI를 넘어 데이터까지: 선언현 패러다임의 확장.
선언현 패러다임은 UI를 넘어 데이터 관리 영역으로 자연스럽게 확장됨.
예를 들어 사용자가 소셜 미디어 앱에서 프로필 이미지를 변경했다고 상상해보자.
피드를 스크롤하다 보면 오래된 글에느 ㄴ이전 이미지가, 새 글에는 바꾸니 이미지가 보이는 데이터 불일치 상황이 발생할 수 있슴
이 문제를 해결하기 위해 '단일 진실 공급원' 개념이 등장함
하지만 여러 컴포너트가 서로 얽힌 복잡한 데이터 그래프의 일부를 필요로 할 떄, 이 데ㅐ이터를 가져오고, 정규화하고, 일관성을 유지하는 '어떻게'의 문제가 여전히 남음
"리액트가 UI렌더링의 'How'를 가져갔던 것처럼, GraphQL은 데이터 처리의 'How'를 가져갈 수 있음"
UI는 컴포넌트는 자신이 필요한 데이터가 무엇인지를 GraphQL 조각 문법으로 코드 바로 옆에 선언하기만 하면 됩니다.
이는 2장에서 다룬 '지능 중심의 관심사 분리'개념의 궁극적인 확장이비다.
이제 컴포넌트는 자신의 렌더링 로직 뿐만 아니라 데이터 의존성 까지 한 곳에서 관리하게 됩니다.
데이터를 네트워크에서 가져오고, 중복을 제거하며 정규화하고, 데이터가 변경되었을 때 관련된 모든 UI를 자동으로 업데이트하는 복잡한 과정은 Relay나 Apollo 같은 GraphQL 기반 라이브러리가 알아서 해줌.
결과적으로 개발자는 데이터 관리의 복잡성에서 벗어나 비즈니스 로직과 사용자 경험을 반드는데 더 집중 할 수 있다.
// 로그인 여부를 체크하고 리다이렉트하는 로직
app.use((req, res, next) => {
if (!req.user) {
res.redirect("/login");
} else {
next();
}
});
// 'How'를 추상화한 미들웨어
app.use(redirectIf((req) => !req.user, "/login"));
const redirectIf = (compare, to) => {
return (req, res, next) => {
if (compare(req)) {
res.redirect(to);
} else {
next();
}
}
}