프론트엔드 스터디 11주차: React 기초 2 —.
useEffect로 사이드 이펙트를 다루고, 이벤트 처리와 폼 상태 관리까지 — React로 실제 동작하는 앱을 만들기 위한 핵심 기술을 배웁니다.
<strong>입문 강의 (처음이라면):</strong> 얄코 JS 입문 강의
※ 얄코 무료 파트에는 Promise/async 비동기 파트가 포함되어 있지 않으므로, 비동기 부분은 아래 본문과 심화 자료로 학습하세요.
<strong>강의 스킵 가능:</strong> 아래 스킵 진단 문제 10개를 모두 맞히면 강의
시청 스킵 가능합니다.
<strong>심화 자료 (딥다이브 대비):</strong>
---
---
function makeCounter() {
let count = 0; // 외부 함수의 변수
return function () {
// 내부 함수 — 클로저
count++;
return count;
};
}
const counter = makeCounter();
// makeCounter()는 이미 종료됐지만
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
// count 변수가 여전히 살아있음function createAccount(initialBalance) {
let balance = initialBalance; // 외부에서 직접 접근 불가
return {
deposit(amount) {
balance += amount;
},
withdraw(amount) {
if (amount > balance) return "잔액 부족";
balance -= amount;
},
getBalance() {
return balance;
},
};
}
const account = createAccount(1000);
account.deposit(500);
console.log(account.getBalance()); // 1500
console.log(account.balance); // undefined — 직접 접근 불가---
// 콜백 지옥
fetch("/user", function (user) {
fetch("/posts?userId=" + user.id, function (posts) {
fetch("/comments?postId=" + posts[0].id, function (comments) {
// 점점 깊어짐...
});
});
});
// Promise 체이닝 — 수평으로 나열
fetch("/user")
.then((user) => fetch("/posts?userId=" + user.id))
.then((posts) => fetch("/comments?postId=" + posts[0].id))
.then((comments) => console.log(comments))
.catch((err) => console.error(err));<strong>pending</strong>: 비동기 작업 진행 중 (초기 상태)
<strong>fulfilled</strong>: 작업 성공 — .then() 콜백 실행
<strong>rejected</strong>: 작업 실패 — .catch() 콜백 실행
한 번 fulfilled/rejected 상태가 되면 변경 불가
// 순차 실행 — 느림 (앞이 끝나야 다음 시작)
async function sequential() {
const a = await fetchA();
const b = await fetchB();
return [a, b];
}
// 병렬 실행 — 동시에 시작하고 모두 완료 기다림
async function parallel() {
const [a, b] = await Promise.all([fetchA(), fetchB()]);
return [a, b];
}
// 가장 먼저 완료된 것만 사용
async function race() {
return await Promise.race([fetchA(), fetchB()]);
}---
// Promise 체이닝
function getUser(id) {
return fetch(`/users/${id}`)
.then((res) => res.json())
.then((user) => user)
.catch((err) => {
throw err;
});
}
// async/await — 같은 동작, 더 직관적
async function getUser(id) {
try {
const res = await fetch(`/users/${id}`);
const user = await res.json();
return user;
} catch (err) {
throw err;
}
}// 잘못된 예 — 순차 실행 (불필요하게 느림)
async function bad() {
const a = await fetchA(); // fetchA 완료 대기
const b = await fetchB(); // 그 다음에야 fetchB 시작
}
// 올바른 예 — 병렬 실행
async function good() {
const [a, b] = await Promise.all([fetchA(), fetchB()]);
}useEffect(() => {
async function fetchData() {
try {
const res = await fetch("/api/data");
const data = await res.json();
setData(data);
} catch (err) {
setError(err);
}
}
fetchData();
}, []);async function fetchUser(userId) {
const res = await fetch(`/api/users/${userId}`);
if (!res.ok) {
throw new Error(`HTTP error: ${res.status}`);
}
const data = await res.json();
return data;
}let loading = true;
let error = null;
let data = null;
try {
data = await fetchUser(1);
} catch (err) {
error = err;
} finally {
loading = false;
}// 서로 독립적인 요청 — 병렬 가능
const [user, notifications] = await Promise.all([
fetchUser(userId),
fetchNotifications(userId),
]);
// 앞 요청 결과가 뒤 요청에 필요 — 순차 실행
const user = await fetchUser(userId);
const posts = await fetchPostsByUser(user.id);---
`function makeAdder(x) {
return function (y) {
return x + y;---
`function makeCounter() {
let count = 0;
return function () {
count++;
return count;---
프론트엔드 스터디 7주차 학습 자료: 불변성, 프로토타입, 타입 체크
프론트엔드 스터디 8주차 학습 자료: 클로저, Promise, async/await
프론트엔드 스터디 9주차 학습 자료: React 입문 전 필수 JS 문법
Post Q&A
프론트엔드 스터디 8주차: 클로저, Promise, async/await 전체를 기준으로 질문과 피드백을 받아요.답을 본 뒤에는 이 내용을 댓글로 달아서 서징에게도 물어볼 수 있어요. 작성자가 직접 볼 수 있어요!
지금 당장 읽지 않아도 됩니다. React를 배우면서 에러 처리가 필요해지거나 면접 대비가 필요할 때 참고하세요.