이벤트 처리하기
// Button.jsx
const Button = ({ text, color, children }) => {
// 이벤트 객체
const onClickButton = () => {
console.log(text);
};
return (
<button
onClick={onClickButton}
// onMouseEnter={onClickButton}
style={{ color: color }}
>
{text} - {color.toUpperCase()}
{children}
</button>
);
};
Button.defaultProps = {
color: "black",
};
export default Button;
버튼을 클릭하거나 마우스를 갖다대는 등의 이벤트를 처리하는 '이벤트 핸들링'을 배웠다. button 태그 내부에 이벤트 이름을 입력하고, 화살표 함수 ()=>{} 를 중괄호 안에 넣어주는 방법이 있다. 만약 내부 코드가 길다면 함수 선언식을 불러오는 방법도 있다. 이때, 함수의 호출 결과가 아닌, 함수의 이름 onClickButton 을 전달해야 한다. 마치 콜백함수를 전달하듯이.
State로 상태관리하기
// App.jsx
import "./App.css";
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
const [light, setLight] = useState("OFF");
return (
<>
<div>
<h1>{light}</h1>
<button
onClick={() => {
setLight(light === "ON" ? "OFF" : "ON");
}}
>
{light === "ON" ? "끄기" : "켜기"}
</button>
</div>
<div>
<h1>{count}</h1>
<button
onClick={() => {
setCount(count + 1);
}}
>
+
</button>
</div>
</>
);
}
export default App;
화면을 업데이트 할 때 사용되는 state에 대해 알아보자. state의 값의 변화에 따라 유저가 보는 화면이 업데이트 된다. 이를 리렌더링이라고 한다.
함수 컴포넌트에서 state를 생성하려면 리액트 내장함수를 이용해야 한다. 임포트문을 이용해서 불러온다. useState 함수는 두 개의 요소를 담은 배열을 반환한다. 첫 번째 요소는 state 값, 두 번째 요소는 state 값을 변화시키는 상태 변화 함수이다. useState 함수의 인수로 넣어준 값은 배열의 비구조화 할당 방법에 의해 초기 state 값이 된다.
참고로 일반 변수를 이용하면 값을 바꾸어도 리렌더링이 되지 않는다. 리액트에서는 state가 변화해야 리렌더링이 이루어지기 때문이다.
State와 Props
// App.jsx
import "./App.css";
import { useState } from "react";
import Bulb from "./components/Bulb";
import Counter from "./components/Counter";
function App() {
return (
<>
<Bulb />
<Counter />
</>
);
}
export default App;
// Bulb.jsx
import { useState } from "react";
const Bulb = () => {
const [light, setLight] = useState("OFF");
return (
<div>
{light === "ON" ? (
<h1 style={{ backgroundColor: "orange" }}>ON</h1>
) : (
<h1 style={{ backgroundColor: "gray" }}>OFF</h1>
)}
<button
onClick={() => {
setLight(light === "ON" ? "OFF" : "ON");
}}
>
{light === "ON" ? "끄기" : "켜기"}
</button>
</div>
);
};
export default Bulb;
// Counter.jsx
import { useState } from "react";
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<h1>{count}</h1>
<button
onClick={() => {
setCount(count + 1);
}}
>
+
</button>
</div>
);
};
export default Counter;
state를 props로 전달하는 것도 가능하다. 부모인 App 컴포넌트에서 light에 대한 state를 선언하고, <Bulb light = {light} /> 로 자식인 Bulb 컴포넌트에게 state를 전달한다. Counter 컴포넌트도 마찬가지이다. 하지만, 이런 식으로 state에 대한 계층 구조를 형성하면, 부모의 state가 변경될 때 해당 부모의 모든 자식들도 업데이트 되는 불필요한 상황이 발생한다.
리액트 컴포넌트가 리렌더링 되는 경우는 다음과 같기 때문.
- 자신이 관리하는 state 값이 변경될 때
- 전달받는 props의 값이 변경될 때
- 부모 컴포넌트가 리렌더링 될 때 <= 이 경우에 해당한다.
그러므로 독립된 state는 각각의 컴포넌트에 따로 작성해주는 것이 좋다. 이렇게 하면 필요한 부분만 리렌더링 되어 불필요한 업데이트를 줄일 수 있다.
State로 사용자 입력 관리하기 1
// Register.jsx
// 간단한 회원가입 폼
// 1. 이름
// 2. 생년월일
// 3. 국적
// 4. 자기소개
import { useState } from "react";
const Register = () => {
const [name, setName] = useState("이름");
const [birth, setBirth] = useState("");
const [country, setCountry] = useState("");
const [bio, setBio] = useState("");
const onChangeName = (e) => {
setName(e.target.value);
};
const onChangeBirth = (e) => {
setBirth(e.target.value);
};
const onChangeCountry = (e) => {
setCountry(e.target.value);
};
const onChangeBio = (e) => {
setBio(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName} placeholder={"이름"} />
</div>
<div>
<input value={birth} onChange={onChangeBirth} type="date" />
</div>
<div>
<select value={country} onChange={onChangeCountry}>
<option></option>
<option value="kr">한국</option>
<option value="us">미국</option>
<option value="uk">영국</option>
</select>
</div>
<div>
<textarea value={bio} onChange={onChangeBio} />\
</div>
</div>
);
};
export default Register;
사용자 입력에 따라 state를 관리하려면, 가장 먼저 useState 함수를 선언한다. 인수로 들어가는 값은 state 초기값이다. 해당 값을 input 해주려면 input 태그 안에 value 속성을 사용하면 된다. ex) value={name}
input 창에 사용자가 입력을 하면 발생하는 onChange 이벤트가 있다. 우리는 이벤트 핸들러, 즉 onChange 이벤트가 발생하면 실행할 함수를 작성해주면 된다. 값을 입력하고 개발자 도구를 살펴보면, 이벤트 핸들러의 매개변수를 e라 하면 e.target.value 위치에 해당 값이 저장된 것을 확인할 수 있다. 이 값을 상태 변화 함수의 인수로 전달해주면 state 값이 바뀐다.
'프론트엔드 > 한 입 크기로 잘라먹는 리액트' 카테고리의 다른 글
| React.js - 카운터 앱, State Lifting (0) | 2025.01.30 |
|---|---|
| React.js - State로 사용자 입력 관리하기 2, useRef로 컴포넌트의 변수 생성하기, React Hooks (0) | 2025.01.27 |
| React.js - React 컴포넌트, JSX로 UI 표현하기, Props로 데이터 전달하기 (1) | 2025.01.22 |
| React.js - 소개, App 생성, App 구동 (1) | 2025.01.20 |
| Node.js - 모듈 시스템, 라이브러리 (2) | 2025.01.20 |