Form
= 양식

보통은 회원가입을 하거나 로그인을 할 때 위와 같이 텍스트를 입력하는 양식을 많이 볼 수 있는데 텍스트 입력뿐만 아니라 체크박스나 셀렉트 등 사용자가 무언가 선택을 해야 하는 것 모두를 폼이라고 생각하면 됩니다.
폼이란?
사용자로부터 입력을 받기 위해 사용하는 것

사용자가 입력한 값에 접근하고 제어할 수 있도록 하는 제어 컴포넌트(Controlled Components)에 대해서 배워 보고 이후 여러 가지 종류의 폼에 대해 배워 보겠습니다.
이름 그대로 누군가의 통제를 받는 컴포넌트입니다.
여기서 통제를 하는 그 누군가가 바로 리액트입니다.
제어 컴포넌트
= 값이 리액트의 통제를 받는 Input Form Element

왼쪽은 HTML 폼을 나타낸 것이고, 오른쪽은 제어 컴포넌트를 나타낸 것입니다.
HTML 폼에서는 각 엘리먼트가 자체적으로 state를 관리하게 됩니다. 따라서 <input> <textarea> <select> 가 각각 내부에 state를 갖고 있습니다. 이렇게 되면 아무래도 자바스크립트 코드를 통해 각각의 값에 접근하기가 쉽지 않습니다.
하지만 오른쪽에 나와 있는 제어 컴포넌트에서는 모든 데이터를 state에서 관리합니다. 또한 앞에서 배운 것처럼 state의 값을 변경할 대에는 무조건 setState() 함수를 사용하게 됩니다. 참고로 위 그림은 클래스 컴포넌트를 기준으로 그린 것인데 함수 컴포넌트에서는 useState() 훅을 사용하여 state를 관리합니다.
Textarea 태그
여러 줄에 걸쳐 긴 텍스트를 입력받기 위한 html 태그


Select 태그
drop-down 목록을 보여주기 위한 html 태그



지금까지 살펴본 것처럼 텍스트 타입의
<input> 태그, <textarea> 태그, 그리고 <select> 태그 를
controlled component로 만드는 방식은 모두 비슷합니다.
value라는 attribute 를 통해서 값을 전달하고 값을 변경할 때는 onChange 에서 setValue() 함수를 사용하여 값을 업데이트합니다.File input 태그
디바이스의 저장 장치로부터 사용자가 하나 또는 여러 개의 파일을 선택할 수 있게 해 주는 HTML 태그
보통은 서버로 파일을 업로드하거나 자바스크립트의 File API를 사용해서 파일을 다룰 때 사용합니다. 실제로 사용하는 방법은 아래 코드와 같습니다.
위 코드처럼 <input> 태그를 사용하고 타입을 file로 해주면 됩니다. 참고로 File input 태그는 그 값이 읽기 전용이기 때문에 리액트에서는 비제어 컴포넌트가 됩니다.
지금까지는 하나의 컴포넌트에서 하나의 입력만을 다뤘는데 만약 하나의 컴포넌트에서 여러 개의 입력을 다루기 위해서는 어떻게 해야 할까요?
여러 개의 state를 선언하여 각각의 입력에 대해 사용!

Reservation 이라는 이름을 가진 호텔 예약을 위한 컴포넌트인데 예약을 하기 위해 필요한 정보 두 가지를 입력받도록 되어 있습니다.
하나는 아침식사 선택 여부이고, 다른 하나는 방문객 수입니다.
아침식사 선택 유무를 입력받기 위한 <input> 태그는 type 이 checkbox 로 되어 있고, 값이 변경되면 setHaveBreakfast() 함수를 통해 값을 업데이트합니다.
그리고 방문객 수를 입력받기 위한 <input> 태그는 type이 number로 되어 있고, 값이 변경되면 setNumberOfGuest() 함수를 통해 값을 업데이트합니다.
클래스 컴포넌트에서는 setState() 함수 하나로 모든 state의 값을 업데이트했지만 함수 컴포넌트에서는 각 state의 변수마다 set 함수가 따로 존재하기 때문에 위와 같은 형태로 각각의 set 함수를 사용해서 구현하면 됩니다.
앞에서 배운 것처럼 제어 컴포넌트에 value prop 을 정해진 값으로 넣으면 코드를 수정하지 않는 한 입력값을 바꿀 수 없습니다. 만약 value prop을 넣되 자유롭게 입력할 수 있게 만들고 싶다면 값에 undefined 또는 null을 넣어주면 됩니다. 아래 예제 코드를 봅시다.
const root = ReactDOM.createRoot(rootNode);
root.render(<input value="hi" />);
setTimeout(function() {
root.render(<input value={null} />);
}, 1000);
처음에는 input의 값이 hi로 정해져 있어서 값을 바꿀 수 없는 입력 불가 상태였다가 timer에 의해 1초 뒤에 value가 null인 <input> 태그가 렌더링되면서 입력 가능한 상태로 바뀝니다. 이러한 방법을 잘 활용하면 value prop을 넣으면서 동시에 사용자가 자유롭게 입력할 수 있게 만들 수 있습니다.
- 폼 : 사용자로부터 입력을 받기 위해 사용하는 양식
- 제어 컴포넌트 :
사용자가 입력한 값에 접근하고 제어할 수 있게 해 주는 컴포넌트
값이 리액트의 통제를 받는 입력 폼 엘리먼트<input type="text">: 한 줄로 텍스트를 입력받기 위한 HTML 태그<textarea>: 여러 줄에 걸쳐서 텍스트를 입력받기 위한 HTML 태그<select>: 드롭다운 목록을 보여 주기 위한 HTML 태그<input type="file">: 디바이스의 저장 장치로부터 사용자가 하나 또는 여러 개의 파일을 선택할 수 있게 해 주는 HTML 태그 / 서버로 파일을 업로드하거나 자바스크립트의 File API를 사용해서 파일을 다룰 때 사용- 여러 개의 입력 다루기 : 컴포넌트에 여러 개의 state를 선언하여 각각의 입력에 대해 사용하면 됨
- Input Null Value : value prop은 넣되 자유롭게 입력할 수 있게 만들고 싶을 경우, 값에 undefined 또는 null을 넣으면 됨