diff --git "a/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.2_API_\354\203\201\355\203\234_\352\264\200\353\246\254\355\225\230\352\270\260/seongho.md" "b/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.2_API_\354\203\201\355\203\234_\352\264\200\353\246\254\355\225\230\352\270\260/seongho.md"
index 3beced8..3c5068e 100644
--- "a/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.2_API_\354\203\201\355\203\234_\352\264\200\353\246\254\355\225\230\352\270\260/seongho.md"
+++ "b/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.2_API_\354\203\201\355\203\234_\352\264\200\353\246\254\355\225\230\352\270\260/seongho.md"
@@ -1 +1,100 @@
-
+### 상태 관리 라이브러리에서 호출하기
+---
+실제 API를 호출하는 코드는 컴포넌트 내에서 비동기 함수를 직접 호출하지 않음.
+비동기 API를 호출하기 위해서는 API의 성공 및 실패에 따른 상태관리가 되어야 하므로, 상태관리 라이브러리의 액션이나 훅과 같이 재정의된 형태를 사용해야 함
+
+상태 관리 라이브러리의 비동기 함수들은 서비스 코드를 사용해서 비동기 상태를 변화 시킬 수 있는 함수를 제공함.
+컴포넌트는 이러한 함수를 사용해서 상태를 구독하며, 상태가 변경될 때 컴포넌트를 다시 렌더링하는 방식으로 동작함.
+
+`Redux`예시를 살펴보자
+```ts
+import { useEffect } from "react";
+import { useDispatch, useSelector } from 'react-redux';
+
+export function useMonitoringHistory() {
+ const dispatch = useDispatch();
+
+ const searchState = useSelector((state) => state.monitoringHistory.searchState);
+
+ const getHistoryList = async (
+ newState: Partial
+ ) => {
+ const newSearchState = { ...searchState, ...newState };
+ dispatch(monitoringHistorySlice.actions.changeSearchState(newSearchState));
+
+ const response = await getHistories(newSearchState); // 비동기 API 호출
+ dispatch(monitoringHistorySlice.actions.fetchDate(response));
+ }
+
+ return {
+ searchState,
+ getHistoryList
+ };
+}
+```
+해당 코드는 `getHistoryList`만 호출하고, 해당 결과를 받아와서 상태를 업데이트 하는 일반적인 방식으로 사용할 수 있음. 그러나, 해당 코드에서는 `getHistoryList`함수에서는 `dispatch`코드를 제외하더라도 **API호출**과 **상태 관리 코드**를 작성해야 함.
+
+```ts
+const API = axios.create();
+
+const setAxiosInterceptor = (store: EnhancedStore) => {
+ API.interceptors.request.use(
+ (config: AxiosRequestConfig) => {
+ const { params, url, method } = config;
+
+ // 전역상태 관리 코드...
+
+ return config;
+ },
+ (error) => Promise.reject(error)
+ );
+
+ API.interceptors.response.use(
+ (response: AxiosResponse) => {
+ const { method, url } = response.config;
+
+ // 전역상태 관리 코드...
+
+ return response.data.data;
+ },
+ (error) => {
+ // 전역상태 관리 코드...
+
+ return Promise.reject(error);
+ }
+ );
+}
+```
+요런식으로 API를 호출할 때, 호출한 뒤, 에러가 발생했을 때 각각 전역상태를 세팅해주어야 함.
+
+
+
+### 훅으로 호출하기
+---
+`react-query`나 `swr`과 같은 훅을 사용한 방법은 전역 상태 관리 라이브러리를 사용한 방식보다 훨씬 간단함.
+이러한 훅은 캐시를 사용하여 비동기 함수를 호출하며, 의도치 않은 상태 변경을 방지하는데 도움이 됨.
+
+```ts
+// 커스텀 훅
+const useGetJobList = () => {
+ return useQuery(['getJobList'], async () => {
+ const response = await JobService.fetchJobList();
+
+ // View Model을 사용해서 결과 return
+ return new JobList(response);
+ });
+}
+```
+이렇게 작성한 이후, 일반적인 훅을 호출하는 것 처럼 사용하면 됨.
+만약, 항시 최신 상태를 표현하려면 `폴링`이나 `웹소켓` 등의 방식을 사용해야 함.
+
+> [!TIP]
+> **폴링(Polling)**
+> 클라이언트가 주기적으로 서버에 요청을 보내 데이터를 일정 주기마다 최신 데아터로 업데이트 하는 방식
+
+
+
+전역 상태 관리 라이브러리에서는 비동기로 상태를 변경하는 코드가 추가되면 점점 전역 상태 관리 스토어가 비대해지는 것을 볼 수 있음.
+따라서 `redux`나 `mobX`와 같은 라이브러리를 `react-query`로 변경하는 추세임.
+
+그러나 늘 그렇듯이 `react-query`가 정답인것은 아님. 어떤 상태 관리 라이브러리를 선택할지는 상황에 따라 적절한 판단이 필요함.
diff --git "a/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.3_API_\354\227\220\353\237\254_\355\225\270\353\223\244\353\247\201/seongho.md" "b/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.3_API_\354\227\220\353\237\254_\355\225\270\353\223\244\353\247\201/seongho.md"
index 3beced8..f4662e1 100644
--- "a/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.3_API_\354\227\220\353\237\254_\355\225\270\353\223\244\353\247\201/seongho.md"
+++ "b/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.3_API_\354\227\220\353\237\254_\355\225\270\353\223\244\353\247\201/seongho.md"
@@ -1 +1,175 @@
-
+비동기 API호출을 하다보면, 상태 코드에 따라서 다양한 에러를 마주하게 됨.
+ts에서 어떻게 에러를 처리하고, 명시할 수 있는지 알아보자
+
+
+
+### 타입 가드 활용하기
+---
+`Axios`를 사용한다면 `isAxiosError`라는 타입가드를 활용할 수 있지만, 서버 에러임을 명확하게 표시하고, 서버에서 내려주는 에러 응답 객체에 대해서도 구체적으로 정의하면 더 좋음.
+
+```ts
+interface ErrorResponse {
+ status: string;
+ serverDataTime: string;
+ errorCode: string;
+ errorMessage: string;
+}
+
+function isAxiosError(error: unknonw): error is AxiosError {
+ return axios.isAxiosError(error);
+}
+```
+이렇게 작성하면 서버 에러인지, 클라이언트 에러인지 명확하게 구분이 가능함.
+
+```ts
+try {
+ // API 호출 로직
+} catch(error) {
+ if (isAxiosError(error)) {
+ // 서버 에러
+ setErrorMessage(error.errorMessage);
+
+ return;
+ }
+
+ // 클라이언트 에러
+ setErrorMessage('클라이언트 에러');
+}
+```
+
+
+
+### 에러 서브클래싱 하기
+---
+> [!NOTE]
+> **서브클래싱(Subclassing)**
+> 기존 클래스를 확장하여 새로운 클래스를 만드는 과정을 말함.
+> 새로운 클래스는 상위 클래스의 모든 속성과 메서드를 상속받아서 사용할 수 있고, 추가적으로 새로운 속성과 메서드를 정의할 수도 있음.
+
+우리가 코드를 작성하다보면 다양한 에러가 내려올 때가 있는데 이때 서브클래싱을 활용하면 어떤 에러인지 바로 확인할 수 있고, 다르게 처리가 가능함.
+
+```ts
+class OrderHttpError extends Error {
+ private readonly privateResponse: AxiosResponse | undefined;
+
+ constructor(message: string, response?: AxiosResponse) {
+ super(message);
+
+ this.name = 'OrderHttpError';
+ this.privateResponse = response;
+ }
+
+ getResponse(): AxiosResponse | undefined {
+ return this.privateResponse;
+ }
+}
+
+class NetworkError extends Error {
+ constructor(message = '') {
+ super(message);
+
+ this.name = 'NetworkError';
+ }
+}
+
+class UnauthorizedError extends Error {
+ constructor(message = '') {
+ super(message);
+
+ this.name = 'UnauthorizedError';
+ }
+}
+```
+
+요런식으로 케이스를 분류해둔 뒤, 가공해서 처리할 수 있음
+
+```ts
+const enum HttpStatusCode {
+ 'NETWORK' = 500,
+ 'UNAUTHORIZED' = 401
+}
+
+// 에러 분류
+const classifyErrorByType = (
+ error: Error | AxiosError
+) => {
+ if (isAxiosError(error)) {
+ const { response } = error;
+
+ switch (response) {
+ case response === HttpStatusCode.NETWORK :
+ return Promise.reject(
+ new NetworkError(response.data.message)
+ );
+
+ case response === HttpStatusCode.UNAUTHORIZED :
+ return Promise.reject(
+ new UnauthorizedError(response.data.message)
+ );
+
+ default:
+ return Promise.reject(
+ new OrderHttpError(
+ response.data.message,
+ response
+ )
+ );
+ }
+ } else {
+ return Promise.reject(error);
+ }
+}
+
+// 에러별 핸들링
+const handleError = (error: unknown) {
+ if (error instanceof UnauthorizedError) {
+ return onUnauthorizedError(
+ error.message,
+ // ...
+ );
+ }
+
+ if (error instanceof NetworkError) {
+ return alert('네트워크 연결이 원활하지 않습니다.');
+ }
+
+ return onOrderHttpError(
+ error.message,
+ error
+ );
+}
+```
+이렇게 해두면 아래와 같이 활용할 수 있음.
+
+```ts
+const getJobList = async () => {
+ try {
+ // API 호출 로직
+ } catch (error) {
+ const classifiedError = classifyErrorByType(error); // 에러 분류
+ handleError(classifiedError); // 분류된 에러 별 액션
+ }
+}
+```
+
+
+
+### 인터셉터를 활용한 에러 처리
+---
+만약 `Axios`를 사용한다면 이러한 에러 분류를 `interceptor`에 붙히는 것도 좋은 방법인 것 같음.
+
+```ts
+axios.interceptors.response.use(
+ (response: AxiosResponse) => response,
+ classifyErrorByType, // 인터셉터에서 에러 분류
+);
+```
+
+
+
+### 리액트 쿼리를 활용한 에러 처리
+---
+리액트 쿼리에서는 `onError`나 `isError`와 같이 에러 핸들러나, 상태를 반환해주는 플래그가 존재하기 때문에 훨씬 에러를 관리하기가 쉬움.
+
+> [!CAUTION]
+> ***`onError는` react-query의 4버전까지만 존재하는 에러 핸들러임 (5버전에서는 삭제)***
diff --git "a/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.4_API_\353\252\250\355\202\271/seongho.md" "b/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.4_API_\353\252\250\355\202\271/seongho.md"
index 3beced8..5df2bf8 100644
--- "a/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.4_API_\353\252\250\355\202\271/seongho.md"
+++ "b/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.4_API_\353\252\250\355\202\271/seongho.md"
@@ -1 +1,74 @@
-
+FE개발을 하다보면 API가 나오기 전에 개발을 진행해야 하는 일이 종종 생김.
+그렇다면 이러한 상황에서는 프론트엔드 개발을 어떻게 진행할 수 있을까??
+
+
+ -
+ 임시 더미 데이터를 만들어서 구현하기
+
+
+ -> 요청 응답에 따라서 각기 다른 화면을 보여줘야 할 경우 대응하기가 힘들다.
+
+ -
+ 별도의 가짜 서버를 만들어서 운영하기
+
+
+ -> 프론트 개발 과정에서 발생하는 모든 예외를 처리하는 것은 쉽지 않다.
+
+
+
+
+
+이럴 때 `모킹`이라는 방법을 활용할 수 있음.
+`모킹`을 활용하면 앞서 제시한 상황에서 유연하게 대처할 수 있음. 또한 서버의 영향을 받지 않고 프론트엔드 개발을 할 수 있게 됨.
+
+그렇다면 모킹에는 어떤 방법들이 있을까?
+
+
+
+### JSON파일 불러오기
+간단한 조회만 필요한 경우에는 .json파일을 만들거나, js파일안에 JSON형식의 정보를 저장하고 export해주는 방식을 사용하면 됨.
+이러고 get요청에 해당 파일 경로를 삽입해주면 조회 응답으로 원하는 값을 받을 수 있음.
+```ts
+// mock/service.ts
+const MOCK = [
+ {
+ name: 'OSH',
+ age: 27,
+ }
+];
+
+export default MOCK;
+
+// api
+const getPerson = apiRequester.get('/mock/service.ts');
+```
+
+
+
+### NextApiHandler 활용하기
+---
+만약 `NextJS`를 사용하고 있다면, NextApiHandler를 사용하는 방법도 있음.
+```ts
+// route.ts
+const MOCK = [
+ // mock data...
+]
+
+export async function GET(req: NextRequest) {
+ return NextResponse.json(MOCK);
+};
+```
+
+
+
+### axios-mock-adapter활용하기
+---
+만약, axios를 사용한다면 axios-mock-adaptor를 사용할 수 있음.
+> [!WARNING]
+> `axios-mock-adapter`는 api요청을 중간에 가로채는 것 이기 때문에 실제 API 요청을 주고받지는 않음.
+
+
+
+### 그 외 방법들
+---
+나는 개인적으로도 사용해본 `msw`나 `mirage`도 괜찮다고 생각함.
diff --git a/README.md b/README.md
index 4602e8d..b77f96a 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@
| 4주차 | 4.2 타입 좁히기 - 타입 가드 ~ 4.4 Exhaustiveness Checking으로 정확한 타입 분기 유지하기 | 2025.04.01 | ✅ |
| 5주차 | 5장 타입 활용하기 | 2025.04.15 | ✅ |
| 6주차 | 6.1 자바스크립트의 런타임과 타입스크립트의 컴파일 ~ 7.1 API 요청 | 2025.04.22 | ✅ |
-| 7주차 | 7.2 API 상태 관리하기 ~ 7.4 API 모킹 | YYYY.MM.DD | |
+| 7주차 | 7.2 API 상태 관리하기 ~ 7.4 API 모킹 | 2025.05.06 | ✅ |
| 8주차 | 8장 JSX에서 TSX로 | YYYY.MM.DD | |
| 9주차 | 9장 훅 ~ 10장 상태관리 | YYYY.MM.DD | |
| 10주차 | 11장 CSS-in-JS ~ 12장 타입스크립트 프로젝트 관리 | YYYY.MM.DD | |