프론트엔드 스터디 11주차: React 기초 2 —.
useEffect로 사이드 이펙트를 다루고, 이벤트 처리와 폼 상태 관리까지 — React로 실제 동작하는 앱을 만들기 위한 핵심 기술을 배웁니다.
<strong>학습 챕터:</strong> 한 입 크기로 잘라먹는 리액트 — 컴포넌트 / JSX /
Props / 이벤트 처리하기 / 컴포넌트와 상태
<strong>자료 바로가기:</strong>
---
---
// 명령형 — DOM을 직접 조작 (jQuery 스타일)
const button = document.createElement("button");
button.textContent = "클릭";
button.addEventListener("click", () => {
button.textContent = "클릭됨!";
});
document.body.appendChild(button);
// 선언형 — React 스타일: "이런 화면을 보여줘"
function App() {
const [clicked, setClicked] = useState(false);
return (
<button onClick={() => setClicked(true)}>
{clicked ? "클릭됨!" : "클릭"}
</button>
);
}// Header, Sidebar, Content 각각이 독립적인 컴포넌트
function App() {
return (
<div>
<Header />
<Sidebar />
<Content />
</div>
);
}---
// 가장 간단한 컴포넌트
function Greeting() {
return <h1>안녕하세요!</h1>;
}
// 다른 컴포넌트 안에서 사용
function App() {
return (
<div>
<Greeting />
<Greeting />
</div>
);
}// ✅ 대문자 — React 컴포넌트로 인식
<MyButton /> → React.createElement(MyButton)
// ❌ 소문자 — HTML 태그로 인식 (존재하지 않는 태그)
<myButton /> → React.createElement('mybutton')---
// ❌ 에러 — 루트 요소가 두 개
function App() {
return (
<h1>제목</h1>
<p>내용</p>
);
}
// ✅ Fragment로 감싸기 — 불필요한 DOM 노드 없음
function App() {
return (
<>
<h1>제목</h1>
<p>내용</p>
</>
);
}function Profile({ user }) {
return (
<div>
{/* 변수 */}
<h1>{user.name}</h1>
{/* 계산 */}
<p>나이: {user.age + 1}살 (내년 기준)</p>
{/* 함수 호출 */}
<p>가입일: {formatDate(user.createdAt)}</p>
</div>
);
}// ❌ HTML 습관대로 쓰면 안 됨
<div class="container">
// ✅ JSX에서는 className
<div className="container">function Dashboard({ isLoggedIn, notifications }) {
return (
<div>
{/* && — 조건이 true일 때만 렌더링 */}
{isLoggedIn && <p>환영합니다!</p>}
{/* 삼항 — true/false에 따라 다른 것을 렌더링 */}
{isLoggedIn ? <LogoutButton /> : <LoginButton />}
{/* 숫자 0 주의 — 0은 falsy이지만 화면에 0이 출력됨 */}
{notifications.length > 0 && <Badge count={notifications.length} />}
</div>
);
}---
// 부모에서 props 전달
function App() {
return <UserCard name="철수" age={25} isAdmin={true} />;
}
// 자식에서 구조 분해로 수신 — 지난 주 배운 문법!
function UserCard({ name, age, isAdmin }) {
return (
<div>
<h2>{name}</h2>
<p>{age}세</p>
{isAdmin && <span>관리자</span>}
</div>
);
}// ❌ props 직접 수정 — 절대 하면 안 됨
function UserCard({ name }) {
name = "영희"; // React의 단방향 원칙 위반
return <h2>{name}</h2>;
}function TodoList({ todos }) {
return (
<ul>
{todos.map((todo) => (
// key는 고유한 id를 사용 — 배열 인덱스는 피하세요
<li key={todo.id}>
{todo.text} {todo.done && "✓"}
</li>
))}
</ul>
);
}
// 사용
<TodoList
todos={[
{ id: 1, text: "장보기", done: true },
{ id: 2, text: "운동하기", done: false },
{ id: 3, text: "공부하기", done: false },
]}
/>;---
import { useState } from "react";
function Counter() {
// [현재 값, 값을 바꾸는 함수] = useState(초기값)
const [count, setCount] = useState(0);
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
<button onClick={() => setCount(count - 1)}>-1</button>
<button onClick={() => setCount(0)}>초기화</button>
</div>
);
}// ❌ 직접 변경 — React가 변경을 감지하지 못함
count = count + 1;
// ✅ setState — React가 감지하고 리렌더링 실행
setCount(count + 1);// ❌ 위험 — 빠른 연속 클릭 시 오래된 count를 참조할 수 있음
setCount(count + 1);
// ✅ 안전 — 항상 최신 상태(prev)를 받아서 계산
setCount((prev) => prev + 1);// 버튼 한 번 클릭에 +3을 하고 싶은 경우
function handleClick() {
// ❌ 세 번 호출해도 +1만 됨 (모두 같은 count를 참조)
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
// ✅ 세 번 호출하면 +3이 됨 (각각 최신 prev를 받음)
setCount((prev) => prev + 1);
setCount((prev) => prev + 1);
setCount((prev) => prev + 1);
}function SignupForm() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [agreed, setAgreed] = useState(false);
return (
<form>
<input value={name} onChange={(e) => setName(e.target.value)} />
<input value={email} onChange={(e) => setEmail(e.target.value)} />
<label>
<input
type="checkbox"
checked={agreed}
onChange={(e) => setAgreed(e.target.checked)}
/>
동의합니다
</label>
</form>
);
}---
`function Counter() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);---
---
---
프론트엔드 스터디 9주차 학습 자료: React 입문 전 필수 JS 문법
Post Q&A
프론트엔드 스터디 10주차: React 기초 1 — 컴포넌트, JSX, props, useState 전체를 기준으로 질문과 피드백을 받아요.답을 본 뒤에는 이 내용을 댓글로 달아서 서징에게도 물어볼 수 있어요. 작성자가 직접 볼 수 있어요!
지금 당장 읽지 않아도 됩니다. React를 배우면서 에러 처리가 필요해지거나 면접 대비가 필요할 때 참고하세요.