<input>
<textarea>
<select>
와 같은 폼 엘리먼트는 일반적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트한다.⇒ 리액트에서는 기본적으로 엘리먼트의 상태를 state로 관리하는데,
<input>
<textarea>
<select>
태그들은 사용자 입력으로 상태를 가진다.
⇒ 이 차이를 통일 시키기 위해 React 컴포넌트는 폼에 발생하는 사용자 입력값을 제어한다.
⇒ 이처럼 React에 의해 값이 제어되는 입력 폼 엘리먼트를 “제어 컴포넌트"라고 함.
input, textArea 태그
<input type="text" value={this.state.value} onChange={this.handleChange} />
select 태그
selected
어트리뷰트를 사용하는 대신 최상단 select
태그에 value
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
// multiple 옵션을 허용한다면 `value` 어트리뷰트에 배열을 전달할 수 있습니다.
<select multiple={true} value={['B', 'C']}>
다중 입력 제어하기
여러 input
엘리먼트를 제어해야할 때, 각 엘리먼트에 name
어트리뷰트를 추가하고 event.target.name
값을 통해 핸들러가 어떤 작업을 할 지 선택할 수 있게 해준다.
setState()
는 자동적으로 현재 state에 일부 state를 병합하기 때문에 바뀐 부분에 대해서만 호출하면 된다.
this.setState({
[name]: value
});
사용자 입력 값은 change이벤트 핸들러로 전달만되고, 상태로 업데이트 되어 상태가 렌더링되는 것이다.
⇒ 하지만 제어 컴포넌트를 사용하면 사용자가 입력할 때마다 상태가 업데이트되므로 많은 수의 리렌더링이 발생할 수 있다.
대안으로 비제어 컴포넌트+useRef를 사용할 수 있다.
// value대신 ref를 등록해준다.
// 초기값이 필요한 경우에는 defaultValue속성을 사용할 수 있다. - <select>와 <textarea>포함
// checkbox, radio type은 defaultChecked를 사용한다.
<input type="text" ref={this.input} defaultValue="Bob"/>
// ref.currnet.value에 각 엘리먼트의 입력값을 저장하다가 필요할 시 값을 가져와서 사용한다.
handleSubmit(event) {
alert('A name was submitted: ' + this.input.current.value);
event.preventDefault();
}
제어된 양식 필드와 제어되지 않은 양식 필드 모두 장점이 있다. 특정 상황을 평가하고 접근 방식을 선택하십시오 .
비제어로 사용하면 좋은 경우
→ 값이 입력될 때마다 화면갱신이 될 필요 없고 필요할 때만(주로 제출)값을 가져와야 하는 경우
(ex-로그인, 회원가입 폼)
제어로 사용하면 좋은 경우
→ 값이 입력될 때마다 특정 로직을 실행해야하거나 다른 엘리먼트에 영향을 끼치는 경우
(ex- 텍스트 자동 저장, 가격 포맷팅)
비제어에서 제어로 변경하는 것은 어렵지 않기 때문에 언제든지 제어된 입력으로 마이그레이션할 수 있다.
참고 링크
https://ko.reactjs.org/docs/uncontrolled-components.html
https://goshacmd.com/controlled-vs-uncontrolled-inputs-react/