diff --git "a/01\355\232\214/.gitkeep" "b/01\355\232\214/.gitkeep"
deleted file mode 100644
index e69de29..0000000
diff --git "a/02\355\232\214/.gitkeep" "b/02\355\232\214/.gitkeep"
deleted file mode 100644
index e69de29..0000000
diff --git "a/03\355\232\214/.gitkeep" "b/03\355\232\214/.gitkeep"
deleted file mode 100644
index e69de29..0000000
diff --git "a/03\355\232\214/\354\235\264\353\217\204\355\230\204/README.md" "b/03\355\232\214/\354\235\264\353\217\204\355\230\204/README.md"
new file mode 100644
index 0000000..5aaaaae
--- /dev/null
+++ "b/03\355\232\214/\354\235\264\353\217\204\355\230\204/README.md"
@@ -0,0 +1,12 @@
+[3화] UI표현하기 ~ 상호작용 더하기 전반부
+
+# 조건부 렌더링
+
+# 리스트 렌더링
+
+1. key가 왜 중요할까
+
+# 컴포넌트 순수성 유지
+
+1. mutation(변이)
+
diff --git "a/04\355\232\214/\354\235\264\353\217\204\355\230\204/Readme.md" "b/04\355\232\214/\354\235\264\353\217\204\355\230\204/Readme.md"
new file mode 100644
index 0000000..e25bf72
--- /dev/null
+++ "b/04\355\232\214/\354\235\264\353\217\204\355\230\204/Readme.md"
@@ -0,0 +1,469 @@
+[4화] Adding Interactivity (상호작용 추가하기)
+
+## 랜더링하고 커밋하기
+- step 1 . 촉발!!
+ - 렌더링이 일어나는데는 두가지 이유가 있다.
+ 1. 컴포넌트의 초기 렌더링인 경우
+ - 대상 DOM 노드로 createRood를 호출 후 render메서드를 호출한다
+
+ 2. 컴포넌트의 state (또는 상위요소중의 하나)가 업데이트된 경우
+ - state를 업데이트하면 set함수로 업데이트하여 추가렌더링을 일으킨다.(업데이트할때마다!!)
+
+ 추가. 부모에서 자식한테 prop이 없을때는?
+ - **렌더링은 되지만** 바뀌는 데이터가 없으니 그대로 있는다
+
+- step 2. 컴포넌트 렌더링
+ - 촉발 후 React는 **컴포넌트를 호출**하여 화면에 표시할 내용을 파악
+ - 이 과정은 재귀적으로 일어나는데
+ 1. 업데이트된 컴포넌트가 다른 컴포넌트를 반한
+ 2. React는 다른 컴포넌트 렌더링
+ - 예제는 간단해서.. 패스
+ - 첫 렌더링을 하는동안 각 태그에 대한 DOM노드(html요소)를 생성
+### 함정
+- 렌더링은 항상 순수한 계산이어야 합니다.
+ - 동일한 입력에는 동일한 출력을 나와야 한다.
+ - 이전의 state를 변경해서는 안됩니다. 렌더링 전에 존재했던 객체나 변수를 변경해서는 안됩니다.
+ - (이 경우는 코드의 복잡해짐을 겪는 경우가 너무 많았어서 꼭 지켜야 될거 같아요)
+### 성능 최적화 (state 관리 챕터에서 깊게 다룰 예정)
+- npm build를 통해 성능 최적화를 할수 있지만 성급하게 해서는 안된다 (다 따져보고 해야하는데 다음챕터에서 언급)
+
+- step 3. React가 DOM에 변경사항을 커밋
+ ```js
+ export default function Clock({ time }) {
+ return (
+ <>
+
{time}
+
+ >
+ );
+ }
+ ```
+타임의 초가 변경될때마다 렌더링이 되는 모습을 확인할수 있다.
+이 경우 컴포넌트를 각자 사용하면 될거 같긴 하지만 더 좋은 경우가 있을지 확인해보자
+
+## 스냅샷으로서의 state
+- 스냅샷 (한번찍은 정보에 대해 쭉 사용한다 (변경하기 전까지))
+1. state를 설정하면 렌더리이 실행됨
+
+- 인터페이스가 이벤트(불린 값에 의하던지 일정 숫자,클릭)에 반응하려면 state를 업데이트해야 합니다.
+ - 렌더링은 함수를 호출한다는 뜻인데 모든 변수(prop,이벤트,로컬변수)는 렌더링 당시의 state를 사용합니다.
+ ```js
+ import { useState } from 'react';
+
+ export default function Counter() {
+ const [number, setNumber] = useState(0);
+
+ return (
+ <>
+
{number}
+
+ >
+ )}
+ //3개의 큐가 생성이 되지만 각각 set값에 들어갈때는 렌더링 초기의 값 (0)에 들어가므로 결과적으로 1이 출력된다.
+ //strict모드에서는 2번 , 없이는 1번 렌더링 되는것을 확인할수 있다.
+ ```
+ - 하지만 시점을 미뤄도 그대로 number의 값이 0으로 표시가 될까?
+ - 아니다! 지정된 state는 버튼을 클릭했을때 변경이 되었을수 있지만 보여지는 변수의 값은 예약되어있는 값을 출력하기 때문이다.
+ - state변수의 값은 이벤트핸들러의 코드가 비동기적이라도 렌더링내에서 절대 변경되지 않습니다!!
+ - 렌더링 내에서 변수를 변경하고 싶다면 다음 챕터인 state업데이트를 공부하자!
+ - 이벤트 헨들러의 state관계는 렌더링된 jsx와의 관계와 동일하다고 볼수 있다.(위의 jsx문 참고)
+ - 렌더링시점에서의 state변수와 jsx문 안에서의 state변수와 같다는 말
+
+- 문제 1
+ - alert의 위치가 크게 의미가 없는 이유는 snapshot의 영향인데 바뀐 state변수의 값은 예약어 일뿐 현재 상태에서는 어떠한 영향도 끼치지 않기 때문이다.
+
+
+## 여러 state 업데이트를 큐에 담기
+- state변수를 여러번 업데이트 하고 싶다면 전 챕터의 "number+1"이 아닌 아래의 업데이트 함수를 이용하자
+ - 아래의 방법은 number의 값을 예약하며 개별적으로 처리되는게 아닌 일괄적으로 데이터를 저장하여 처리
+ - 따라서 업데이트 함수는 "다음 state값"을 전달하는 것이 아닌 "state값을 계산하는 함수"를 "지시"하는 방법입니다.
+ - 전달하는 것은 다음 전달값이 초기화 되며 값을 출력하는 대신
+ - 업데이트 함수는 큐를 순회하여 업데이트되는 state값을 제공하는것이 다릅니다.
+
+```js
+import { useState } from 'react';
+
+export default function Counter() {
+ const [number, setNumber] = useState(0);
+
+ return (
+ <>
+
+
+ >
+ )
+}
+//위와 같은 방법은 number에 저장된 state값을 함수에 전달하여 6이 나오는것을 확인할수 잇는데
+// "number+5"와 "n=>n+1"의 순서를 바꾼다면 함수로 지시한 값은 초기화 되고 "1"만 출력되는 것을 확인할수 있습니다.
+//이는 jsx문에서 위에서 아래로 순회한다는 것을 보여준다.
+```
+#### 문제 2
+- for of 문과 forEach문을 사용할수 있는데 배열안의 값을 나열하여 타입비교를 통해 배치시킬수 있다.
+ - 갠적으로 for문보다는 forEach문이 더 간결해 보여 좋을거 같습니다. 복사보다는 그대로 출력시키는게 좋아보입니다.
+
+## 객체 state 업데이트
+- state는 객체를 포함해서 어떠한 js값이든 저장할수 있는데!
+ - state에 있는 객체를 직접 변이(mutation)해서는 안됩니다.
+ - 대신 객체를 업데이트하려면 새 객체를 생성또는 복사를 통해 state를 업데이트 해야합니다.**중요**
+- js객체의 값에는 number,boolean,string,symbol,null,undefined의 기본값이 있는데 이러한 종류의 값은 읽기전용의 값입니다.
+ - 하지만 렌더링을 촉발하여? 값을 바꿀수 있습니다(업데이트? 복사?)
+
+```jsx
+const [x, setX) = useState(0);
+
+setX(5);
+//위와 같이 선언된 x의 값이 0에서 5로 변경은 되었지만 0(디폴트여서 인지? 예약어라서?)자체는 변경되지 않습니다.
+
+const [position,setposition] = useState({x:0,y:0});
+
+position.x = 5; // 이건 변이! 왜냐 초기값을 변경하기 때문에 //순수성을 지켜야 한다.
+```
+```js
+import { useState } from 'react';
+export default function MovingDot() {
+ const [position, setPosition] = useState({
+ x: 0,
+ y: 0
+ });
+ return (
+
+ );
+}
+//필터를 사용하여 0이상인 count값만 렌더링한다.
+```
\ No newline at end of file
diff --git "a/07\355\232\214/\354\235\264\353\217\204\355\230\204/README.md" "b/07\355\232\214/\354\235\264\353\217\204\355\230\204/README.md"
new file mode 100644
index 0000000..e3f68bd
--- /dev/null
+++ "b/07\355\232\214/\354\235\264\353\217\204\355\230\204/README.md"
@@ -0,0 +1,276 @@
+[7화] UI표현하기 ~ 상호작용 더하기 전반부
+
+### 이펙트가 필요하지 않을수 있습니다.
+
+#### ✅ 불필요한 Effect 처리
+1. 렌더링을 위해 데이터를 변환하는 경우
+ - popst나 useState에 따라 바뀌는 state에서 계산할수 있는 값은 state에 넣지 말고
+ - 대신 랜더링 중에 계산하세요
+- 간단한 계산
+-
+```js
+function Form() {
+ const [firstName, setFirstName] = useState('Taylor');
+ const [lastName, setLastName] = useState('Swift');
+
+ // 🔴 이러지 마세요: 중복 state 및 불필요한 Effect
+ const [fullName, setFullName] = useState('');
+ useEffect(() => {
+ setFullName(firstName + ' ' + lastName);
+ }, [firstName, lastName]);
+ // ...
+ //대신
+ // ✅ 좋습니다: 렌더링 과정 중에 계산
+ const fullName = firstName + ' ' + lastName;
+}
+```
+- 복잡한 계산?
+```js
+function TodoList({ todos, filter }) {
+ const [newTodo, setNewTodo] = useState('');
+ // ✅ getFilteredTodos()가 느리지 않다면 괜찮습니다.
+ const visibleTodos = getFilteredTodos(todos, filter);
+}
+// 하지만 이 getfilteredTodes함수가 느리거나 갖고있는 값이 많을경우 캐싱화를 생각해보자
+```
+```js
+import { useMemo, useState } from 'react';
+
+function TodoList({ todos, filter }) {
+ const [newTodo, setNewTodo] = useState('');
+ const visibleTodos = useMemo(() => {
+ // ✅ todos나 filter가 변하지 않는 한 재실행되지 않음
+ // memo는 다음렌더링때도 값을 가지고 있기 때문에(캐시에 저장)
+ // 의존성에 속한 값이 변할경우에만 실행이 됩니다! 그외는 기존에 저장된 데이터를 활용해요
+ return getFilteredTodos(todos, filter);
+ }, [todos, filter]);
+ // Or 한줄로 표현하면
+ const visibleTodos = useMemo(() =>
+ getFilteredTodos(todos, filter), [todos, filter]);
+}
+```
+- 하지만 이 방법은 전체시간이 1ms이상이라면 memo를 사용하는 것을 고려해봐요
+- 왜냐면 memo는 첫렌더링시 기록단축에 도움이 되지 않고 재렌더링 시에만 도움이 되기 때문이에요
+-
+#### ✅ prop이 변경되면 모든 state재설정 하기
+```js
+export default function ProfilePage({ userId }) {
+ const [comment, setComment] = useState('');
+
+ // 🔴 이러지 마세요: prop 변경시 Effect에서 state 재설정 수행
+ useEffect(() => {
+ setComment('');
+ }, [userId]);
+ // ...
+}
+// 이것은 ProfilePage와 그 자식들이 먼저 오래된 값으로 렌더링한 다음 새로운 값으로 다시 렌더링하기 때문에 비효율적입니다.
+//또 state가 있는 모든 컴포넌트에서 이 작업을 수행해야 하므로 복잡하죠!
+
+```
+- 그 대신 key를 전달하여 정확한 자식 컴포넌트에게 전달할수 있습니다.
+```js
+export default function ProfilePage({ userId }) {
+ return (
+
+ );
+}
+
+function Profile({ userId }) {
+ // ✅ This and any other state below will reset on key change automatically
+ // ✅ key가 변하면 이 컴포넌트 및 모든 자식 컴포넌트의 state가 자동으로 재설정됨
+ const [comment, setComment] = useState('');
+ // ...
+}
+```
+#### ✅ props가 변경될때 일부 state 조정하기
+- 하지만 이러한 경우보다는 렌더링 과정에서 계산을 하는것이 좋습니다.
+- 굳이 한다면 key로 모든 state를 재설정하거나 렌더링중 모두 계산할수 있는지 고려해보자
+- 그렇지 않고 써야 한다면 무한루프를 어떻게 해결할건지(조건식으로던지?) 고려하고 써야한다.
+- 일부 or 전체의 state및 props 조정은 할수 있겠지만 컴포넌트의 순수성을 유지하는것이 좋으므로 지양하는것이 좋은데ㅎㅎ;; 고려만이라도 해보자
+
+#### 이벤트 핸들러간 로직 공유
+- Effect안에 특정 이벤트 로직 존재
+- 이런경우 페이지를 새로고침할때마다 effect가 실행되기 때문에 Effect내부가 아닌
+컴포넌트를 따로 빼서 사용자에게 필요한 경우에만 사용되도록 사용해야 합니다.
+```js
+function ProductPage({ product, addToCart }) {
+ // 🔴 이러지 마세요: Effect 내부에 특정 이벤트에 대한 로직 존재
+ useEffect(() => {
+ if (product.isInCart) {
+ showNotification(`Added ${product.name} to the shopping cart!`);
+ }
+ }, [product]);
+
+ function handleBuyClick() {
+ addToCart(product);
+ }
+
+ function handleCheckoutClick() {
+ addToCart(product);
+ navigateTo('/checkout');
+ }
+ // ...
+}
+function ProductPage({ product, addToCart }) {
+ // ✅ 좋습니다: 이벤트 핸들러 안에서 각 이벤트별 로직 호출
+ function buyProduct() {
+ addToCart(product);
+ showNotification(`Added ${product.name} to the shopping cart!`);
+ }
+
+ function handleBuyClick() {
+ buyProduct();
+ }
+
+ function handleCheckoutClick() {
+ buyProduct();
+ navigateTo('/checkout');
+ }
+
+ //이렇게 하면 새로고침할때마다 가 아닌 필요한 경우에만 알람을 띄울수 있습니다.
+}
+```
+#### POST요청 보내기
+
+- 버튼을 눌르는 post요청도 마찬가지로 제출을 클릭하였을때 요청을 보내므로
+이벤트행핸들러를 사용하여 코드문을 작성합니다.
+
+#### 연쇄 계산
+- 이 경우는 state값에 따라서 또 다른 state값을 조정하고 싶을때가 있는데 이경우도 effect가 아닌
+이벤트 헨들러에서 적용하는것이 좋습니다.
+ - 또 비효율적입니다. 간단한 계산같은 경우 체인의 각 값의 호출 사이에 렌더링을 다시 해야하기 때문에 비효율 적이죠!
+ - 공식문서의 코드문경우엔 무려 3번이나 렌더링을 해야죠
+- 하지만 드롭다운의 선택값의 따라 다음 드롭다운의 옵션이 달라지는 form을 작성한다 했을때!
+이는 effect체인이 적절해 보입니다. 왜냐 선택되는 값에 따라 결과가 달리지기 때문이죠
+
+#### 어플리케이션 초기화 하기
+- 일부 로직은 앱이 로드될때 한번만 실행되어야 할때도 있는데 그경우엔 Effect가 아닌 최상위 변수로 선언을 사용해보죠
+- Effect로 최상위 컴포넌트에 배치할 경우 개발중에는 두번 실행되는것을 확인할수 있습니다.
+- 두번 실행될경우 예기치 못한 토큰무효화 라든지의 문제가 발생할수 있기 때문에 지양합시다
+- 하지만 prd환경같은 경우엔 1번 실행되어 다시 마운트 되지 않을수도 있지만 그래도! 동일한 제약조건을 따르면 코드를 이용하고 재사용하기 편하기 때문에 사용하지 말죠!
+ - window변수의 경우엔 nextjs를 다루는 환경에서는 다르니 사용에 주의하죠
+
+
+#### state변경을 부모컴포넌트에 알리기
+```js
+function Toggle({ onChange }) {
+ const [isOn, setIsOn] = useState(false);
+
+ // 🔴 Avoid: The onChange handler runs too late
+ // 🔴 이러지 마세요: onChange 핸들러가 너무 늦게 실행됨
+ useEffect(() => {
+ onChange(isOn);
+ }, [isOn, onChange])
+
+ function handleClick() {
+ setIsOn(!isOn);
+ }
+
+ function handleDragEnd(e) {
+ if (isCloserToRightEdge(e)) {
+ setIsOn(true);
+ } else {
+ setIsOn(false);
+ }
+ }
+
+
+}
+```
+- 이 경우엔 사용자의 동작(클릭,드래그)에 의해서 이뤄지는 코드문이기에 Effect는 맞지 않습니다.또 늦습니다.
+- 그래서 각 코드들은 이벤트 핸들러에서 작성합시다.
+
+```js
+function Toggle({ isOn, onChange }) {
+ function handleClick() {
+ onChange(!isOn);
+ }
+
+ function handleDragEnd(e) {
+ if (isCloserToRightEdge(e)) {
+ onChange(true);
+ } else {
+ onChange(false);
+ }
+ }
+
+ // 이렇게 ison과 onchange를 같이 관리하여 손쉽게 코드문을 이해할수 있게 해줄수도 있습니다.
+}
+```
+#### 부모에게 데이터 전달하기
+- 이경우엔 부모 -> 자식 으로 데이터흐름이 이어지고 있는데 자식에서 데이터를 페치하지말고 미리 부모에서 해당 데이터를 패치하고 전달하도록 하면
+- 데이터흐름이 깔끔해지고 정보의 출처도 한눈에 알아볼수 있다 (자식꺼는 이리저리 찾아봐야 하니까! 자식은 전달만 받자!)
+
+#### 외부 스토어 구독하기
+- 외부에서 가져오는 데이터api의 경우 react가 모르는 사이 변경될수 있는데 그럴땐 컴포넌트에서 수동으로 데이터를 구독하도록 해야합니다.
+```js
+function useOnlineStatus() {
+ // Not ideal: Manual store subscription in an Effect
+ // 이상적이지 않음: Effect에서 수동으로 store 구독
+ const [isOnline, setIsOnline] = useState(true);
+ useEffect(() => {
+ function updateState() {
+ setIsOnline(navigator.onLine);
+ }
+
+ updateState();
+
+ window.addEventListener('online', updateState);
+ window.addEventListener('offline', updateState);
+ return () => {
+ window.removeEventListener('online', updateState);
+ window.removeEventListener('offline', updateState);
+ };
+ }, []);
+ return isOnline;
+}
+
+function ChatIndicator() {
+ const isOnline = useOnlineStatus();
+ // ...
+}
+```
+- 이 경우엔 윈도우가 online일 경우에 값을 저장하라 라는 코드문인데 useEffect로 하기보다는 react에서 제공하는 훅인 useSyncExternalStore이걸 사용하자
+- 요것은 훅을 공부할때 더 자세히 해보자
+
+#### 데이터 패칭하기
+
+```js
+function SearchResults({ query }) {
+ const [results, setResults] = useState([]);
+ const [page, setPage] = useState(1);
+
+ useEffect(() => {
+ // 🔴 이러지 마세요: 클린업 없이 fetch 수행
+ fetchResults(query, page).then(json => {
+ setResults(json);
+ });
+ }, [query, page]);
+
+ function handleNextPageClick() {
+ setPage(page + 1);
+ }
+ // ...
+}
+```
+- 이 경우 페이징의 값에따라 변경되는 페칭과 query에대한 패칭은 ?? 을 나타내는 구문입니다.
+- 하지만 클린업이 없다는 점이 잘못된 점입니다.
+- 그래서 ignore문을 넣어(클린없) 해결해보죠
+- 클린업을 하는 이유는 더이상 관련없는 페치가 앱에 계속 영향을 미치지 않아야 하기 때문이죠!! effect와 동기화 하기 참조!!
+
+*경쟁상태*
+- 요건 서로 다른 요청이 서로 영향을 미치는 것을 의미합니다. 패치에서는 패칭으로 불러온 값이 계속 남아있어 앱에 영향을 주는 것을 의미할수 도 있죠
+
+## 정리
+
+1. 렌더링중에 계산은 effect가 필요 x
+2. 비용이 많이 드는(시간이 소요되는) 계산을 저장하려면 usememo하자
+3. 전체 컴포넌트의 state변경은 key를 넣어 정확하게 수행하자
+4. 컴포넌트에 표시되는 코드는 effect 나머지는 이벤트핸들러!!!
+5. 자식컴포넌트에서 데이터를 발생시키는게 아닌 부모에서 데이터를 발생시켜 자식한테 주자
+6. 부모컴포넌트에서 state를 끌어올리면 부모컴포넌트에서 더 많은 로직을 포함해야 하지만 전체적으로 걱정할 state가 줄어든다!
+ - 서로다른 state를 동기화 하려면 부모쪽에서 끌어올리기를 해보자
+7. effect에서 데이터를 fetch할수 있지만 경쟁조건을 피하기 위해 클립업(ignore)를 구현해야죠
\ No newline at end of file
diff --git "a/12\355\232\214/\353\217\204\355\230\204.md" "b/12\355\232\214/\353\217\204\355\230\204.md"
new file mode 100644
index 0000000..6940afe
--- /dev/null
+++ "b/12\355\232\214/\353\217\204\355\230\204.md"
@@ -0,0 +1,34 @@
+<12회차 useMemo>
+
+- 컴포넌트 최상단에서 useMemo를 호출하여 리렌더링사이의 계산을 캐싱합니다.
+```js
+ import { useMemo } from 'react';
+
+function TodoList({ todos, tab }) {
+const visibleTodos = useMemo(
+() => filterTodos(todos, tab),
+[todos, tab]
+);
+// ...
+}
+```
+- 매개변수는 2개의 인자가 있다
+ 1. calculateValue
+ - 캐시하려는 값을 계산하는 함수입니다.이 함수는 순수해야 하며 ,인자를 받지않고 값을 반환해야합니다.
+ - 초기렌더링중 함수를 호출하는데 ,이후 렌더링에서는 의존성이 변경되지 않았다면 동일한 값을 반환합니다. 그렇지 않으면 함수를 호출하고 나중에 재사용할수있도록 저장합니다.
+ 2. dependencies
+ - calculateValue 코드 내에서 참조되는 모든 반응형 값들의 목록입니다.
+ - 값에는 모든 변수와 함수가 포함되어야 합니다.(배열형식으로)
+-
+
+
+
+
+상위 useMemo + 하위 memo를 함께 써야만 리렌더링을 하지 않는가?
+
+상위 useMemo는 데이터 일부 (todos,tab의 의존성에 따른 visibleTodos)에 대해서만 메모화
+그 밖의 데이터들(theme)의 변경에 대해서는 어차피 리렌더링을 피하지 못함.
+
+하위컴포넌트가 리렌더링을 피하는 방법은 momo를 해야만 한다.
+상위는 useMemo를 써야하는 경우도 있고 그렇지 않은 경우도 있을수 있다.
+useMemo + memo
\ No newline at end of file