명령형(Imperative)·절차적(Procedural) 프로그래밍은 결과에 도달하는 방법(how)을 단계별로 지시하고, 선언형 프로그래밍(Declarative Programming)은 원하는 결과(what)만 기술하고 과정은 도구에 맡긴다. 길 안내로 치면 "직진하다 두 번째 신호에서 우회전"이 명령형, "강남역 가 주세요"가 선언형이다.
// 명령형: 반복과 누적을 직접 관리
const evens = []
for (let i = 0; i < nums.length; i++) if (nums[i] % 2 === 0) evens.push(nums[i])
// 선언형: 무엇을 원하는지만
const evens2 = nums.filter(n => n % 2 === 0)- SQL(Structured Query Language), HTML(HyperText Markup Language), CSS(Cascading Style Sheets)가 대표적인 선언형 언어다. 컬렉션을 다룰 때 반복문을 파이프라인으로 바꾸는 것도 같은 방향이다(반복문을 파이프라인으로 바꾸기)
- 함수형 프로그래밍(Functional Programming)은 선언형의 한 갈래로, 부수 효과 없는 순수 함수를 조합해 프로그램을 만든다(부수 효과와 Effect)
React가 선언형인 이유
바닐라 JS(JavaScript)로 카운터를 만들면 버튼을 만들고, 이벤트를 달고, 값이 바뀔 때마다 어느 DOM(Document Object Model)을 어떻게 고칠지 모두 적어야 한다. React에서는 "count가 이 값일 때 화면은 이렇다"만 적으면 무엇을 고칠지는 React가 계산한다(Virtual DOM, 재조정(Reconciliation)). 상태와 UI의 관계가 한곳에 드러나서 예측하기 쉽다. 컬렉션 가상화도 훅으로 "이런 목록을 원한다"고 선언하는 방식이다(리스트 가상화).
다만 포커스 이동, 스크롤, 외부 라이브러리 연동처럼 명령형이 꼭 필요한 곳은 useRef와 Effect를 탈출구로 쓴다(useEffect와 useLayoutEffect).