🚀 개요
- react에서 form에 접근하기 위해서는 기본적으로 state를 활용한다.
- hook의 useState를 활용해서 component를 활용할 수 있다고 보면 되는데, 이렇게 state를 통해 control이 가능한 것을 controlledComponent라고 하고, 대표적으로 input, textarea, select가 있다.
- 그렇다면 UncontrolledComponent도 있는가? 그렇다. 값들을 직접 하지 못하고, reference를 통해서 접근을 해야하는 것들이 있다. 바로 외부에서 ref를 받아오는 경우가 그렇다.
export default function ControlledComponent() {
const [name, setName] = useState("")
const [essay, setEssay] = useState("Please write an essay about your favorite DOM element.")
const [flavor, setFlavor] = useState("coconut")
function handleChange(event) {
const type = event.target.type;
if (type === 'text') {
setName(event.target.type);
}
if (name === 'essay') {
setEssay(event.target.value)
}
if (name === 'flavor') {
setFlavor(event.target.value)
}
}
// function handleEssayChange(event) {
// setEssay(event.target.value);
// }
// function handleFlavorChange(event) {
// setFlavor(event.target.value);
// }
function handleSubmit(event) {
alert(`name: ${name}, essay: ${essay}, flavor : ${flavor}`);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input name="name" type="text" value={name} onChange={handleChange} />
</label>
<br />
<br />
<label>
Essay:
<textarea name="essay" onChange={handleChange} />
</label>
<br />
<label>
Pick your favorite flavor:
<select name="flavor" onChange={handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</label>
<br />
<input type="submit" value="Submit" />
</form>
)
}
- 다음과 같이 input, textarea, select를 활용해서 간단한 입력 form을 만들었다.
- 각각의 요소를 리액트에서 접근할 때 무엇을 주의해야하는지 알아보자
🚀 Input
export default function ControlledComponent() { const [name, setName] = useState("") function handleChange(event) { setName(event.target.value) } function handleSubmit(event) { alert(`name: ${name}, essay: ${essay}, flavor : ${flavor}`); event.preventDefault(); } return ( <form onSubmit={handleSubmit}> <label> Name: <input name="name" type="text" value={name} onChange={handleChange} /> </label> ) }
- input을 구성하는 코드는 위와 같다.
- 여기서 name input 태그의 입력한 값을 name으로 하고, 해당 값의 변경을 추적하기위해 useState를 통해 setname(event.target.value)로 값을 넣어줬다.
- submit을 누르면 해당 정보를 alert으로 띄워주는 코드를 만들었다.
- 여기서 주의해야할 점은
input의 value는 항상 state로 통제하고, 변화값을 추적하는 것은 함수 컴포넌트로 따로 빼서 별도로 저장해준다는 것
이다.
🚀 Textarea
const [essay, setEssay] = useState("Please write an essay about your favorite DOM element.") return ( <form onSubmit={handleSubmit}> <label> Name: <input name="name" type="text" value={name} onChange={handleChange} /> </label> <br /> <br /> <label> Essay: <textarea name="essay" value={essay} onChange={handleChange} /> </label> )
- textarea 역시 value를 essay라는 state를 통해서 주었고, state의 useState hook을 이용해서 따로 정의내리고, setEssay의 값은 handlchange로 따로 함수로 빼서 관리하고 있다.
🚀 Select
const [flavor, setFlavor] = useState("coconut") return ( <label> Pick your favorite flavor: <select name="flavor" value={flavor} onChange={handleChange}> <option value="grapefruit">Grapefruit</option> <option value="lime">Lime</option> <option value="coconut">Coconut</option> <option value="mango">Mango</option> </select> </label> )
- select의 구조 역시 위의 것들과 동일하다. 각각의 선택에 따라 flavor라는 state에 값을 넣어주고 있다. 초기 값을 coconut으로 설정했다.
🚀 다중 입력 제어하기
function handleChange(event) { const type = event.target.type; if (type === 'text') { setName(event.target.type); } if (name === 'essay') { setEssay(event.target.value) } if (name === 'flavor') { setFlavor(event.target.value) } }
- 만약 입력 제어 함수가 굉장히 단순한 것이고, 각 요소를 제어하는 것이 비슷하다면 하나의 함수 컴포넌트에서 여러가지 입력을 제어할 수 있다.
- 위와 같이 각각의 요소마다 name 혹은 type을 통해서 조건문을 걸어줘서 해당 조건을 부합할 때 setState로 값을 넘겨주는 것이 가능하다.
return ( <form onSubmit={handleSubmit}> <label> Name: <input name="name" type="text" value={name} onChange={handleChange} /> </label> <br /> <br /> <label> Essay: <textarea name="essay" onChange={handleChange} /> </label> <br /> <label> Pick your favorite flavor: <select name="flavor" onChange={handleChange}> <option value="grapefruit">Grapefruit</option> <option value="lime">Lime</option> <option value="coconut">Coconut</option> <option value="mango">Mango</option> </select> </label> <br />
- 이렇게 되면 해당 값의 함수를 모두 만들어서 각각의 변화값을 같은 함수로 통제할 수 있다. 위의 코드가 onChange={handleChange}로 같은 것을 통해서 예를 들 수 있다.
export default function UncontrolledComponent() {
const fileInputRef = useRef(null);
function handleSubmit(event) {
event.preventDefault();
alert(
`Selected file - ${fileInputRef.current.files[0].name}`
);
}
return (
<form onSubmit={handleSubmit}>
<label>
Upload file:
<input type="file" ref={fileInputRef} />
</label>
<br />
<button type="submit">Submit</button>
</form>
)
}
🚀 ref활용
- file upload 하는데 해당 파일에 대한 통제는 uncontroll하기 때문에 useRef 훅을 통해서 초기값은 Null로 설정하고 불러오기 위해서 current의 파일로 불러오고 있다.
- ref로 불러올 땐 useRef를 사용하고, current로 불러오는 구조에 대해서 꼭 인지하자!