프론트엔드 스터디 11주차: React 기초 2 —.
useEffect로 사이드 이펙트를 다루고, 이벤트 처리와 폼 상태 관리까지 — React로 실제 동작하는 앱을 만들기 위한 핵심 기술을 배웁니다.
<strong>useEffect 안에서 fetch 에러 처리</strong>를 하고 싶은데 try/catch가
낯설 때
<strong>API 응답 유효성 검사, 폼 입력 검증</strong>에 정규 표현식을 쓰고 싶을
때
<strong>커스텀 에러 클래스</strong>로 에러 종류를 구별하고 싶을 때 <strong>면접</strong>에서 에러 처리나 정규 표현식 관련 질문을 받게 될 때
---
<strong>학습 챕터:</strong> poiemaweb — 에러 처리 / 정규 표현식 <strong>자료 바로가기:</strong>
<strong>딥다이브 요약본 (보충용):</strong>
---
---
function divide(a, b) {
if (b === 0) throw new Error("0으로 나눌 수 없습니다");
return a / b;
}
try {
const result = divide(10, 0);
console.log(result);
} catch (err) {
console.error(err.message); // "0으로 나눌 수 없습니다"
console.error(err.name); // "Error"
} finally {
console.log("항상 실행"); // 에러 여부 관계없이 실행
}// JS에서 자주 마주치는 에러 타입들
try {
null.property; // TypeError
undeclaredVar; // ReferenceError
JSON.parse("{bad}"); // SyntaxError
} catch (err) {
if (err instanceof TypeError) {
console.log("타입 에러:", err.message);
} else if (err instanceof ReferenceError) {
console.log("참조 에러:", err.message);
}
}class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
class NetworkError extends Error {
constructor(message, statusCode) {
super(message);
this.name = "NetworkError";
this.statusCode = statusCode;
}
}
// 에러 종류에 따라 다르게 처리
try {
throw new ValidationError("이메일 형식이 올바르지 않습니다", "email");
} catch (err) {
if (err instanceof ValidationError) {
console.log(`[${err.field}] ${err.message}`);
} else if (err instanceof NetworkError) {
console.log(`HTTP ${err.statusCode}: ${err.message}`);
} else {
throw err; // 처리할 수 없는 에러는 다시 전파
}
}// 기본 패턴
async function fetchUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) {
throw new NetworkError("요청 실패", res.status);
}
return await res.json();
} catch (err) {
console.error("fetchUser 에러:", err.message);
throw err; // 필요하면 상위로 전파
}
}
// 호출부 처리
async function loadUser() {
try {
const user = await fetchUser(1);
setUser(user);
} catch (err) {
setError(err.message);
}
}---
// 문자 클래스
const digits = /\d/; // 숫자 [0-9]
const words = /\w/; // 단어 문자 [a-zA-Z0-9_]
const spaces = /\s/; // 공백 문자
const any = /./; // 줄바꿈 제외 모든 문자
// 수량자
const zeroOrMore = /a*/; // 0번 이상
const oneOrMore = /a+/; // 1번 이상
const optional = /a?/; // 0번 또는 1번
const exactly3 = /a{3}/; // 정확히 3번
const twoToFour = /a{2,4}/; // 2~4번
// 앵커
const start = /^hello/; // hello로 시작
const end = /world$/; // world로 끝
const exact = /^hello world$/; // 정확히 이 문자열// 이메일 유효성 검사
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
emailRegex.test("user@example.com"); // true
emailRegex.test("invalid-email"); // false
// 한국 휴대폰 번호
const phoneRegex = /^01[016789]-?\d{3,4}-?\d{4}$/;
phoneRegex.test("010-1234-5678"); // true
// URL에서 도메인 추출
const url = "https://www.example.com/path?query=1";
const domain = url.match(/https?:\/\/([^\/]+)/)?.[1];
// "www.example.com"
// 날짜 포맷 변환 (YYYY-MM-DD → YYYY.MM.DD)
"2026-06-08".replace(/(\d{4})-(\d{2})-(\d{2})/, "$1.$2.$3");
// "2026.06.08"const str = "Hello World hello";
const regex = /hello/gi; // g: 전역, i: 대소문자 무시
// test — 매칭 여부 (boolean)
regex.test(str); // true
// match — 매칭 결과 배열
str.match(regex); // ["Hello", "hello"]
// replace — 교체
str.replace(regex, "Hi"); // "Hi World Hi"
// split — 분리
"a,b,,c".split(/,+/); // ["a", "b", "c"]
// search — 첫 번째 매칭 인덱스
str.search(/World/); // 6---
`function riskyOperation() {
throw new TypeError("타입 에러 발생");---
`function test() {
try {
throw new Error("에러 발생");
console.log("A");---
프론트엔드 스터디 심화: this, 실행 컨텍스트, 이터러블
Post Q&A
프론트엔드 스터디 심화: 에러 처리와 정규 표현식 전체를 기준으로 질문과 피드백을 받아요.답을 본 뒤에는 이 내용을 댓글로 달아서 서징에게도 물어볼 수 있어요. 작성자가 직접 볼 수 있어요!
지금 당장 읽지 않아도 됩니다. React를 배우면서 에러 처리가 필요해지거나 면접 대비가 필요할 때 참고하세요.