Form태그와 제어 / 비제어 컴포넌트

yoon Y·2022년 6월 18일
0

리액트 학습

목록 보기
3/5

제어 컴포넌트

  • HTML 폼 엘리먼트는 폼 엘리먼트 자체가 내부 상태를 가지기 때문에, React의 다른 DOM 엘리먼트와 다르게 동작한다.
  • HTML에서 <input> <textarea> <select>와 같은 폼 엘리먼트는 일반적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트한다.
  • 일반적으로 리액트는 React에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state 속성에 유지되며 setState()에 의해 업데이트된다.
  • 핸들러를 통해 입력 값을 상태로 업데이트해주는 과정이 필요하다.

⇒ 리액트에서는 기본적으로 엘리먼트의 상태를 state로 관리하는데, <input> <textarea> <select> 태그들은 사용자 입력으로 상태를 가진다.
⇒ 이 차이를 통일 시키기 위해 React 컴포넌트는 폼에 발생하는 사용자 입력값을 제어한다.
⇒ 이처럼 React에 의해 값이 제어되는 입력 폼 엘리먼트를 “제어 컴포넌트"라고 함.


제어 컴포넌트로 사용하는 법

input, textArea 태그

  • value에 state를 적용해줌.
  • 사용자 입력은 받지만 그 입력으로 input값이 렌더링되게 하지 않고, Change핸들러 함수에서 입력받은 값으로 상태를 업데이트(+렌더링) 시켜준다.
  • 다른 UI 엘리먼트에 상태로 저장된 input의 값을 전달하거나, Change핸들러 함수 내에서 값을 조작(포맷팅)할 수 있다.
  • textArea는 원래 자식이 값이 되지만 리액트에서는 value속성으로 대체한다.
<input type="text" value={this.state.value} onChange={this.handleChange} />

select 태그

  • React에서는 각 option에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를 사용할 수 있다.


비제어 컴포넌트

  • 대부분 경우에 폼을 구현하는데 제어 컴포넌트를 사용하는 것이 좋지만 비제어 컴포넌트를 사용하는게 좋은 경우도 있다.
  • 제어 컴포넌트에서 폼 데이터React 컴포넌트에서 다루어진다.
  • 비제어 컴포넌트는 DOM 자체에서 폼 데이터가 다루어진다.
  • 비제어 컴포넌트를 만들려면 ref를 사용 하여 DOM에서 폼 값을 가져올 수 있다.
// 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/

profile
#프론트엔드

0개의 댓글