diff --git a/Chapter_3/Jae0/useCallback.md b/Chapter_3/Jae0/useCallback.md
new file mode 100644
index 0000000..37c80b9
--- /dev/null
+++ b/Chapter_3/Jae0/useCallback.md
@@ -0,0 +1,21 @@
+## useCallback
+
+`useMemo` 에서는 전달 받은 `Callback` 의 `return` 값을 메모이제이션 한것과 유사하게
+
+💡 `useCallback` 은 전달받은 `Callback` 함수 자체를 저장하여 함수를 메모이제이션 함
+⇒ 즉 특정 함수를 새로 만들지 않고 다시 재사용한다는 의미를 가짐
+
+useMemo와의 차이점은 저장하고자 하는 값이 변수냐 함수냐의 차이 일뿐
+
+`const memoFuncName = useCallback( Callback , [ ] )`
+
+- **첫 번째 인자**
+
+ 변수는 인자로 전달받은 `Function`을 메모이제이션해 값을 가지고 있게 됨
+
+- **두 번째 인자**
+ Array로 Array 안의 내부의 값이 변경되지 않는 이상 변경되지 않음!
+
+**주의점**
+
+🔥 함수 내부의 전역 변수를 받아 사용하는 로직이 존재한다면 해당 변수를 디펜던시 안에 넣어줘야함!
diff --git a/Chapter_3/Jae0/useContext.md b/Chapter_3/Jae0/useContext.md
new file mode 100644
index 0000000..3bd820e
--- /dev/null
+++ b/Chapter_3/Jae0/useContext.md
@@ -0,0 +1,105 @@
+> **Prop Drilling & Context**
+>
+> 만약 최 상위 Component 가 지니고 있는 상태를 깊이 존재하는 하위 Component에게 전달하기
+>
+> 위해서는 중간에 존재하는 Component들의 prop을 통해 전달 > 전달 > 전달 > 전달을 통해
+>
+> 주고 받아야하는 복잡한 문제가 발생! - 문제는 하위에서 최상위로 전달할 때도 동일한 문제가 발생함
+>
+> 이런 문제는 깊어지고 상태가 많아질수록 데이터 관리에 불편하고,
+>
+> 중간에 state가 의도와 다르게 변경될 수 있는 위험성을 초래함
+>
+> 이런 과정을 PropDrilling이라고함
+>
+> 그리고 이런 prop drilling을 극복하기 위해 등장한 개념이 Context 임
+
+💡 이런 Prop Drilling을 개선하기 위해 Redux Recoil 등의 라이브러리가 존재하고,
+
+Context API는 React 라이브러리에서 기본으로 제공되는 상태 주입 API로
+상위 컴포넌트에서 만들어진 Context를 통해 하위 컴포넌트가 상태를 쉽게 사용가능하게 함
+
+- 상태를 주입하는 역할을 할뿐 다른 라이브러리처럼 상태 관리를 해주는 API가 아님
+ - 🔥 Context API는 특정 상태를 통해 다른 상태를 만들수 없으며,
+ 필요에 따라 이러한 상태 변화를 최적화 할 수 없기 때문에 상태관리 라이브러리가 아님
+- 최상단에 Context provider를 지정하기보다는 범위를 좁히고 좁혀 사용하는것이 좋음
+
+**사용 방법**
+
+```jsx
+// Context 생성
+
+import { createContext, useState } from "react";
+
+// createContext 를 통해 Context를 만들어줌
+export const Context = createContext();
+
+// component를 umbrella로 감싸줄 외부 Wrap component 함수 만들기.
+export function ContextProvider({ children }) {
+ // conText에서 사용할 기본 State 지정
+ const [State, setState] = useState(false);
+
+ // 상태를 변경할 Function
+ const Toggle = () => setState((state) => !state);
+
+ return (
+
+ {/* 기본 상태와 상태변경을 위한 함수를 객체로 전달한다 */}
+ {children}
+
+ )
+}
+
+// Context 위치 선언
+export default function App() {
+ // 앞서 만든 해당 Context component로 감싸 주기
+ return (
+
+
+
+ )
+}
+
+// 하위 Component
+
+export default function ChildComponent (){
+ // useContext 를 통해 Context 불러오기
+ const { State, Toggle } = useContext(Context);
+
+ return (
+
+ { state }
+
+
+ )
+}
+```
+
+**ContextAPI 오류 검증**
+
+- 만약 하위 컴포넌트에서 Context를 제대로 불러오지 못했을 때를 대비한 방어 코드
+
+```tsx
+export default function ChildComponent() {
+ // useContext 를 통해 Context 불러오기
+
+ function checkContext() {
+ const context = useContext(Context);
+ if (context === undefined) {
+ throw new Error("context가 불려오지 못함");
+ }
+ return context;
+ }
+
+ const { state, toggle } = checkContext();
+
+ return (
+
+ {state}
+
+
+ );
+}
+```
diff --git a/Chapter_3/Jae0/useEffect.md b/Chapter_3/Jae0/useEffect.md
new file mode 100644
index 0000000..83e8562
--- /dev/null
+++ b/Chapter_3/Jae0/useEffect.md
@@ -0,0 +1,113 @@
+💡 무엇인가 변화가 생겨날 대 변화를 감지하고 반응하는 Hook
+
+주로 화면에 처음 렌더링될때 , 다시 렌더링되는순간 , 사라지는순간 에 특정 작업을 처리하고 싶을때 사용함
+
+```jsx
+useEffect(() => {
+ // code
+}, [value]);
+```
+
+**첫 번째 인자**
+
+Callback 함수를 전달받고,
+
+Callback함수 내부에 실행하고 싶은 코드를 작성하면 됨
+
+**두 번째 인자**
+
+dependency Arr 를 전달받고 내부에는 값(value)을 전달 할 수 있음
+
+- 전달받은 값(value)이 변화 되어질 때 마다 useEffect 내부의 Callback 함수가 실행되어짐
+
+🔥 useEffect는 특별한 기능을 통해 값을 감시하지 않고,
+
+렌더링이 새롭게 될 때마다 의존성에 존재하는 값을 보며 의존성의 값이 이전 값과 다를때
+
+전달받은 Callback 함수를 실행하게 된다.
+
+- 일부 외부 데이터와 동기화 하려는것이 아니라면 사용하지 않음
+- Component의 최상위 위치에서만 선언할 수 있음
+- strict 모드에서는 useEffect가 2번 실행 되어짐
+
+### 의존성
+
+``
+
+의존성 배열 조차 전달하지 않는 경우 의존성을 비교할 필요 없이 렌더링 될 때마다 callback이 실행됨
+
+⇒ 주로 component가 렌더링 된것을 확인하고싶을 때 사용함
+
+```jsx
+// 렌더링 테스트 코드
+useEffect(()=>{
+ console.log("렌더링 발생"
+})
+```
+
+🔥 그렇다면 왜 아무것도 전달하지 않고 사용할까?
+
+1. useEffect는 component가 렌더링이 완료된 후 실행되어지고, 일반 함수는 렌더링 도중 실행되어짐
+2. 서버 사이드 렌더링 관점에서 useEffect는 클라이언트 사이드에서 실행되는것을 보장함
+
+`[]`
+
+빈 배열을 전달한 경우 React에서는 비교할 의존성이 없다고 판단하고 최초 렌더링 직후에만 실행되어짐
+
+### 주의, 권장 사항
+
+- useEffect가 전달 받는 callback에 기명 함수를 사용하는것을 권장함
+
+ ⇒ 많은 useEffect들이 생겨나고 이를 구분하기위해 사용하기 좋음
+
+ ```jsx
+ useEffect(function 이름() {}, []);
+ ```
+
+- useEffect는 가능한 작고 가볍게 만들수록 좋음
+
+- dependency에는 외부에서 생성된 객체, 함수와 같은 참조값을 사용하면 안된다
+
+ ```jsx
+ function ChatRoom({ roomId }) {
+ const [message, setMessage] = useState('');
+
+ const options = {
+ serverUrl: serverUrl,
+ roomId: roomId
+ };
+
+ useEffect(() => {
+ const connection = createConnection(options);
+ connection.connect();
+ return () => connection.disconnect();
+ }, [options]);
+ // ...
+ ```
+
+ 위의 예시처럼 options 를 감시하고 있다면,
+ 만약 options의 데이터가 변하지 않은 상태에서 다른 이유로 rerender가 발생했을때 원하는 의도는
+ useEffect가 다시 실행되지 않는 것을 의도함.
+ 하지만 🔥 options는 참조 데이터 이기때문에 rerender시에 값의 변화가 없어도 참조 주소가 변경됨
+ 따라서 useEffect는 참조 주소가 변경된것을 변화로 감지하고 useEffect가 실행되어짐
+
+### Clean Up
+
+💡 이전 값을 기준으로 실행되며, 이전 상태를 청소해주는 역할
+
+```jsx
+useEffect(() => {
+ element.addEventListener();
+
+ return () => {
+ element.removeEventListener();
+ // clean up zone
+ };
+});
+```
+
+clean up 작업은 useEffect 에 전달한 callback 함수의 return 함수 내부에서 실행되어짐
+
+🔥 즉 useEffect 내부의 callback이 실행될 때 이전 clean up 함수가 존재한다면
+
+clean up 함수를 실행 한 뒤 callback 함수를 실행함
diff --git a/Chapter_3/Jae0/useState.md b/Chapter_3/Jae0/useState.md
new file mode 100644
index 0000000..456ab5e
--- /dev/null
+++ b/Chapter_3/Jae0/useState.md
@@ -0,0 +1,48 @@
+💡 State ? 리액트에서 component 가 지니고 있는 상태를 의미함
+
+```jsx
+const [state, setState] = useState(initailState);
+const [num, setNum] = useState(0);
+```
+
+내부의 state는 원하는 이름으로 변경 시켜 줄 수 있음
+
+state
+
+현재의 상태값은 배열 첫번 째 아이템인 state 내부에 들어있음
+
+setState
+
+상태를 변경 시켜주고싶을때 사용할 수 있는 함수
+
+initailState
+
+해당 state의 초기값을 전달할 수 있음
+
+만약 전달된 초기값이 없다면 `undefined`
+
+- setState 를 이용해 state를 변경시켜주면 해당 component 는 다시 한 번 렌더링이 진행됨
+- state를 사용하지 않고 내부에 변수를 통해 상태를 관리하게된다면, 매번 렌더링이 다시 이루어질때
+ 해당 함수형 component는 매번 실행되어지고 내부 변수의 변화된 값은 매번 초기화됨
+- state가 자신의 state를 렌더링이 되어도 유지할 수 있는 이유는 closer
+
+### 게으른 초기화
+
+💡 `useState`에 변수 대신 함수를 넘기는 방법을 게으른 초기화 라고 함
+
+```jsx
+// 일반적 사용 방법
+const [state,setState] = useState(Number.parseInt(window.localStorage ... ))
+// 해당 로직은 state가 처음 실행되는 순간에도 복잡한 연산을 실행함
+// 그리고 값이 변경되어 다시 리렌더링 되는 순간에도 다시 복잡한 연산을 실행하게됨
+
+// 게으른 초기화
+const [state,setState] = useState(()=>{
+ return Number.parseInt(window.localStorage.getItem(key))
+})
+```
+
+- 기본적으로 게으른 초기화를 사용하는 순간은 주로 무거운 연산을 포함하고 있을때 사용을 권장함
+ ⇒ 렌더링이 다시 발생하면 인수로 전달한 실행 값이 다시 실행되기 때문
+ ⇒ 배열에 대한 접근 `map` `filter` `find` 등 / Storage에 접근
+- 게으른 초기화 함수는 오로지 state가 처음 만들어지는 순간에만 사용됨