Skip to content

Instantly share code, notes, and snippets.

@b1u3b3rr7
Created April 29, 2021 00:26
Show Gist options
  • Save b1u3b3rr7/99b53cf910590476d1942e253cc15e32 to your computer and use it in GitHub Desktop.
Save b1u3b3rr7/99b53cf910590476d1942e253cc15e32 to your computer and use it in GitHub Desktop.

개요

리액트는 <input>, <textarea>, <select>와 같이 입력받을 수 있는 HTML 폼 요소들을 제어 컴포넌트와 비제어 컴포넌트 두 가지의 개념으로 구분하고 있다.

이 글에서는 제어, 비제어 컴포넌트가 무엇인 지 소개하고 상황에 따라 어떻게 사용해야 적절한 지 소개하며 글을 마친다.

제어 컴포넌트와 비제어 컴포넌트

제어 컴포넌트란?

리액트에서 사용자의 입력을 받고자 해봤다면 아래와 같은 코드를 보고 다음과 같이 생각할 수 있을 것이다.

<input type='number' value={count} onChange={handleChange}>

“이 input 요소의 값은 count일 것이고, 변경이 발생할 때마다 handleChange가 호출되겠구나.”

만약 valueonChange 속성이 없다면 당연히 위와 같은 생각을 할 수 없을 뿐더러 이후 어떠한 값이 될 지 알 수 없다.

또한 사용자가 값을 바꿀 경우 호출되는 이벤트 핸들러 함수 handleChange에서 count에 대한 작업을 해줘야만 값이 변경되므로 count에 대한 작업을 하지 않을 경우에는 입력 폼 요소의 값이 그대로 유지된다는 것을 확신할 수 있다.

이 상황은 마치 입력 폼 요소가 이벤트 핸들러 외에 다른 누군가에 의해 변경될 수 없도록 제어하고 있는 것 같다.

이렇게 입력 폼 요소의 value 속성을 지정하여 값을 제어할 수 있는 컴포넌트를 제어 컴포넌트라고 한다.

비제어 컴포넌트란?

위 제어 컴포넌트의 개념과 반대로 생각하면 쉽다. 입력 폼 요소의 value 속성을 제어하지 않는 것이다.

이러한 경우 별도의 value 속성을 지정해주지 않았으므로 화면에는 DOM에 저장된 데이터 값이 나타내진다

자바스크립트에서 document.getElementById('id').value를 통해 볼 수 있는 그 값이다.

value 속성을 제어하진 않더라도 기본값을 지정해주고 싶은 경우에는 리액트에서 제공하고 있는 defaultValue, defaultChecked 속성을 통해 해결할 수 있으며 default… 속성은 이후 값이 바뀌더라도 화면에는 반영되지 않는다.

둘 중 어느 것을 사용하도록 해야하는가?

당연한 답변이겠지만 제어 컴포넌트를 사용하도록 해야하며 리액트 공식 문서에서도 다음과 같이 말하고 있다.

“대부분 경우에 폼을 구현하는데 제어 컴포넌트를 사용하는 것이 좋습니다.”

이 말은 단순히 값을 제어하고 사용할 수 있도록 하기 위함을 넘어서 리액트의 핵심 개념이 담겨져 있다.

리액트의 핵심 원칙 중 하나는 단일 진실 공급원이며 모든 데이터 요소를 한 곳에서만 제어하도록 하는 설계이다.

이 원칙은 리액트 공식 문서 중 State 끌어올리기에서 재차 강조되고 있는 원칙이며 읽어볼 것을 추천한다.

완전한 해결책

리액트 공식 문서에서는 유효성 검사, 방문한 필드 추적 및 폼 제출 처리와 같은 완벽한 해결을 원한다면 Formik이 대중적인 선택 중 하나라고 소개하고 있다.

참고

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment