React 잼민이들아, 왠만하면 비제어 컴포넌트 써라.

Composite·2024년 2월 25일
3
post-thumbnail

당장 Velog에 검색해 보니까 귀엽게들 리액트의 제어 컴포넌트와 비제어 컴포넌트 구분하는 노트들 거의 하나쯤은 장만하고 시작하네.
아주 보기좋다. 흐뭇할 지경이야.

그러나, 리액트에서 양식을 관리할 때, 왠만하면 비제어 컴포넌트로 가려고 하는 습관을 들이도록 하자.
리액트의 제어 컴포넌트는, 상태 관리의 그저 슈가러시일 뿐이다. 단 거 한꺼번에 많이 먹으면 혈당쇼크 오잖아.
즉, 니 몸이 혈당을 버티려고 인슐린 생성하고 별 지랄 하다가 못버티면 당뇨병에 뭐 몸 씹창되듯이,
상태관리 편하다고 제어 컴포넌트를 무작정 쓰다간 함수 갈아엎는 빈도가 많아지고, 흔들리는 너의 컴포넌트가 기다릴 것이다.

왜?

내가 리액트 글을 쓰면서 항상 강조하는 게 있다.

상태가 변하면, 컴포넌트 함수 본문이 갈아엎어진다.

기본 중의 기본이다. constlet 변수처럼 변하는 마법이 리액트에서는 가능한 이유가 이런 기본적인 매커니즘 때문이다.

그리고, 함수 본문 갈아엎어지면, 렌더링 다시 하는 것도 알고 있을 것이다.
즉, 이런 기본적인 제어 컴포넌트는,

<input type="text" value={state} onChange={e => setState(e.currentTarget.value)} />

네가 저 입력 양식에 뭔가를 입력할때마다 재렌더링된다는 것이다. 왜냐면, onChage 함수가 controlled를 위해 태어난 일반적인 HTML input 태그의 onchange 하고 하등 상관없는 이벤트로 설계했기 때문이다.
그래서, 리액트 하다가 쌩 HTML 작성하는데 onchange 함수 만들었는데, 리액트였던 것 처럼 네가 양식에 입력할 때마다 호출하는 게 아닌, 양식의 값을 바꾸고 포커스를 옮겨야 발동하는 원래 특성에 당황하는 프론드엔드 잼민이들이 있더라.

만약 회원가입 양식을 만든다고 치자. 저런 양식 1~2개 아니잖아. 못해도 3개일 수 있고, 더 많으면 많았지 적을 수가 없잖아.
그걸 일일이 제어 컴포넌트로 만들면... 으휴... 니 컴포넌트가 쌈바춤 추는 모습이 여기까지 보인다.

그래서?

그래서 리액트의 패러다임을 지키면서 렌더링 최적화된 양식 컴포넌트 라이브러리인 React Hook Form 이 인기를 얻는 것이다.
아마 리액트 개발자라면 많이들 쓸 것이다.

근데 난 그 라이브러리 안쓴다. 전에 땔감특집 글에 고객 남품한 리액트 사이트 내 컴포넌트에 양식들은 왠만하면 value 속성과 onChange 속성을 안 쓴다.
애초에 얘네들 상태가 바뀌어야할 명분도 없고, 상태 전환은 그저 양식을 제출할 때만 필요하기 때문이다.

그렇다. 렌더링 전략 수립은 리액트 개발자의 기본 자질이다. 잼민이와 으른이의 차이점이란 것이다.
내가 사실 리액트 18부터 시작했는데, 클래스 컴포넌트는 알고 있지만 혐오하기 때문에 일부러 안쓴 것 뿐이고.
자바충이 혀가 길게 보일 수 있겠지만 자바스크립트에게까지 자바의 패러다임을 주기는 싫은 게 내 철학인지라.

그런데?

그래 맞다. 제어 컴포넌트가 정말 필요한 곳이 있다.
가장 대표적인 예시를 찾는다면, 아무래도 자동완성일 것이다.
물론 HTML 자체에 <datalist> 태그로 자동완성을 쉽게 만들 수는 있지만,
구글처럼 입력한 부분만 강조하거나 그런 예쁜 기능은 기본 HTML로는 불가능하기 때문에 결국 직접 만들거나 구하거나 하겠지.

