팀원 중 한명이 controlled컴포넌트라는 단어를 언급한 적이 있었는데 해당 단어에 대해서 제대로 알지 못해서 이번기회에 공부해보았다.
먼저 Form에 대해서 간략한 설명을 하겠다. Form에 대해서 설명한 이유는 제어,비제어 컴포넌트에 관한 설명을 하기 위해서 필요한 배경지식이기 때문이다.
Form이란? 사용자에게 정보를 입력받아 전송하는 태그를 의미한다
Form Tag Elements란 Form태그를 구성하는 요소들을 의미하며 대표적으로 input,textarea,select 가 있다.
<form>
<input id="name"/>
<textarea id="info"/>
<select id="job"/>
...
</form>
대표적으로 input을 예시로 들어서 설명하겠다
자바스크립트만을 이용해서 input태그에 사용자가 입력한 데이터를 어떻게 확인 할 수 있을까?
form태그에 submit이벤트를 연결하여 submit이벤트가 실행되었을때 직접 요소에 접근해서 value값에 도달 할 수 있다.
const onSubmit=(e)=>{
e.preventDefault()
console.log(e.target.elements["name"].value)
console.log(document.getElementById("name").value)
}
그렇다 submit과 같은 이벤트가 실행되었을때만 해당 value를 알 수 있다.
따라서 사용자가 입력하고 있는 중간에는 유효성 검사를 진행할 수 없다는 특징이 있다.
제어컴포넌트는 각 태그에 대한 value값을 state로 접근하고 값을 변경시킨다.
const ControlledComponent=()=>{
const [name,setName]=useState("")
const onChange=(e)=>{
setName(e.target.value);
}
return <div>
<input value={name} onChange={onChange} />
</div>
}
useState를 이용하게 된다면 state값이 변경될때마다 리렌더링이 발생되고 실시간으로 유효성체크를 할수 있다.
이런식으로 state에 의해서 value값이 결정되는 것이 신뢰가능한 단일출처(Single Source of Truth:SSOT)라고 한다
특정 값을 한곳에서 관리할 수 있도록 하는 것이다.
아래와 같이 name이라는 변수에 요소의 값을 넣고 name변수를 다른곳에서 변수값을 변경하게되면 더이상 value attribute와 variables값이 동일하지 않게 된다.
let name=""
const onSubmit=(e)=>{
e.preventDefault()
name=e.target.elements["name"].value
}
이러한 상황을 해결하기 위해 react에서는 제어컴포넌트 형식으로 Form의 데이터값을 react가 제어를 함으로써 SSOT를 유지할 수 있도록 한것이다.
비제어컴포넌트는 각 태그에 대한 value값을 useRef로 접근한다
처음 설명한 javascript만을 이용해서 요소의 값에 접근하는 방식과 유사하다.
ref로 input을 연결하고 해당 ref로 요소에 접근해서 value값 알 수 있다.
const UnControlledComponent=()=>{
const name=useRef("")
const onSubmit=()=>{
console.log(name.current.value)
}
return <div onClick={onSubmit}>
<input ref={name} />
</div>
}
input에 사용자 입력값을 받는다고 해서 리렌더링은 발생되지 않으며 실시간으로 유효성 체크를 할 수 없다.
제어컴포넌트
비제어 컴포넌트
React-hook-form
제어,비제어 컴포넌트의 장점들을 최대한 활용시킨 라이브러리로 form관련 라이브러리로 많이 사용하고 있다.
기본적으로 비제어 컴포넌트 형식으로 활용이 되면서 특정 요소에 대해서는 구독이라는 기능을 이용하여 제어컴포넌트 형식으로 사용할 수 있는 라이브러리이다.
https://www.freecodecamp.org/news/what-are-controlled-and-uncontrolled-components-in-react/
https://www.youtube.com/watch?v=PBgQKK6nelo