React가 구식이라는 주장에 대해, 2024년 이후에도 여전히 가치 있는 React의 핵심 패러다임(단방향 데이터 흐름, 불변 상태, JSX/함수 호출 기반 렌더링)을 왜 장점으로 보는지 설명한다.
React가 구식이라는 글을 최근에 읽었다. 나는 오래전부터 React를 좋아해 왔다(2015년에 내가 했던 로컬 밋업 발표도 있다?! https://ejosh.co/de/2015/08/my-talk-on-react/ ). 이 글은 다른 글에 대한 반박으로 올리는 것은 아니다. 2024년 그리고 그 이후에도 여전히 가치 있는 React의 핵심 패러다임을 비춰 보고자 한다.
내 글의 핵심으로 들어가기 전에, 같은 저자가 쓴 Tailwind, 음악, Mario Kart에 관한 훌륭한 글(https://joshcollinsworth.com/blog/tailwind-is-smart-steering)이 있다. 관련 부분을 발췌했지만, 전체 글을 읽는 것을 추천한다:
우리는 Bon Jovi와 Sufjan Stevens를 마음껏 해부할 수도 있었을 것이다. 하지만 그건 중요하지 않았다. 우리의 의견 차이는 결국 둘 중 누구도 재생 버튼을 누르기 전부터 시작된 것이었기 때문이다.
우리는 무엇이 기능(feature)이고 무엇이 버그(bug)인지에 대해 애초에 합의한 적이 없었다.
마찬가지로, Tailwind 논쟁에서 서로 반대편에 있는 대부분의 사람들은 사실 Tailwind 자체에 대해서는 완전히 동의하고 있다고 나는 의심한다. 나는 우리의 분열이 atomic CSS나 유틸리티 클래스에 있는 게 아니라고 생각한다. 갈등은 우리가 도구를 고르기 훨씬 전부터 내렸던 가치 판단에서 나온다. 한쪽이 판매 포인트로 보는 것을 다른 쪽은 결함으로 본다.
Tailwind는 훌륭하다.
Tailwind는 또한 나쁜 아이디어다.
이 관점은 정말 좋다. 사람마다 도구와 그 도구가 내린 결정들을 다르게 평가한다. 나는 이 정서에 전적으로 동의한다.
사람들이 도구를 다르게 평가한다는 이 맥락에서 원문 글을 보자: https://joshcollinsworth.com/blog/antiquated-react (즉, React 때문에 잊어버린(혹은 애초에 몰랐던) 것들). 이 글도 전체를 읽는 것을 추천한다.
저자는 React가 왜 구식인지, 그리고 왜 다른 기술을 선택해야 하는지에 대해 많은 요점을 제시한다. 아쉽게도 React는 Tailwind와 같은 존중을 받지 못한다. 저자는 누군가가 왜 그것을 판매 포인트로 볼 수 있는지 살펴볼 시간을 들이지 않은 채 React에서 결함만 본다. React의 가장 가치 있는 기능들이 그저 결함으로 분류되고, React 말고 다른 것을 써야 한다는 결론으로 이어진다. 나 말고 다른 Josh, 그러니까 Josh 본인이 다음 인용문이 이 글을 쓰게 만든 계기였다고 인정한다.
오늘 누군가 IE 지원이 필요 없는 새 앱에서 React를 써야 할 이유가 있냐고 물었다.
나는 단 하나의 이유도 떠올릴 수 없었다…
React가 얼마나 구식인지 놀랍다.
덧붙이자면, “대체 누가 React를 선택하겠어?”라는 핵심 아이디어를 가진 글이 점점 더 많아지는 것을 보았다. 그리고 이 글과 마찬가지로, 사실은 React의 가장 가치 있는 기능인 것들을 결함으로 본다.
원문 글에서 언급된 React의 두 가지 큰 결함/기능을 다루겠다.
React는 단방향 데이터 바인딩을 유명하게도 권장한다. 여기서 말하는 것은 React에서 useState나 Redux 같은 것을 사용해 상태를 다루는 관용적(idiomatic) 방식이다. 이 둘의 공통점은 상태가 불변(문자 그대로든 사실상 그러하든)이며, 상태 변화가 상태를 갱신하는 명시적 함수(액션 또는 setState)를 통해 일어난다는 점이다.
원문 글에서는 양방향 데이터 바인딩이 단방향 데이터 바인딩을 선호하게 되면서 잊힌 것으로 묘사된다. https://joshcollinsworth.com/blog/antiquated-react#two-way-data-binding-isnt-hard-and-it-isnt-a-bad-idea
해당 섹션에 대한 답으로, React에서 폼이 엉망진창이었던(즉, 별로였던) 과거가 있었다는 점은 인정하겠다. 다만 지금은 React로 개발하는 대부분이 React Hook Form을 쓰거나, 그냥 폼 onSubmit 이벤트에서 데이터를 가져오는 방식일 거라고 본다.
하지만 양방향 데이터 바인딩의 힘을 보여주는 다른 예시는 없다. 폼은 중요하고 웹의 핵심 부분이다. 그러나 보통 웹 애플리케이션에서 추적되는 상태 중 가장 작은 부분이다. 만약 폼이 애플리케이션에서 가장 큰 상태 객체라면, 사실 React가 필요 없다. 어떤 JavaScript 라이브러리도 마찬가지다. 그저 최신 HTML 입력 검증과 폼이면 된다.
나는 양방향 데이터 바인딩을 하는 것은 무엇이든 결함이라고 본다. 그것은 어떤 프로젝트에서든 가장 큰 숨은 문제 두 가지인 복잡성과 가변성을 도입한다. 이 둘은 서로 연관되어 있다. 애플리케이션을 더 만들기 시작하면, 언제든 어떤 방식으로든 바뀔 수 있는 변수가 더 많아진다. 그러면 머릿속에 들어맞는 애플리케이션 모델을 유지하기가 매우 어려워진다1.
불변이며 각 상태 전이를 위한 명시적 함수가 있는 단방향 데이터 바인딩은 중요한 기능이다. 이는 React의 가장 강력한 패러다임 중 하나다. 너무 단순해 보일 수 있지만, 과소평가하지 말라.
양방향 데이터 바인딩은 훌륭하다.
양방향 데이터 바인딩은 또한 나쁜 아이디어다.
다음 인용문이 내가 여기서 쓴 모든 것의 촉매였다. 이것은 나에게 가치 불일치가 있다는 것을 분명히 보여 주었다.
하지만 Vue는 JSX보다는 기본 HTML에 더 가까운 템플레이팅 언어를 사용하기 때문에, 템플릿 파일에서 조건문과 루프를 훨씬 쉽게 작성할 수 있다.
map과 삼항 연산자 같은 우회책(workarounds)에 의존할 필요 없이.
삼항 연산자와 map은 우회책이 아니다. 이것들은 UI를 구성하기 위한 강력하고 표현력 있는 도구다. 솔직히 말해, 여기서는 나 자신을 표현할 최선의 단어를 찾기가 어렵다. HTML 템플릿 파일에서 조건과 반복을 하는 것이야말로 우회책이고, 할 수 있는 일을 제한한다는 점이 내게는 자명하기 때문이다.
JSX에 대한 내 기본 주장을 잘 요약한 Reddit comment (작성자 __versus)을 소개한다.
JSX는 정말 좋은 혁신인데, JavaScript에 대해 알고 있는 모든 것을 가져와서 그 안에 HTML을 끼워 넣기 때문이다. 그리고 놀랍게도 이는 JS 문법 안에서 완전히 표현될 수 있다. 이는 다른 라이브러리들이 같은 목표에 도달하기 위해 택하는 경로와 대조적이다. 그들은 대신 HTML 위에 커스텀 DSL을 덧씌우는데, 때때로 JS처럼 보이긴 하지만 HTML 문법의 제약 때문에 실제 JS만큼 표현적이거나 완전할 수는 전혀 없다.
요약하면 React가 훌륭한 이유는 언어 안에서 표현력을 희생하는 타협이 거의 없고, 컴포넌트를 렌더링하기 위해 일반 JS의 모든 기능을 사용할 수 있게 해 주기 때문이다. 반면 다른 템플릿 언어들은 HTML의 범위 안에 맞추기 위해 표현력을 희생해야 한다.
JSX는 HTML이 아니며, HTML이 되려는 것도 아니다. 그것을 HTML처럼 취급하면 만들 수 있는 것이 제한된다. JSX는 그저 함수 호출이다. 그게 전부다. HTML의 표현력은 JavaScript에서 함수 호출을 하는 표현력에 비하면 극히 작다.
Hacker News의 dmitriid는 이 아이디어를 더 확장한다. 다음 섹션은 인용이지만, 여기에서의 마크다운 렌더링을 활용하기 위해 글의 일부로 렌더링하겠다.
그렇다. 하지만 당신이 보지 못하는 한 가지는, 이것이 직접 함수 호출로 컴파일된다는 점이다.
<Tag a="b" x={y+z}>{valid JS expression}</Tag>
는
React.createElement(Tag, { a: "b", x: y + z }, [<valid JS expression>])
이다.
이는 다음을 의미한다:
React 렌더링은 함수 호출과 표현식의 더미일 뿐이다. 이것은 강력하다. 과소평가하지 말라. 이는 모든 함수형 프로그래밍 언어가 뒷받침하는 React의 핵심 가치 제안이다.
HTML 템플레이팅은 훌륭하다.
HTML 템플레이팅은 또한 나쁜 아이디어다.
이 글의 주제로 다시 돌아오면, 우리는 무엇이 기능이고 무엇이 버그인지에 대해 결코 합의하지 못할 것이다. 사실 우리는 Vue, Svelte, Solid, 혹은 다른 어떤 프론트엔드 프레임워크에 대해서도 완전히 동의하고 있다. 당신은 기능을 보고 나는 결함을 본다2.
본질적으로 이 글은 다음과 같은 이론적 대화로 요약할 수 있다.
React는 구식이다. 불변 데이터를 권장하고, HTML과 닮지 않은 합성된 함수 호출과 표현식으로 렌더링하도록 강제한다.
뭐라고? 그게 바로 내가 찾는 것이다. 프론트엔드에 함수형 패러다임을 적용할 수 있다.
나는 그건 중요하지 않다. 양방향 데이터 바인딩을 하고 HTML 템플릿 파일을 쓰는 무언가를 원한다.
뭐라고? 그게 바로 내가 피하려는 것이다.
우리는 무엇이 기능이고 무엇이 버그인지에 대해 애초에 합의한 적이 없었다.
댓글에서 반박을 쓰는 모든 분들은, Josh Collingsworth의 첫 번째 글을 읽어 달라. Vue(또는 다른 어떤 프론트엔드 프레임워크)에는 아무 문제도 없다. Vue는 구식이 아니다. 내가 “X는 also a bad idea”라는 수사적 장치를 쓰긴 했고 그 문장들을 철회하진 않지만, 그것을 당신의 인격에 대한 공격으로 받아들이지 말아 달라. Vue에는 가치가 있고, 사람들이 React보다 Vue를 선택하는 이유도 이해한다. 다만 그 반대가 항상 성립한다고 느끼지는 않았다. 이 글은 사람들이 가치 있게 여기는 React의 기능과, 2024년에도 많은 기업이 React를 선택하는 이유를 강조하기 위한 것이다.