HTML의 폼 엘리먼트는 자체가 내부 상태를 가지기에
React의 다른 DOM 엘리먼트와 조금 다르게 동작합니다.
위의 폼은 사용자가 제출하면 새로운 페이지로 이동하는 동작을 수행합니다.
React에서 동일한 동작을 원한다면 그대로 사용해도 괜찮습니다.
하지만 대부분 Javascript 함수로 폼의 제출을 처리하고 사용자가 폼에 입력한 데이터에 접근하도록 하는 것이 편리합니다.
이를 위한 표준 방식이 "제어 컴포넌트(controlled components)"라고 불리는 기술을 이용하는 것입니다.
제어 컴포넌트(Controlled Component)
HTML에서 input, textarea, select와 같은 폼 엘리먼트는
일반적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트합니다.
리액트에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state 속성에 유지되며 setState()에 의해 업데이트 됩니다.
우리는 리액트의 state를 신뢰 가능한 단일 출처(single source of truth)로 만들어 두 요소를 결합할 수 있습니다.
그러면 폼을 렌더링 하는 리액트 컴포넌트는 폼에 발생하는 사용자 입력값을 제어합니다.
이러한 방식으로 React에 의해 값이 제어되는 입력 폼 엘리먼트를 제어 컴포넌트라고 합니다.
예를 들어 이전 예시가 전송될 때 이름을 기록하길 원한다면 폼을 제어 컴포넌트로 작성하면 됩니다.
value 어트리뷰트는 폼 엘리먼트에 설정되므로 표시되는 값은 항상 this.state.value 가 되고
리액트 state는 신뢰 가능한 단일 출처(single source of truth)가 됩니다.
리액트 state를 업데이트하기 위해 모든 키 입력에서 handleChange가 동작하기에
사용자가 입력할 때 보이는 값이 업데이트됩니다.
제어 컴포넌트로 사용하면 모든 state 변화는 연관된 핸들러를 가집니다.
이것을 통해 사용자 입력을 수정하거나 유효성을 검사하는 것이 간단해집니다.
예를 들어, 이름이 모두 대문자로 쓰이게 하고자 한다면 handleChange를 다음과 같이 사용하면 됩니다.
textarea 태그
리액트 textarea는 value 어트리뷰트를 대신 사용합니다.
이렇게 하면 textarea를 사용하는 폼은 한 줄 입력을 사용하는 폼과 비슷하게 작성할 수 있습니다.
this.state.value를 생성자에서 초기화하므로 textarea는 일부 텍스트를 가진채 시작됩니다.
select 태그
HTML에서 select는 드롭 다운 목록을 만듭니다.
selected 옵션이 있으므로 Coconut 옵션이 초기값이 되는 점을 주의해야 합니다.
리액트에서는 최상단 select 태그에 value 어트리뷰트를 사용합니다.
한 곳에서 업데이트만 하면 되기에 제어 컴포넌트에서 사용하기 더 편합니다.
전반적으로 위의 세 개가 다 비슷하게 동작합니다.
모두 제어 컴포넌트를 구현하는데 value 어트리뷰트를 허용합니다.
select 태그에 multiple 옵션을 허용한다면 value 어트리뷰트에 배열을 전달할 수 있습니다.
file input 태그
HTML에서 <input type="file">는 사용자가 하나 이상 파일을 자신의 장치 저장소에서
서버로 업로드하거나 File API를 통해 Javascript로 조작할 수 있습니다.
<input type="file" />
값이 읽기 전용이기에 리액트에서는 비제어 컴포넌트로 사용됩니다.
다중 입력 제어하기
여러 input 엘리먼트를 제어해야 할 때, 각 엘리먼트에 name 어트리뷰트를 추가하고
event.target.name 값을 통해 핸들러가 어떤 작업을 할지 선택할 수 있게 해 줍니다.
주어진 input 태그의 name에 일치하는 state를 업데이트하기 위해
ES6의 computed property name 구문을 사용하고 있습니다.
this.setState({
[name] : value
});
ES5 코드는 다음과 같습니다.
var partialState = {};
partialState [name] = value;
this.setState(partialState);
또한 setState()는 자동적으로 현재 state에 일부 state를 병합하기에
바뀐 부분에 대해서만 호출하면 됩니다.
제어되는 Input Null 값
제어 컴포넌트에 value prop을 지정하면 의도하지 않는 한 사용자가 변경할 수 없습니다.
value를 설정했는데 여전히 수정할 수 있다면 실수로 value를 undefined나 null로 설정했을 가능성이 있습니다.
첫 번째 입력은 잠겨있지만 잠시 후 입력이 가능해집니다.
제어 컴포넌트의 대안
데이터를 변경할 수 있는 모든 방법에 대해 이벤트 핸들러를 작성하고
리액트 컴포넌트를 통해 모든 입력 상태를 연결해야 하기에
때로는 제어 컴포넌트를 사용하는 게 버거울 수 있습니다.
'Today Learning _' 카테고리의 다른 글
Part 12-10. 리액트 살펴보기(합성(Composition) vs 상속(Inheritance)) (2) | 2020.03.24 |
---|---|
Part 12-9. 리액트 살펴보기(state 끌어올리기) (0) | 2020.03.24 |
Part 12-7. 리액트 살펴보기(리스트와 Key) (0) | 2020.03.19 |
Part 12-6. 리액트 살펴보기(조건부 렌더링) (0) | 2020.03.19 |
Part 12-5. 리액트 살펴보기(이벤트 처리하기) (0) | 2020.03.18 |