\(@^0^@)/

[TIL] 제어 컴포넌트(Controlled Components)와 비제어 컴포넌트(Uncontrolled Components)의 특징 본문

TIL

[TIL] 제어 컴포넌트(Controlled Components)와 비제어 컴포넌트(Uncontrolled Components)의 특징

minjuuu 2022. 7. 26. 23:31
728x90

제어 컴포넌트 (Controlled Component)

HTML에서 <input>, <textarea>, <select>와 같은 폼 엘리먼트는 일반적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트합니다.
React에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state 속성에 유지되며 setState()에 의해 업데이트됩니다.

우리는 React state를 “신뢰 가능한 단일 출처 (single source of truth)“로 만들어 두 요소를 결합할 수 있습니다. 그러면 폼을 렌더링 하는 React 컴포넌트는 폼에 발생하는 사용자 입력값을 제어합니다.
이러한 방식으로 React에 의해 값이 제어되는 입력 폼 엘리먼트를 “제어 컴포넌트 (controlled component)“라고 합니다.

예를 들어, 이전 예시가 전송될 때 이름을 기록하길 원한다면 폼을 제어 컴포넌트 (controlled component)로 작성할 수 있습니다.

공식문서에는 클래스형으로 나와있기에, 함수형으로 예시를 들어보자.

import React, { useState } from "react";

const SimpleForm = () => {
	const [nickname, setNickname] = useState("");
	const handleChange = (e) => {
		setNickname(e.target.value);
	};

	const handleSubmit = (e) => {
		e.preventDefault();
		alert(nickname);
	};

	return (
		<form onSubmit={handleSubmit}>
			<label>닉네임 : </label>
			<input type='text' name="nicknmae" value={nickname} onChange={handleChange} />
			<input type='submit' value='제출' />
		</form>
	);
};

export default SimpleForm;

제어 컴포넌트를 활용해서 nickname을 등록하기 위해 useState를 사용하여 nickname의 상태 값을 만들어주고,
onChange로 input에 입력값을 받아서 set에 계속 업데이트해준다.
또한 해당 input의 value값에도 업데이트되는 상태 값을 넣어주고, submit 할 경우에도 상태 값을 넘겨준다.

https://ko.reactjs.org/docs/forms.html

 

폼 – React

A JavaScript library for building user interfaces

ko.reactjs.org


비제어 컴포넌트 (Uncontrolled Component)

대부분 경우에 폼을 구현하는데 제어 컴포넌트를 사용하는 것이 좋다. 제어 컴포넌트에서 폼 데이터는 React 컴포넌트에서 다루어진다. 대안인 비제어 컴포넌트 DOM 자체에서 폼 데이터가 다루어진다.

모든 state 업데이트에 대한 이벤트 핸들러를 작성하는 대신 비제어 컴포넌트를 만들려면 ref를 사용하여 DOM에서 폼 값을 가져올 수 있다.

공식문서에는 클래스형으로 나와있기에, 함수형으로 예시를 들어보자.

const UnControlledForm = () => {
    const inputRef = useRef();

    const handleSubmit = (e) => {
        e.preventDefault();
        alert(inputRef.current.value);
    };

    return (
        <form onSubmit={handleSubmit}>
            <label>닉네임 : </label>
            <input type='text' name='nickname' ref={inputRef} />
            <input type='submit' value='제출' />
        </form>
    );
};

export default UnControlledForm;

비제어 컴포넌트는 DOM에 신뢰 가능한 출처를 유지하므로 비제어 컴포넌트를 사용할 때 React와 non-React 코드를 통합하는 것이 쉬울 수 있다. 빠르고 간편하게 적은 코드를 작성할 수 있지만, 그 외에는 일반적으로 제어된 컴포넌트를 사용해야 한다.


언제 비제어 컴포넌트를 사용해야 할까?

제어된 input은 props를 현재 값으로 받아들이고, 해당 값을 변경하기 위해서 callback을 받는다.
이렇게 접근하는 방법이 더 "react"적인 방법이라고 할 수 있다. (항상 그런 것은 아님)
어느 쪽이든 괜찮지만, 입력값은 state의 어딘가에 있어야 한다.

파일 입력 태그
React에서 <input type="file" /> 은 프로그래밍적으로 값을 설정할 수 없고 사용자만이 값을 설정할 수 있기 때문에 항상 비제어 컴포넌트이다.

 

일반적으로, input을 렌더 하는 컴포넌트(form 컴포넌트)는 state를 아래의 코드와 같이 저장한다.

import React, { useState } from "react";

const SimpleForm = () => {
    const [nickname, setNickname] = useState("");
    const handleChange = (e) => {
        setNickname(e.target.value);
    };

    return (
        <>
            <label>닉네임 : </label>
            <input type='text' name="nicknmae" value={nickname} onChange={handleChange} />
        </>
    );
};

export default SimpleForm;

 

새 문자를 입력할 때마다 handleChange가 호출되어, 입력의 새 값을 가져와 상태로 설정한다.
이러한 흐름 유형은 값을 형식 component로 변경하므로 Form명시적으로 요청할 필요 없이 구성 요소는 항상 입력의 현재 값을 갖는다.
즉, 데이터(상태)와 UI(입력)가 항상 동기화된다. 상태는 입력에 값을 제공하고 입력 Form은 현재 값을 변경하도록 요청함.

이것은 form 컴포넌트가 input의 변경 사항에 즉시 응답할 수 있다는 의미.
ex) 유효성 체크, 모든 필드에 유효한 데이터가 없다면 버튼 비활성화, 신용 카드 번호, 휴대폰 번호와 같은 특정 입력 형식

그러나 이러한 것들이 필요하지 않고 제어되지 않는 것이 더 낫다고 생각한다면 비제어 컴포넌트를 사용하는 것도 괜찮다.
물론 input 이외에도 다른 형식의 요소들이 있다. checkbox, radiobutton, select, textareas
prop를 통해 값을 설정한다면, 제어 컴포넌트가 된다.

각각의 form 요소에 value값을 설정하기 위한 다양한 prop을 갖고 있다. 참고하여 제어 컴포넌트를 활용해보자.

결론

제어 컴포넌트와 비제어 컴포넌트 모두 메리트가 있다. 각자 상황에 맞게 적용하면 그것이 베스트.
UI 피드백 측면에서 양식이 매우 단순하다면 비제어 컴포넌트로 ref를 사용해도 좋음.

무조건적으로 따라야 하는 구분이 아니다. 언제든 비제어 컴포넌트에서 제어 컴포넌트로 마이그레이션 할 수 있다.

https://goshacmd.com/controlled-vs-uncontrolled-inputs-react/

 

Controlled and uncontrolled form inputs in React don't have to be complicated - Gosha Arinich

There are many articles saying you should use setState, and the docs claim refs are bad. So contradictory. How are you supposed to make forms?

goshacmd.com

https://ko.reactjs.org/docs/uncontrolled-components.html

 

비제어 컴포넌트 – React

A JavaScript library for building user interfaces

ko.reactjs.org


[ 출처, 참고  : zerobase frontendSchool React 이론 ]

728x90