
Form 은 기본적으로 사용자로부터 입력을 받기 위해 사용됩니다.
React의 Form과 HTML의 Form은 조금 차이가 있습니다.
| React | HTML |
|---|---|
| 컴포넌트 내부에서 state를 통해 데이터를 관리 | 엘리먼트 내부에 각각의 state가 존재 |
<!-- HTML Form -->
<form>
<label>
이름:
<input type="text" name="name" />
</label>
<button type="submit">제출</button>
</form>
이 코드는 리액트에서도 잘 작동하지만 자바스크립트 코드를 통해 사용자가 입력한 값에 접근하기엔 불편한 구조입니다.
사용자가 입력한 값에 접근하고 제어할 수 있도록 해주는 컴포넌트입니다. 입력 값이 React 컴포넌트의 state를 통해 관리됩니다.
입력 양식의 초기 값을 내가 원하는 대로 넣어줄 수도 있으며 다른 양식의 값이 변경되었을 때, 또 다른 양식의 값도 자동으로 변경시킬 수 있습니다. 즉, 여러 개의 입력 양식의 값을 원하는 대로 조정할 수 있습니다.
// 모든 입력값을 대문자로 변경
const handleChange = (event) => {
setValue(event.target.value.toUpperCase());
}
// React의 Controlled Component
function NameForm(props) {
const [value, setValue] = useState('');
const handleChange = (event) => {
setValue(event.target.value);
}
const handleSubmit = (event) => {
alert('입력한 이름: ' + value);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
이름:
<input type="text" value={value} onChange={handleChange} />
</label>
<button type="submmit">제출</button>
</form>
)
}
input 태그의 value 부분에 React 컴포넌트의 state에서 값을 가져다 넣어주는 것입니다. 그래서 항상 state에 들어있는 값이 input에 표시됩니다.
또한 입력값이 변경되었을 때 호출되는 onChange에는 handleChange 함수가 호출되도록 했는데, handleChange 함수에서는 setValue 함수를 사용하여 새롭게 변경된 값을 value라는 이름의 state에 저장합니다.
여러 줄에 걸쳐 긴 텍스트를 입력받기 위한 HTML 태그입니다.
<!-- HTML 예시 -->
<textarea>
안녕하세요.
</textarea>
// React 예시
function RequestForm(props) {
const [value, setValue] = useState('요청사항을 입력하세요.');
const handleChange = (event) => {
setValue(event.target.value);
}
const handleSubmit = (event) => {
alert('입력한 요청사항: ' + value);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
요청사항:
<textarea value={value} onChange={handleChange} />
</label>
<button type="submmit">제출</button>
</form>
)
}
Drop-down 목록을 보여주기 위한 HTML 태그입니다. Drop-down 목록은 여러가지 옵션 중에서 하나를 선택할 수 있는 기능을 제공합니다.
<!-- HTML 예시 -->
<select>
<option value="apple">사과</option>
<option value="banana">바나나</option>
<option selected value="grape">포도</option>
<option value="watermelon">수박</option>
</select>
// React 예시
function FruitSelect(props) {
const [value, setValue] = useState('grape');
const handleChange = (event) => {
setValue(event.target.value);
}
const handleSubmit = (event) => {
alert('선택한 과일: ' + value);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
과일을 선택하세요:
<select value={value} onChange={handleChange}>
<option value="apple">사과</option>
<option value="banana">바나나</option>
<option selected value="grape">포도</option>
<option value="watermelon">수박</option>
</select>
</label>
<button type="submmit">제출</button>
</form>
)
}
// 여러 개 옵션 선택
<select multiple={true} value={['B', 'C']}>
디바이스의 저장 장치로부터 하나 또는 여러 개의 파일을 선택할 수 있게 해주는 HTML 태그입니다. 서버로 파일을 업로드하거나 자바스크립트의 File API를 사용해서 파일을 다룰 때 사용합니다.
참고로 File input 태그는 그 값이 읽기 전용이기 때문에 React에서는 uncontrollec 컴포넌트가 됩니다. 즉, 값이 React의 통제를 받지 않습니다.
<!-- HTML 예시 -->
<input type="file" />
하나의 컴포넌트에서 여러 개의 입력을 다루고 싶다면, 여러 개의 state를 선언하여 각각의 입력에 대해 사용하면 됩니다.
function Reservation(props) {
const [haveBreakfast, setHaveBreakfast] = useState(true);
const [numberOfGuest, setNumberOfGuest] = useState(2);
const handleSubmit = (event) => {
alert(`아침식사 여부: ${haveBreakfast}, 방문객 수: ${numberOfGuest}`);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
아침식사 여부:
<input
type="checkbox"
checked={haveBreakfast}
onChange={(event) => {
setHaveBreakfast(event.target.checked);
}} />
</label>
<br />
<label>
방문객 수:
<input
type="number"
checked={numberOfGuest}
onChange={(event) => {
setNumberOfGuest(event.target.value);
}} />
</label>
<button type="submmit">제출</button>
</form>
);
}
제어 컴포넌트에 value prop을 정해진 값으로 넣으면 코드를 수정하지 않는 한 입력 값을 바꿀 수 없습니다. 만약 value prop은 넣되 자유롭게 입력할 수 있게 만들고 싶다면 값에 undefined 또는 null을 넣어주면 됩니다.
ReactDOM.render(<input value="hi" />, rootNode);
setTimeout(function() {
ReactDOM.render(<input value={null} />, rootNode);
}, 1000);
처음엔 input 값이 "hi"로 정해져 있어 값을 바꿀 수 없는 입력 불가 상태였다가, 타이머에 의해 1초 뒤에 value가 null인 input 태그가 렌더링 되면서 입력 가능한 상태로 바뀝니다.