[React] 제어 컴포넌트와 비제어 컴포넌트

2024. 5. 23. 23:03카테고리 없음

제어 컴포넌트 vs 비제어 컴포넌트


1. Form tag elements

 

input 태그는 전통적인 html태그
자바스크립트를 통해서 동작

input태그는 form태그 엘리먼트의 대표적인 특성 중 하나.

form태그 엘리먼트들은 독특한 특징이 하나 있는데 value attribute를 통해 자체적인 Data를 가짐
value가 사용자 입력값으로 변함. => 사용자가 입력한 값으로 value attribute가 바뀜


 

사용자가 입력한 값에 의해 value atrribute가 바뀜. 

=> 사용자가 입력한 값이 value atrribute에 저장

=> input 태그의 value atrribute는 DOM에 존재
=> Input을 통한 사용자의 입력데이터는 DOM에 저장된다 (논점)


2. 신뢰 가능한 단일 출처


 React에 의해 값이 제어되는 입력 폼 엘리먼트를 "제어 컴포넌트"
=> 사용자가 직접 input 에 값을 조작(DOM이 저장)했는데  React는 그것을 본인이 직접 제어

"신뢰 가능한 단일출처"
=> 하나의 상태를 나타내는 state는 한 곳에만 존재해야 함.

만약 어떤 state가 있는데 여러 컴포넌트에서 사용 돼야 한다면?

Props로 내려주거나, Context api 혹은 Redux 같은 전역 상태 관리 툴을 사용해서 해당 state에 접근
이러한 노력들이 하나의 상태는 한곳에만 존재하고 그것을 사용하고 싶은 사람들은 그곳에 접근하게 함

"하나의 상태는 한 곳에만 존재해야 한다" ?

인풋태그에서 본인이 독자적인 데이터를 가지고 있음 (value atrribute)

신뢰 가능한 단일출처

이유) 입력에있는 값을 가지고 싶으면 해당 element 접근하여 value atrribute통해 가져오면 항상 최신의 입력값을 가져올수 있음(신뢰 가능)

현재까지는 단일 출처 

=> 인풋이 한 곳에만 존재하고 그것에 접근하여 가져오기 때문에 현재는 단일 출처

 


하지만 개발을 하다가 인풋의 value를 코드 어딘가에서 변수로 저장하여 사용하게 되었다고 생각해보면

name이라는 변수가 있고, 인풋에 값이 입력될때마다 인풋 value가 변하게 됨

=> 원래 가지고 있는 value가 하나 있고, 자바스크립트 코드 상에 존재하는 name 변수가 하나 더 있음

처음에는 신뢰 가능한 단일 출처 였으나 신뢰하기 힘든 2개의 출처가 됨

3. 제어 컴포넌트 vs 비제어 컴포넌트


협업을 하게 되었을때는 최신화된 값인지 정확한 일치값인지 확신하기 어렵기 때문에 그것을 보완할수 있는것이 react 
React가 2개로 나뉘어진 값을 늘 최신의 값으로 일치함을 보장 가능 => 제어 컴포넌트


제어 컴포넌트의 대표적인 코드로 name이라는 react 의 state가 있음
이 state는 input의 value props을 통해 넘겨지고,
이 input의 값이 바뀔때마다 사용자가 값을 입력할때마다 입력된 값이 name에 set 

set된 name은 span 태그에 렌더링

변경된 input value가 매번 state로 push

=> input value와 react의 value는 항상 최신의 값으로 일치함이 보장
=> 매 입력마다 state가 변경되므로 re-rendering 발생 

비제어 컴포넌트


공식문서에서는 제어 컴포넌트에서 폼 데이터는 React 컴포넌트에서 다루어짐 (이전 내용)

비제어 컴포넌트는 DOM자체에서 데이터가 다루어짐
비제어 컴포넌트는 DOM에 신뢰가능한 출처를 유지 

사실은 비제어 컴포넌트는 전통적인 html form 태그

일반적인 방식과 똑같은 방식으로 동작

React에서는 차이점이 있음


비제어 컴포넌트 코드

리턴되는 엘리먼트를 보면 ref 인데 제어컴포넌트에서는 onchange가 있었는데 inputRef 가 있음
ref는 비제어 컴포넌트를 사용할때 굉장히 중요한 내용

ref는 React에서 값을 담는 상자로 컴포넌트 마운트 시점에 current에 elemnet대입이 되고 컴포넌트가 리 렌더링 돼도

 ref는 값을 유지(컴포넌트의 전역변수 같은 개념)

사용자가 input에 값을 입력하고 submit을 하게되면 handleSubmit이 호출
handlesubmit은 inputRef의 current에 담긴 value를 콘솔로그 


React가 값을 관여하는 바가 전혀 없음
사용자 입력으로 DOM이 직접 조작되고 해당값이 필요할때 ref를 통해 input의 value를 pull을 하고있음. (가져옴)
비제어 컴포넌트로 input의 value를 사용하게 되면 react가 데이터가 항상 일치함을 보장할수 없음
또 state로 관리 하지 않기 때문에 re-rendering이 발생하지 않음

[정리]

제어 컴포넌트는 리액트가 값을 관리하고 사용자 입력이 항상 state로 push되기 때문에 최신화 값이 유지(값이 항상 일치)
입력마다 Re-rendering이 발생 

비제어 컴포넌트는 DOM이 값을 저장하고, 입력 값이 필요할때 element에서 직접 접근하여 가져와야 함
=> react가 관여하는 바가 없기 때문에 값이 항상 일치함을 보장할 수 없음
=> state를 사용하지 않기 때문에 Re-rendering이 발생하지 않음

 제어컴포넌트와 비제어컴포넌트의 사용 예

제어 컴포넌트는 항상 최신의 값을 보장하고 매 입력마다 re-rendering이 발생 
그래서 매 입력마다 입력 값으로 어떤 동작을 해야하는 경우에 사용하면 좋음

입력값을 다른곳에 rendering 해야 하는 경우, 사용자 입력에 대한 즉각적인 확인 및 검증을 해서 피드백을 해야 하는 경우

비제어 컴포넌트는 원하는 시점에 값을 가져온다는 특징이 있음 

매입력마다 re-rendering이 발생하지 않는다는 특징도 있음
따라서 매 입력마다 최신의 값이 꼭 필요하지 않는 경우

매 렌더링마다 복잡한 연산이 발생하는 경우에는 비제어컴포넌트를 사용하는것을 고려해보면 좋음

 

 



[정리]

1. Form tag elemnets는 DOM에 사용자 입력을 저장
2. input의 value를 다른곳에서 저장하여 사용하면 값이 일치함을 신뢰하기 어려움
3. 제어 컴포넌트는 value와 staste를 동기화 함으로써 항상 최신의 값을 보장
4. 제어 컴포넌트와 비제어 컴포넌트는 각각 장단점이 있으니, 사용처에 맞게 선택하면 됨