하지만, onChange 이벤트에다가 axiosfetch 써서 불러올 때... 느낌이 쎄하다면 당신은 프론트엔드 개발자의 자질이 있다.
그렇다. 호출 빈도가 많을 수록 백엔드 개발자와 모니터링하던 인프라 엔지니어가 너에게

맘마미야

이지랄할 것이다.

뭐 길게 말할 것도 없이 debounce 에 대해 알면 해결은 끝난다. 따라서 길게 말하기엔 주제에 벗어나기 때문에 여기까지.
모르면 검색해봐. 요즘 ChatGPT에게 대충 물어봐도 대답 잘만 해주니까 얼마나 좋은 시대에 살고있냐.

어쩌라고?

결론부터 말하자면, 양식 컴포넌트는 앵간하면 비제어 컴포넌트를 작성하고, 필요한 곳에만 제어 컴포넌트 방식으로 작성하라는 게 내가 하고싶은 말이다.
이유는, 제어 컴포넌트는 양식과 상태 연계가 매우 편하지만, 입력할 때마다 상태 바뀌고 함수 갈아엎고 그런 만큼 렌더링 되는 현상은 준비되지 않으면 엉금엉금 기어가는 네 컴포넌트를 발견할 수 있다 이런얘기다.
하지만, 제어 컴포넌트가 쓸모없는 것은 절대 아니다. 자동완성처럼 어느정도의 빈도를 가지고 필요한 만큼 렌더링을 통해 사용자에게 좋은 경험을 선사해줄 수 있다.

공식에서는 당연히 리액트 패러다임 유지를 위해 제어 컴포넌트를 추천한다고 했었다. 물론 최신 문서에는 추천이고 뭐고 없긴 하지만.

또한가지, 아토믹 디자인을 쓰게 만드는 원흉이 이놈이다. 아토믹 디자인은 검색해보면 안다. 최소 단위의 컴포넌트를 만들어 필요한 만큼만 존나게 쪼개고 그걸 모두 다 조각조각 합쳐서 하나의 페이지를 만드는 방식이다. 그렇다고 아토믹 디자인이 반드시 좋은 것만은 아니다. 자식에 자식에 자식에... 정보 전달 하려면 양자택일 해야 한다. Prop drilling 하든가, <Context> 쓰든가.

그리고, 리액트가 어려운 이유는 멀리갈 것도 없다. 쌩 HTML 하다가 리액트를 하면, 오히려 리액트 네이티브가 뭔가 핏이 좋다.
뭔가 RIA 플랫폼 느낌도 난다. Vue나 다른 프론트엔드와는 정말 이질적이기도 하다. 하지만,

서버 컴포넌트와 차기 훅 시스템이 깡패다. 서버 컴포넌트에 대해 불만 가진 사람들 보면 ASP,JSP,PHP 같은 스파게티 코드를 생각하는 사람들이 꽤 있는데, 쓰다보면 그깟것들과는 수준이 다르다.

내가 리액트 쓰는 이유 알지? 서버 컴포넌트. 크으...

끗.

마지막으로, 여태까지 쓴 똥같은 글은 다른 글도 그렇지만, 그저 내 개인적 견해를 싸질러 놓은 것으로, 제발 좀 그대로 따라하지 말고 본인이 직접 이게 맞는지 판단하고 쓰기 바란다. 물론 내가 객관적으로 틀린 말은 쓴게 아니고, 그저 주관적인 경험에 입각하여 쓰고 뭔가 강요스럽게 작성하는 게 내 취미이기도 하고... 어쨌든, 다른 시니어 개발자나 엔지니어 입장과 사뭇 다른 뉘앙스가 많은 게 내 글이긴 하다. 따라서, 무작정 내가 하라는 대로 하지 말고, 지금 내가 이렇게 오바를 떨고 있으니, 다음에 리액트로 <input> 태그 작성할 때 신중히 생각하고 컴포넌트 잘 짜라는 뜻으로 이해하주길 바랬으면 좋겠지만 그렇게 이해한 사람은 아마 없을 것이다. 그게 내 의도였으니.

진짜끗.

profile
지옥에서 온 개발자

0개의 댓글