[React] 폼(form)
1. 폼(Form)
- 사용자로부터 입력을 받기 위해 사용하는 양식
1) 리액트 폼
- 리액트 컴포넌트 내부에서 state를 통해 관리함
- state의 값을 변경하기 위해서 무조건 setState() 함수 사용
2) HTML폼
- 엘리먼트 내부에 각각의 state가 존재
- 각 엘리먼트가 자체적으로 state 관리
<form>
<label>
이름: <input type="text" name="name" />
</label>
<button type="submit">제출</button>
</form>
2. 제어 컴포넌트(Controlled Components)
- 사용자가 입력한 값에 접근하고 제어할 수 있게 해주는 컴포넌트
- 값이 리액트의 통제를 받는 입력 폼 엘리먼트
import React, {useState} from "react";
// SignUp 컴포넌트
function SignUp(props) {
// <input>태그에 입력된 값을 저장하기 위한 name이라는 state를 갖음
const [name, setName] = useState("");
const handleChangeName = (event) => {
setName(event.target.value);
};
const handleSubmit = (event) => {
alert(`이름: ${name}`);
event.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
<label>
이름: <input type="text" value={name} onChange={handleChangeName} />
</label>
<button type="submit">제출</button>
</form>
);
}
export default SignUp;
cf. onChange콜백 함수의 첫 번째 파라미터인 event는 이벤트 객체를 나타냄 event.tartget은 현재 발생한 이벤트의 타겟을 의미하며, event.target.value는 해당 타겟의 value 속성값 의미 -> 타겟은 input 엘리먼트, event.target.value는 input엘리먼트의 값 |
3. 여러가지 종류의 폼
1) <input> 태그 - text
<input type="text" value ={}>
- 한 줄로 테스트를 입력받기 위한 HTML Form
- 리액트에서는 value라는 attribute로 입력된 값을 관리
2) <textarea> 태그
- 여러 줄에 걸쳐서 텍스트를 입력받기 위한 HTML 태그
a. HTML의 <textarea>
<textarea>
textarea태그는 여러줄에 걸쳐서 나올 정도로 긴 텍스트를 입력받기 위한 HTML 태그
이건 HTML의 textarea 예제
</textarea>
b. 리액트의 <textarea>태그
- 리액트에서는 value라는 attribute로 입력된 값을 관리
<label>
요청사항:<textarea value={value} onChange={handleChangeValue} />
</label>
3) <select> 태그
- 드롭다운 목록을 보여주기 위한 HTML 태그
- 여러가지 옵션 중에서 하나 또는 여러개를 선택할 수 있는 기능 제공
a. HTML <select> 태그
<select>
<option value="apple">사과</option>
<option value="banana">바나나</option>
<option value="grape">포도</option>
<option selected value="watermelon">수박</option>
</select>
- 현재 수박을 선택되어 있는 상태, selectes value로 표현
b. 리액트 <select> 태그
- 리액트에서는 value라는 attribute로 선택된 옵션의 값 관리
<label>
좋아하는 과일:<select value={fruit} onChange={handleChangeFruit} >
<option value="apple">사과</option>
<option value="banana">바나나</option>
<option value="grape">포도</option>
<option value="watermelon">수박</option>
</select>
</label>
4) <input>태그 - File
<input type="file">
- 디바이스의 저장 장치로부터 사용자가 하나 또는 여러 개의 파일을 선택할 수 있게 해주는 HTML 태그
- 서버로 파일을 업로드하거나 자바스크립트의 File API를 사용해서 파일을 다룰 때 사용-
- 읽기 전용(Read-Only)이기 때문에 리액트에서는 비제어 컴포넌트(uncontrolled component)가 됨
4. 여러 개의 입력 다루기
컴포넌트에 여러개의 state를 선언하여 각각의 입력에 대해 사용하면 됨
import React, {useState} from "react";
// SignUp 컴포넌트
function SignUp(props) {
// <input>태그에 입력된 값을 저장하기 위한 name이라는 state를 갖음
const [name, setName] = useState("");
// 성별 값을 저장 하기위한 state 추가
const [gender, setGender] = useState("남자");
const [value, setValue] = useState("요청사항을 입력하세요.");
const [fruit, setFruit] = useState("watermelon")
const handleChangeName = (event) => {
setName(event.target.value);
};
const handleChangeGender = (event) => {
setGender(event.target.value);
};
const handleChangeValue = (event) => {
setValue(event.target.value);
};
const handleChangeFruit = (event) => {
setFruit(event.target.value);
}
const handleSubmit = (event) => {
alert(`이름: ${name}, 성별: ${gender}, 요청사항: ${value}, 좋아하는 과일: ${fruit}`);
event.preventDefault();
};
return (
<form onSubmit={handleSubmit}>
<label>
{/* 이름을 입력할 수 있는 <input>태그 */}
이름: <input type="text" value={name} onChange={handleChangeName} />
</label>
<br />
<label>
성별:<select value={gender} onChange={handleChangeGender}>
<option value="남자">남자</option>
<option value="여자">여자</option>
</select>
</label>
<br />
<label>
요청사항:<textarea value={value} onChange={handleChangeValue} />
</label>
<br />
<label>
좋아하는 과일:<select value={fruit} onChange={handleChangeFruit} >
<option value="apple">사과</option>
<option value="banana">바나나</option>
<option value="grape">포도</option>
<option value="watermelon">수박</option>
</select>
</label>
<button type="submit">제출</button>
</form>
);
}
export default SignUp;
- 각 state의 변수마다 set함수가 따로 존재하기 때문에 위와 같은 형태로 각각의 set함수를 사용해서 구현할 수 있음
5. Input Null Value
value prop은 넣되 자유롭게 입력할 수 있게 만들고 싶을 경우, 값에 nudefined 또는 Null을 넣으면 됨
ReactDOM.render(<input value="hi" />, rootNode);
setTimeout(function() {
ReactDOM.render(<input value={null} />, rootNode);
}, 1000);