React의 이벤트 처리는 HTML과 유사하지만, 몇 가지 차이점이 있습니다. 이를 통해 사용자의 행동(클릭, 입력 등)에 반응하여 컴포넌트의 상태(State)를 변경하고 UI를 동적으로 만들 수 있습니다.
주요 특징:
onclick 대신 onClick, onchange 대신 onChange와 같이 이벤트 이름은 카멜 케이스로 작성합니다.{} 안에 넣어 전달합니다.event.preventDefault() (기본 동작 방지), event.target.value (입력 값 접근) 등의 작업을 수행할 수 있습니다.import React, { useState } from 'react';
function FormComponent() {
const [inputValue, setInputValue] = useState('');
const handleChange = (event) => {
// event.target.value를 통해 input의 현재 값을 가져옴
setInputValue(event.target.value);
};
const handleSubmit = (event) => {
event.preventDefault(); // form의 기본 제출 동작(새로고침)을 막음
alert('Submitted value: ' + inputValue);
};
return (
<form onSubmit={handleSubmit}>
<input type="text" value={inputValue} onChange={handleChange} />
<button type="submit">Submit</button>
</form>
);
}
Controlled Components: 위 예시처럼, input의 value를 컴포넌트의 state와 연결하고, onChange 이벤트를 통해 state를 업데이트하는 방식을 "제어 컴포넌트(Controlled Component)"라고 합니다. 이는 React에서 폼을 다루는 표준적인 방법입니다.
React의 기본 데이터 흐름은 하향식(Top-Down)이지만(부모 → 자식, via Props), 자식 컴포넌트에서 발생한 데이터를 부모 컴포넌트로 전달해야 할 때가 많습니다. (e.g., 자식의 폼에서 입력한 데이터를 부모의 목록 상태에 추가)
핵심 원리: 부모가 데이터를 처리할 함수를 자식에게 Props로 전달하고, 자식은 그 함수를 호출하여 데이터를 "위로" 보냅니다.
[부모] 자식으로부터 받은 데이터를 처리할 함수를 정의합니다.
[부모] 해당 함수를 자식 컴포넌트에 Props로 전달합니다.
[자식] 특정 이벤트(e.g., 폼 제출)가 발생했을 때, Props로 전달받은 함수를 호출하면서 전달할 데이터를 인자로 넘깁니다.
[부모] 함수가 호출되면서 자식의 데이터가 부모의 상태를 업데이트하고, 리렌더링이 발생합니다.
// ParentComponent.js
function ParentComponent() {
const [items, setItems] = useState([]);
// 1. 자식의 데이터를 받아 처리할 함수
const addItemHandler = (newItem) => {
setItems((prevItems) => [newItem, ...prevItems]);
};
return (
<div>
{/* 2. 자식에게 함수를 props로 전달 */}
<ChildForm onAddItem={addItemHandler} />
<ItemList items={items} />
</div>
);
}
// ChildForm.js
function ChildForm(props) {
const [enteredText, setEnteredText] = useState('');
const submitHandler = (event) => {
event.preventDefault();
// 3. props로 받은 함수를 호출하여 데이터를 위로 전달
props.onAddItem(enteredText);
setEnteredText('');
};
return <form onSubmit={submitHandler}>...</form>;
}
map() 메서드를 사용합니다. map()은 배열의 각 요소를 순회하며, 각 요소를 JSX 엘리먼트로 변환한 새로운 배열을 반환합니다.key Prop의 중요성map()을 사용하여 리스트를 렌더링할 때는, 각 엘리먼트에 key라는 특별한 Prop을 반드시 포함해야 합니다.
key의 역할: React가 리스트의 항목이 변경, 추가, 또는 삭제되었을 때 어떤 항목을 변경해야 하는지 효율적으로 식별하기 위해 사용됩니다. key는 React에게 각 항목의 "신분증"과 같습니다.
좋은 key: 각 항목을 고유하게 식별할 수 있는 안정적인 값이어야 합니다. (e.g., 데이터의 id) 배열의 인덱스는 데이터가 변경되지 않는 정적인 리스트에서만 최후의 수단으로 사용해야 합니다.
function TodoList(props) {
return (
<ul>
{/* 배열(props.todos)을 map으로 순회하며 li 엘리먼트 렌더링 */}
{props.todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
);
}
| 방법 | 사용 사례 | 예시 코드 |
|---|---|---|
| 삼항 연산자 | if-else와 같이 두 가지 경우 중 하나를 렌더링할 때 | {isLoggedIn ? <WelcomeUser /> : <LoginButton />} |
논리 && 연산자 | 특정 조건이 참일 때만 엘리먼트를 렌더링할 때 | {unreadMessages.length > 0 && <p>You have messages.</p>} |
if문과 변수 | 렌더링 로직이 복잡하여 JSX 밖에서 처리해야 할 때 | let content = <p>No items found.</p>;if (items.length > 0) { content = <ItemList items={items} />; }return <div>{content}</div>; |
map() 메서드를 사용하며, 각 항목에는 반드시 고유한 key Prop을 지정하여 렌더링 효율을 높여야 합니다.&& 연산자, if문 등 다양한 조건부 렌더링 기법을 활용합니다.