Form과 Controlled Component
Form
사용자로부터 입력을 받기 위해 사용하는 것이다.
리액트 Form VS. HTML Form
리액트는 컴포넌트 내부에서 state를 통해 데이터를 관리하는 반면,
HTML은 Element 내부에 각각의 state가 존재한다.
📌 예제1-1. HTML Form
<form>
<label>
이름:
<input type="text" name="name" />
</label>
<button type="submit">제출</button>
</form>
HTML Form은, 자바스크립트를 이용해 사용자가 입력한 값이 접근하기에는 힘든 구조이다.
✅ Controlled Component(리액트)를 이용하여 웹 페이지를 제작한다.
Controlled component
사용자가 입력한 값에 접근하고, 제어할 수 있도록 하는 컴포넌트를 의미한다.
즉, 값이 리액트에 의해서 통제(접근 및 제어)를 받는 Input Form Element를 의미한다.
HTML Form은 자체적으로 state를 관리하므로, 태그가 각 내부에 state를 가지고 있다.
반면, Controlled Component를 사용하면 모든 입력값이 리액트의 state를 통해 관리된다.
✅ 즉, Controlled Component는 리액트에서 모든 값을 통제할 수 있는 구조를 가지고 있다.
📌 예제1-2. 예제 1-1을 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="submit">제출</button>
</form>
)
}
Controlled Component를 사용하면,
입력값이 리액트의 state를 통해 관리되며 사용자의 입력을 직접적으로 제어할 수 있다.
✅ 즉, 여러 개의 입력 양식의 값을 원하는 대로 조정할 수 있다.
- 입력 양식의 초기값을 내가 원하는 대로 넣어줄수 있으며,
- 다른 양식의 값이 변경되었을 때 또 다른 양식의 값도 자동적으로 변경해줄 수 있다.
📌 예제2. 모든 입력값을 대문자로 변경
const handleChange = (event) => {
setValue(event.target.value.toUpperCase())
}
다양한 Forms
Textarea
📌 (HTML) textarea 태그
<textarea>
안녕하세요,여기에 이렇게 텍스트가 들어가게 됩니다!
</textarea>
HTML에서는 textarea의 자식으로 텍스트가 들어가는 반면,
리액트는 textarea에 value attribute를 사용하여 텍스트를 표시하게 된다.
📌 (React) textarea 태그
function RequestForm() {
const [value, setValue] = useState("요청사항을 입력하세요.")
const handleChange = (event) => {
setValue(evnet.target.value);
}
const handleSubmit = (event) => {
alert('입력한 요청사항: ' + value)
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
요청사항 :
<textarea value={value} onChange={handleChange}></textarea>
</label>
<button></button>
</form>
)
}
Select
Drop-down 목록을 보여주기 위한 HTML 태그이다.
Drop-down은 여러 개의 옵션 중에 하나를 선택할 수 있는 기능을 제공한다.
📌 (HTML) select 태그
<select>
<option value="apple">사과</option>
<option value="banana">바나나</option>
<option selected value="grape">포도</option>
<option value="watermelon">수박</option>
</select>
HTML에서는 현재 선택된 옵션 'selectd' 속성을 부여한다.
반면, React에서는 selected 속성을 사용하는 대신
<select> 태그에 value attribute를 사용하여 선택된 옵션을 표시한다.
📌 (React) select 태그
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 value="grape">포도</option>
<option value="watermelon">수박</option>
</select>
</label>
<button type="submit">제출</button>
</form>
)
}
목록에서 다중으로 선택되도록 하려면 아래와 같이 코드를 작성한다.
- <select> 태그 안에 multipe={true}를 작성하고,
- value attribute에는 선택된 옵션의 값이 들어있는 배열을 넣어준다.
<select multiple={true} value={['B', 'C']}></select>
Summary
// input 태그
<input type="text" value={value} onChange={handleChange}/>
// textarea 태그
<textarea value={value} onChange={handleChange}/>
// select 태그
<select value={value} onChange={handleChange}>
<option value="apple">사과</option>
<option value="banana">바나나</option>
<option value="grape">포도</option>
<option value="watermelon">수박</option>
</select>
input, textarea, select 태그를 모두 Controlled Component로 만드는 방법은 비슷하다.
- value attribute를 통해서 값을 전달하고,
- 값을 변경할 때에는 onChange에서 setValue()를 사용하여 값을 업데이트
이러한 방식은 실제로 사용자 입력을 받는 컴포넌트를 만들 때 사용한다.
File input
디바이스의 저장 장치로부터 하나 또는 여러 개의 파일을 선택할 수 있게 해주는 HTML 태그이다.
📌 (HTML) file input 태그
<input type="file" />
file input 태그는 그 값이 읽기 전용이기 때문에, React에서는 Uncontrolled Component로 구분된다.
Multiple inputs
하나의 컴포넌트에서 여러 개의 입력을 다루기 위해서는,
✅ 여러 개의 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>
<label>
방문객 수:
<input
type="number"
value={numberOfGuest}
onChange={(event) => {
setNumberOfGuest(event.target.value)
}} />
</label>
<button type="submit">제출</button>
</form>
)
}
클래스 컴포넌트에서는 setState() 하나로 모든 state를 업데이트했지만,
함수 컴포넌트는 각 state의 변수마다 'set-' 함수가 따로 존재한다.
그러므로, 함수 컴포넌트에서는 각각의 set 함수를 사용해서 값을 구현 및 업데이트한다.
Input null value
제어 컴포넌트에 value를 정해진 값으로 넣으면, 수정하지 않는 한 입력값을 바꿀 수 없다.
그러므로 value를 넣되, 자유롭게 입력할 수 있도록 하고 싶다면 값에 'undefined' 또는'null'을 넣어준다.
📌 Input null value
ReactDOM.render(<input value="hi" />, rootNode)
// 값을 바꿀수 없는 입력 불가상태
setTimeout(function() {
ReactDOM.render(<input value={null} />, rootNode)
}, 1000)
// 타이머에 의해 입력 가능한 상태로 바뀜
🚀 참고
- 처음 만난 리액트(React) , 소플 - 섹션11. Forms
'React' 카테고리의 다른 글
[React] React Hook의 종류 - useMemo(), useCallback(), useRef() (0) | 2022.12.29 |
---|---|
[React] React Hook의 개념과 종류 - useState(), useEffect() (0) | 2022.12.29 |
[React] List와 key의 개념과 컴포넌트 렌더링 - map(), filter() (0) | 2022.12.29 |
[React] State의 개념과 컴포넌트 Lifecycle (0) | 2022.12.28 |
[React] 조건부 렌더링의 개념 및 구현 (0) | 2022.12.28 |
댓글