1. 이벤트 연결하기
- React는 JavaScript처럼 Camel Case 형태로 함수를 전달해줌.
- HTML의 경우에는 Camel Case가 아닌, 소문자 onclick에 실행함수를 넣는다.
import {useCallback, useState} from "react";
function handleClick2(e) {
console.log('click2', e);
}
function App (){
function handleClick1(e) {
console.log('click1', e);
}
const handleChange = useCallback((e) => {
console.log('change', e.target.value);
}, []);
return (
<div>
<button onClick={handleClick1}>
Button1
</button>
<button onClick={handleClick2}>
Button2
</button>
<div>
<input
type="text"
onChange={handleChange}
/>
</div>
</div>
);
}
export default App;
2. 이벤트의 종류
2.1. 마우스와 관련된 이벤트
- onClick: 마우스 버튼을 ‘클릭’했을 때 발생 (Down + Up)
- onMouseDown: 마우스 버튼을 ‘눌렀을 때’ 발생
- onMouseUp: 마우스 버튼을 ‘뗐을 때’ 발생
- onMouseEnter: 요소 밖에서 안으로 마우스가 들어갔을 때 발생
- onMouseLeave: 요소 안에서 밖으로 마우스가 나갔을 때 발생
- onMouseMove: 요소 안에서 마우스 커서를 움직였을 때 발생.
2.2. 키보드와 관련된 이벤트
- onKeyDown: 키보드의 자판을 눌렀을 때 발생(물리적인 키에 반응)
- onKeyUp: 키보드의 자판을 뗐을 때 발생
- onKeyPress: 키보드의 자판을 눌러 ‘문자가 입력되었을 때’ 발생
- onFocus: 요소가 Focus되었을 때 발생
- onBlur: 요소의 Focus가 사라지면 발생
- onChange: 요소의 값이 변화하면 발생
- Controlled Component: React에 의해 입력 요소값이 제어되는 컴포넌트.
- 장점: 컴포넌트의 state와 input value가 완전히 동일한 값을 가짐(신뢰 가능한 단일 출처), 다른 컴포넌트에 input value를 전달하거나 다른 이벤트 핸들러에서 값을 재설정해줄 수 있음
- 단점: 값이 변경될 때마다 렌더링이 됨(컴포넌트의 영향 범위가 클수록 성능 저하)
- UnControlled Component: Controlled Component와는 반대로, input value를 직접 DOM에서 가져와 사용. 이때 렌더링은 단 한 번만 하게 됨.
function TextInput(){
const [text, setText] = useState('');
return(
<input
type='text'
value={text}
onChange={(e)=>{
setText(e.target.value);
}}
/>
);
}
3.1. Controlled vs Uncontrolled Component
import {useState} from "react";
function TextInput(){
const [value, setValue] = useState('');
console.log('[TextInput] render', value);
return(
<input
type="text"
value={value}
onChange={(e)=>{
setValue(e.target.value);
}}
/>
);
}
export default TextInput;
import {useRef} from "react";
function UncontrolledTextInput(){
const inputRef = useRef();
console.log('[UncontrolledTextInput] render');
return(
<>
<input
ref={inputRef} type="text"
/>
<button
onClick={()=>{
console.log(inputRef.current.value);
}}
>
Get Value
</button>
</>
);
}
export default UncontrolledTextInput;
4. 설문조사 만들기
- 이름과 사는 곳을 입력받는 설문조사 폼 만들기
- 만약 사는 곳이 ‘한국’인 경우, ‘2-1. 한국 어디에 사나요?’라는 항목을 노출시키기.
- 1번과 2번을 모두 입력하지 않았다면 저장 버튼 비활성화.
- 저장 버튼 클릭 시 “저장되었습니다”라는 문구를 띄우고, 입력된 폼 내용을 모두 제거.
4.1. 입력 코드
function TextInputEx({value, setValue}){
return(
<input
type="text"
value={value}
onChange={(e)=>{
setValue(e.target.value);
}}
/>
);
}
export default TextInputEx;
function SelectEx({value, setValue, options= []}){
return(
<select value={value}
onChange={(e)=>{
setValue(e.target.value);
}}
>
<option value="" disabled>지역을 선택해 주세요.</option>
{options.map((item) => (
<option key={item} value={item}>{item}</option>
))}
</select>
);
}
export default SelectEx;
import {useState} from "react";
import TextInputEx from "./eventComponent/TextInputEx";
import SelectEx from "./eventComponent/SelectEx";
const countryOptions = [
"한국",
"러시아",
"일본",
"중국",
"미국"
];
function SSulMoon(){
const [formValue, setFormValue] = useState({
name: "",
country: "",
address: ""
});
console.log('[App] formValue', formValue);
return(
<div className="App">
<div className="form">
<div className="form-item">
<h1>1. 이름이 무엇인가요?</h1>
<TextInputEx value={formValue.name} setValue={(value)=>{
setFormValue((state)=>({
...state,
name: value
}));
}}/>
</div>
<div className="form-item">
<h1>2. 사는 곳은 어디인가요?</h1>
<SelectEx value={formValue.country}
setValue={(value)=>{
setFormValue((state)=>({
...state,
country: value
}));
}}
options={countryOptions}
/>
</div>
{formValue.country === "한국" && (
<div className="form-item">
<h1>2-1. 한국 어디에 사나요?</h1>
<TextInputEx value={formValue.address} setValue={(value) => {
setFormValue((state) => ({
...state,
address: value
}));
}}/>
</div>
)}
{}
<div className="button-group">
<button onClick={() => {
alert('저장되었습니다');
setFormValue({
name: "",
country: "",
address: ""
});
}}
disabled={!formValue.name || !formValue.country}
>
저장
</button>
</div>
</div>
</div>
)
}
export default SSulMoon;
4.1. 결과 페이지

