diff --git "a/\352\271\200\354\235\264\354\202\255/1\354\243\274\354\260\250/README.md" "b/\352\271\200\354\235\264\354\202\255/1\354\243\274\354\260\250/README.md" index ff9aae1..05a4353 100644 --- "a/\352\271\200\354\235\264\354\202\255/1\354\243\274\354\260\250/README.md" +++ "b/\352\271\200\354\235\264\354\202\255/1\354\243\274\354\260\250/README.md" @@ -1,269 +1,269 @@ -# 리액트 공식문서 스터디 1주차 - UI 구성하기 - -- React 컴포넌트 만들기 -- 사용자 정의하기 -- 조건부 표시 방법 알아보기 - -## 첫번째 컴포넌트 -- React를 사용하면 markup, CSS, JavaScipt를 앱의 **재사용 가능한 UI요소인 사용자 정의** `컴포넌트`로 결합할 수 있다. -- **React 컴포넌트: 마크업으로 뿌릴 수 있는 JavaScript** -- HTML태그와 같이 컴포넌트를 작성, 순서 지정 및 중첩해 전체 페이지를 디자인할 수 있다. - - ```jsx - export default function Profile() { - return ( - Katherine Johnson - ); - } -### 컴포넌트를 빌드하는 방법 -1. 컴포넌트 내보내기: `export default`를 사용하면 나중에 다른 파일에서 가져올 수 있도록 파일에 주요기능을 표시할 수 있다. -2. 함수 정의하기: `function Profile(){}`을 사용하면 `Profile`이라는 이름의 함수를 정의할 수 있다. - - 컴포넌트의 이름은 대문자로 시작하는 것이 좋다! -3. 마크업 추가하기 - - 반환문은 한줄에 작성할 수 있다. 여러줄에 있을 경우 괄호`()`로 묶어야 한다. - - 괄호가 없을 경우 `return` 뒤 라인에 있는 모든 코드가 무시된다! -### 컴포넌트 사용하기 -```jsx -function Profile() { - return ( - Katherine Johnson - ); -} - -export default function Gallery() { - return ( -
-

Amazing scientists

- - - -
- ); -} -``` -- `Profile` 컴포넌트를 정의했으므로 여러 `Profile`을 사용하는 `Gallery` 컴포넌트를 내보낼 수 있다. -### React에서의 대소문자 차이 -- 소문자로 시작할 경우: HIML 태그를 가르킨다고 이해 -- 대문자로 시작할 경우: 컴포넌트를 사용하고자 한다고 이해 -### 컴포넌트 중첩 및 구성 -- 같은 파일에 여러 컴포넌트 포함 가능 -> 복잡해지면 별도의 파일로 옮길 수 있음 -- 위 코드의 경우 `Profile` 컴포넌트는 `Gallery`에 렌더링 - - *`Gallery`는 `Profile`을 자식으로 렌더링하는 부모 컴포넌트!* -- 하지만 컴포넌트 정의가 중첩될 경우 버그가 유발된다. -- 자식 컴포넌트에서 부모 컴포넌트의 데이터 일부가 필요한 경우 **props**로 전달하기 - -## 컴포넌트 import 및 export -- 컴포넌트의 가장 큰 장점: `재사용성`, 컴포넌트를 조합해 또 다른 컴포넌트를 만들 수 있다! -- 컴포넌트를 파일로 분리하면 더 쉽게 찾을 수 있고 재사용하기 편리해짐 -### 루트 컴포넌트 -- 컴포넌트는 `App.js`라는 **root 컴포넌트 파일**에 존재 -### 컴포넌트 import 및 export -- 기능별 컴포넌트를 root컴포넌트 밖으로 옮기면 모듈성이 강화되고 다른 파일에서 재사용할 수 있게 된다. -- 컴포넌트를 이동하는 방법 - 1. 컴포넌트를 넣을 JS파일 생성하기 - 2. 새로 만든 파일에 컴포넌트 `export`하기 - - default or named export 방식 사용 - 3. 컴포넌트를 사용할 파일에서 `import`하기 - - default or named export에 대응하는 방식으로 import -### 동일한 파일에서 여러 컴포넌트 import & export하기 -- 하나의 파일에서 default export를 하나만 가질 수 있지만 named export는 여러 개 가질 수 있다. -```jsx -//Gallery.js -export function Profile() { - // named export 방식으로 Gallery.js에서 Profile를 export - return ( - Alan L. Hart - ); -} -``` - -```jsx -// App.js -import Gallery form './Gallery.js'; -import { Profile } from './Gallery.js'; -// named import방식으로 Gallery.js에서 Profile를 App.js 파일로 import -export default function App() { - return ( - - ); -} -``` -## JSX로 마크업 작성하기 -- JSX는 JavaScript를 확장한 문법! JavaScript 파일 안에 HTML과 유사한 마크업 작성을 할 수 있게 한다. -### JSX: JavaScript에 마크업 넣기 -- 웹은 보통 각각 분리된 파일로 관리, 페이지 로직이 JS에서 분리되어 작동하는 동안 HTML안에서는 콘텐츠가 마크업 된다. -- 웹이 인터랙티브해짐 -> 로직의 컨텐츠 결정 경우 증가 -- 리액트에서 **렌더링 로직과 마크업이 같은 위치의 컴포넌트에 함께 있는 이유** - - 모든 편집에서 서로 동기화 상태를 유지할 수 있다. -- JSX는 HTML과 비슷해보이지만 더 엄격하며, 동적으로 정보를 표시한다. - - HTML 마크업을 JSX 마크업으로 변환해보자! -- NOTE: - - JSX: 구문확장 - - React: JS 라이브러리 -### HTML을 JSX로 변환하기 -```html -

Hedy Lamarr's Todos

-Hedy Lamarr - -``` -- 유효한 HTML 코드 -- 하지만 .js파일로 저장하면 오류남 - - JSX는 HTML보다 엄격하고 규칙이 더 있기 때문! -- 대부분의 경우 React 화면 오류 메세지는 문제해결에 도움이 된다! -### JSX 규칙 -1. 단일 루트 엘리먼트 반환하기 - - 하나의 `부모태그`로 감싸주기 - - ex) div 태그 사용하기 - - 또는 빈 태그도 가능(= Fragment: HTML트리구조에 흔적 남기지 않고 그룹화 해준다.) -2. 모든 태그 닫기 -3. 대부분이 카멜 케이스! - - 예약어는 사용할 수 없다. - - 소문자로 시작해 합성어 시작은 대문자로 적기 -- Tip: JSX 변환기를 사용하는 것도 추천! -## JSX에서 JavaScript 사용하기 -- 마크업 내에 동적 프로퍼티 참조하고 싶을 때: JSX에서 중괄호 사용해 JS창으로 열 수 있다! -### 따옴표로 문자열 전달하기 -```jsx -export default function Avatar() { - return ( - Gregorio Y. Zara - ); -} -``` -- "https://i.imgur.com/7vQD0fPs.jpg" 및 "Gregorio Y. Zara"는 문자열로 전달됨 -```jsx -export default function Avatar() { - const avatar = 'https://i.imgur.com/7vQD0fPs.jpg'; - const description = 'Gregorio Y. Zara'; - return ( - {description} - ); -} -``` -- src와 alt가 동적으로 지정됨 -- `""`을 `{}`로 대체 -### 중괄호 사용하기 -- `{}`안에서 js사용할 수 있다. -```jsx -export default function TodoList() { - const name = 'Gregorio Y. Zara'; - return ( -

{name}'s To Do List

- ); -} -``` -### 중괄호 사용위치 -1. JSX 태그안에 직접 텍스트로 사용 -2. `=`기호 바로 뒤에 오는 속성 -### "이중 중괄호 사용: JSX 내에서의 CSS 및 다른 객체 -- JSX내에서 JS객체를 전달하려면 `다른 중괄호쌍`으로 객체를 감싸야 한다. -- JSX에서 `{{`와 `}}` 볼 때 JSX 중괄호 내부의 객체일 뿐이라는 점 기억하기!, 특별한 구문 아님 -## 컴포넌트에 props 전달하기 -- React 컴포넌트는 props를 이용해 서로 통신 -- **props: JSX 태그에 전달하는 정보**, properties의 줄임말 -- 부모 컴포넌트는 props를 줌으로써 자식 컴포넌트에게 일부 정보를 전달할 수 있음 -- 객체, 배열, 함수 포함한 모든 JS값 전달 가능 -```jsx -function Avatar() { - return ( - Lin Lanying - ); -} - -export default function Profile() { - return ( - - ); -} -``` -- className, src, alt, width, height 는 태그에 전달할 수 있다. -### 컴포넌트에 props 전달하기 -1. 자식 컴포넌트에 props 전달하기 -```jsx -export default function Profile() { - return ( - - ); -} -``` -- 이제 `Avatar` 컴포넌트 내 props를 읽을 수 있게 됨. -2. 자식 컴포넌트 내부에서 props 읽기 -```jsx -function Avatar({ person, size }) { - return ( - {person.name} - ); -} -``` -- `props`를 사용하면 부모와 자식 컴포넌트를 독립적으로 생각할 수 있다. -- props는 `함수의 인수와 동일한 역할`을 한다. - - 컴포넌트에 대한 유일한 인자!, React 컴포넌트 함수는 하나의 인자 -props 객체를 받는다. -- 보통은 전체 props를 필요로 하진 않아 개별 props로 구조분해한다. -### 구조 분해 할당 -: props를 선언할 때 `()`안에 `{}`쌍을 넣는 것 -```jsx -function Avatar(props) { - let person = props.person; - let size = props.size; - // ... -} -``` -### props의 기본값 지정하기 -- 값이 지정되지 않았을 때 기본값을 주길 원한다면 변수 바로 뒤에 `=`와 `기본값`을 넣어 `구조 분해 할당`을 해줄 수 있다. -```jsx -function Avatar({ person, size = 100 }) { - // ... -} -``` -- size가 prop없이 렌더링되면 기본값 100으로 설정된다. - - 기본값은 `size prop이 없거나 size={undefined} 로 전달될 때` 사용! -### JSX 전개구문으로 props 전달하기 -- 반복적인 props의 간결함을 높이기 위해 전개구문을 사용한다. -- 전개 구문은 `제한적으로 사용할 것!` - - 모든 컴포넌트에 전개구문이 사용되는 것은 문제가 있다.. 컴포넌트를 분할해 `자식을 JSX로 전달할 것.` - -### 자식을 JSX로 전달하기 -### 시간에 따라 props가 변하는 방식 -## 조건부 렌더링 -## 목록 렌더링 -## 컴포넌트 순수성 유지 +# 리액트 공식문서 스터디 1주차 - UI 구성하기 + +- React 컴포넌트 만들기 +- 사용자 정의하기 +- 조건부 표시 방법 알아보기 + +## 첫번째 컴포넌트 +- React를 사용하면 markup, CSS, JavaScipt를 앱의 **재사용 가능한 UI요소인 사용자 정의** `컴포넌트`로 결합할 수 있다. +- **React 컴포넌트: 마크업으로 뿌릴 수 있는 JavaScript** +- HTML태그와 같이 컴포넌트를 작성, 순서 지정 및 중첩해 전체 페이지를 디자인할 수 있다. + + ```jsx + export default function Profile() { + return ( + Katherine Johnson + ); + } +### 컴포넌트를 빌드하는 방법 +1. 컴포넌트 내보내기: `export default`를 사용하면 나중에 다른 파일에서 가져올 수 있도록 파일에 주요기능을 표시할 수 있다. +2. 함수 정의하기: `function Profile(){}`을 사용하면 `Profile`이라는 이름의 함수를 정의할 수 있다. + - 컴포넌트의 이름은 대문자로 시작하는 것이 좋다! +3. 마크업 추가하기 + - 반환문은 한줄에 작성할 수 있다. 여러줄에 있을 경우 괄호`()`로 묶어야 한다. + - 괄호가 없을 경우 `return` 뒤 라인에 있는 모든 코드가 무시된다! +### 컴포넌트 사용하기 +```jsx +function Profile() { + return ( + Katherine Johnson + ); +} + +export default function Gallery() { + return ( +
+

Amazing scientists

+ + + +
+ ); +} +``` +- `Profile` 컴포넌트를 정의했으므로 여러 `Profile`을 사용하는 `Gallery` 컴포넌트를 내보낼 수 있다. +### React에서의 대소문자 차이 +- 소문자로 시작할 경우: HIML 태그를 가르킨다고 이해 +- 대문자로 시작할 경우: 컴포넌트를 사용하고자 한다고 이해 +### 컴포넌트 중첩 및 구성 +- 같은 파일에 여러 컴포넌트 포함 가능 -> 복잡해지면 별도의 파일로 옮길 수 있음 +- 위 코드의 경우 `Profile` 컴포넌트는 `Gallery`에 렌더링 + - *`Gallery`는 `Profile`을 자식으로 렌더링하는 부모 컴포넌트!* +- 하지만 컴포넌트 정의가 중첩될 경우 버그가 유발된다. +- 자식 컴포넌트에서 부모 컴포넌트의 데이터 일부가 필요한 경우 **props**로 전달하기 + +## 컴포넌트 import 및 export +- 컴포넌트의 가장 큰 장점: `재사용성`, 컴포넌트를 조합해 또 다른 컴포넌트를 만들 수 있다! +- 컴포넌트를 파일로 분리하면 더 쉽게 찾을 수 있고 재사용하기 편리해짐 +### 루트 컴포넌트 +- 컴포넌트는 `App.js`라는 **root 컴포넌트 파일**에 존재 +### 컴포넌트 import 및 export +- 기능별 컴포넌트를 root컴포넌트 밖으로 옮기면 모듈성이 강화되고 다른 파일에서 재사용할 수 있게 된다. +- 컴포넌트를 이동하는 방법 + 1. 컴포넌트를 넣을 JS파일 생성하기 + 2. 새로 만든 파일에 컴포넌트 `export`하기 + - default or named export 방식 사용 + 3. 컴포넌트를 사용할 파일에서 `import`하기 + - default or named export에 대응하는 방식으로 import +### 동일한 파일에서 여러 컴포넌트 import & export하기 +- 하나의 파일에서 default export를 하나만 가질 수 있지만 named export는 여러 개 가질 수 있다. +```jsx +//Gallery.js +export function Profile() { + // named export 방식으로 Gallery.js에서 Profile를 export + return ( + Alan L. Hart + ); +} +``` + +```jsx +// App.js +import Gallery form './Gallery.js'; +import { Profile } from './Gallery.js'; +// named import방식으로 Gallery.js에서 Profile를 App.js 파일로 import +export default function App() { + return ( + + ); +} +``` +## JSX로 마크업 작성하기 +- JSX는 JavaScript를 확장한 문법! JavaScript 파일 안에 HTML과 유사한 마크업 작성을 할 수 있게 한다. +### JSX: JavaScript에 마크업 넣기 +- 웹은 보통 각각 분리된 파일로 관리, 페이지 로직이 JS에서 분리되어 작동하는 동안 HTML안에서는 콘텐츠가 마크업 된다. +- 웹이 인터랙티브해짐 -> 로직의 컨텐츠 결정 경우 증가 +- 리액트에서 **렌더링 로직과 마크업이 같은 위치의 컴포넌트에 함께 있는 이유** + - 모든 편집에서 서로 동기화 상태를 유지할 수 있다. +- JSX는 HTML과 비슷해보이지만 더 엄격하며, 동적으로 정보를 표시한다. + - HTML 마크업을 JSX 마크업으로 변환해보자! +- NOTE: + - JSX: 구문확장 + - React: JS 라이브러리 +### HTML을 JSX로 변환하기 +```html +

Hedy Lamarr's Todos

+Hedy Lamarr +
    +
  • Invent new traffic lights +
  • Rehearse a movie scene +
  • Improve the spectrum technology +
+``` +- 유효한 HTML 코드 +- 하지만 .js파일로 저장하면 오류남 + - JSX는 HTML보다 엄격하고 규칙이 더 있기 때문! +- 대부분의 경우 React 화면 오류 메세지는 문제해결에 도움이 된다! +### JSX 규칙 +1. 단일 루트 엘리먼트 반환하기 + - 하나의 `부모태그`로 감싸주기 + - ex) div 태그 사용하기 + - 또는 빈 태그도 가능(= Fragment: HTML트리구조에 흔적 남기지 않고 그룹화 해준다.) +2. 모든 태그 닫기 +3. 대부분이 카멜 케이스! + - 예약어는 사용할 수 없다. + - 소문자로 시작해 합성어 시작은 대문자로 적기 +- Tip: JSX 변환기를 사용하는 것도 추천! +## JSX에서 JavaScript 사용하기 +- 마크업 내에 동적 프로퍼티 참조하고 싶을 때: JSX에서 중괄호 사용해 JS창으로 열 수 있다! +### 따옴표로 문자열 전달하기 +```jsx +export default function Avatar() { + return ( + Gregorio Y. Zara + ); +} +``` +- "https://i.imgur.com/7vQD0fPs.jpg" 및 "Gregorio Y. Zara"는 문자열로 전달됨 +```jsx +export default function Avatar() { + const avatar = 'https://i.imgur.com/7vQD0fPs.jpg'; + const description = 'Gregorio Y. Zara'; + return ( + {description} + ); +} +``` +- src와 alt가 동적으로 지정됨 +- `""`을 `{}`로 대체 +### 중괄호 사용하기 +- `{}`안에서 js사용할 수 있다. +```jsx +export default function TodoList() { + const name = 'Gregorio Y. Zara'; + return ( +

{name}'s To Do List

+ ); +} +``` +### 중괄호 사용위치 +1. JSX 태그안에 직접 텍스트로 사용 +2. `=`기호 바로 뒤에 오는 속성 +### "이중 중괄호 사용: JSX 내에서의 CSS 및 다른 객체 +- JSX내에서 JS객체를 전달하려면 `다른 중괄호쌍`으로 객체를 감싸야 한다. +- JSX에서 `{{`와 `}}` 볼 때 JSX 중괄호 내부의 객체일 뿐이라는 점 기억하기!, 특별한 구문 아님 +## 컴포넌트에 props 전달하기 +- React 컴포넌트는 props를 이용해 서로 통신 +- **props: JSX 태그에 전달하는 정보**, properties의 줄임말 +- 부모 컴포넌트는 props를 줌으로써 자식 컴포넌트에게 일부 정보를 전달할 수 있음 +- 객체, 배열, 함수 포함한 모든 JS값 전달 가능 +```jsx +function Avatar() { + return ( + Lin Lanying + ); +} + +export default function Profile() { + return ( + + ); +} +``` +- className, src, alt, width, height 는 태그에 전달할 수 있다. +### 컴포넌트에 props 전달하기 +1. 자식 컴포넌트에 props 전달하기 +```jsx +export default function Profile() { + return ( + + ); +} +``` +- 이제 `Avatar` 컴포넌트 내 props를 읽을 수 있게 됨. +2. 자식 컴포넌트 내부에서 props 읽기 +```jsx +function Avatar({ person, size }) { + return ( + {person.name} + ); +} +``` +- `props`를 사용하면 부모와 자식 컴포넌트를 독립적으로 생각할 수 있다. +- props는 `함수의 인수와 동일한 역할`을 한다. + - 컴포넌트에 대한 유일한 인자!, React 컴포넌트 함수는 하나의 인자 -props 객체를 받는다. +- 보통은 전체 props를 필요로 하진 않아 개별 props로 구조분해한다. +### 구조 분해 할당 +: props를 선언할 때 `()`안에 `{}`쌍을 넣는 것 +```jsx +function Avatar(props) { + let person = props.person; + let size = props.size; + // ... +} +``` +### props의 기본값 지정하기 +- 값이 지정되지 않았을 때 기본값을 주길 원한다면 변수 바로 뒤에 `=`와 `기본값`을 넣어 `구조 분해 할당`을 해줄 수 있다. +```jsx +function Avatar({ person, size = 100 }) { + // ... +} +``` +- size가 prop없이 렌더링되면 기본값 100으로 설정된다. + - 기본값은 `size prop이 없거나 size={undefined} 로 전달될 때` 사용! +### JSX 전개구문으로 props 전달하기 +- 반복적인 props의 간결함을 높이기 위해 전개구문을 사용한다. +- 전개 구문은 `제한적으로 사용할 것!` + - 모든 컴포넌트에 전개구문이 사용되는 것은 문제가 있다.. 컴포넌트를 분할해 `자식을 JSX로 전달할 것.` + +### 자식을 JSX로 전달하기 +### 시간에 따라 props가 변하는 방식 +## 조건부 렌더링 +## 목록 렌더링 +## 컴포넌트 순수성 유지 \ No newline at end of file diff --git "a/\352\271\200\354\235\264\354\202\255/2\354\243\274\354\260\250/README.md" "b/\352\271\200\354\235\264\354\202\255/2\354\243\274\354\260\250/README.md" new file mode 100644 index 0000000..6eb72a2 --- /dev/null +++ "b/\352\271\200\354\235\264\354\202\255/2\354\243\274\354\260\250/README.md" @@ -0,0 +1,89 @@ +# 리액트 공식문서 스터디 2주차 + +## 상호작용 추가하기 + +- `state` 시간이 지남에 따라 변하는 데이터 + - 모든 컴포넌트에 추가하고 업데이트할 수 있다 + - `useState` 훅 사용하기 - 특수함수, state변수를 선언할 수 있다 + - = 리액트에게 컴포넌트가 무언가 기억하기를 원한다고 말하기 + +### 이벤트에 응답하기 + +- 이벤트 핸들러 함수는 컴포넌트 안에 정의 +- `handle`로 시작하는 이름 뒤에 이벤트 이름이 오도록 +- 인라인 (함수 짧을 때 편리) or 화살표 함수 사용 +- 이벤트 핸들러 props는 `on`으로 시작, 뒤에 대문자 +- 이벤트 핸들러는 이벤트 객체를 유일한 인수로 받는다 `e` + +### State: 컴포넌트의 메모리 + +- state: 기억하는 컴포넌트별 메모리 +- *지역 변수는 렌더링 간에 유지되지 않음 → 렌더링 사이에 데이터유지 필요 +- useState 훅을 사용해 state변수 선언하고, 리액트가 컴포넌트를 다시 렌더링 할 수 있도록 촉발시키기(state 설정자 함수) +- hook: use로 시작하는 함수, 렌더링 중일 때만 사용할 수 있다 +- state는 컴포넌트 인스턴스에 지역적, 각 사본은 격리된 상태, 부모컴포넌트도 변경할 수 X, 비공개 + +### 랜더링하고 커밋하기 + +- 컴포넌트들은 React에서 렌더링한 뒤 화면에 표시 +1. 렌더링 발동(촉발) +- 첫 렌더링 때, state가 업데이트될 때(리렌더링) +1. 컴포넌트 렌더링 +- 렌더링: 리액트에서 컴포넌트를 호출하는 것 +- 첫 렌더링: 루트 컴포넌트 호출 +- 이후 렌더링: 렌더링 발동된 함수 컴포넌트 호출(재귀적) +1. DOM에 커밋 +- 컴포넌트를 렌더링(호출)한 뒤 리액트는 DOM을 수정 + - 렌더링 결과가 전과 같으면 수정하지 않는다 +- strictmode 사용하면 컴포넌트의 실수를 찾을 수 있다 + +### 스냅샷으로서의 state + +- state 설정 → 새 렌더링 요청 +- JS 변수와 달리 React state는 스냅샷처럼 동작 +- 렌더링은 그 시점의 스냅샷! + - prop, 이벤트 핸들러, 로컬 변수는 모두 렌더링 당시의 state를 사용해 계산 +- 리렌더링 절차 + - 함수 다시 호출 + - 새로운 jsx 스냅샷 반환 + - 스냅샷과 일치하도록 화면 업데이트 +- 컴포넌트 외부에 state 저장 +- state 변수는 변경되지 않고 리렌더링된다. +- state 변수의 값은 렌더링 내에서 절대 변경되지 않는다(고정) +- 과거의 생성된 이벤트 핸들러는 그것이 생성된 렌더링 시점의 state 값 갖는다 + +### 여러 state업데이트를 큐에 담기 + +- state 변수 설정 → 다음 렌더링에 큐(대기열)에 들어감 +- 여러 작업을 시행하고 싶으면 state 업데이트 배치 고려하기 +- 리액트는 state 업데이트 하기 전에 이벤트 핸들러의 모든 코드가 실행될때까지 기다림 → 함수 호출이 완료된 이후에만 일어난다 +- 리액트는 이벤트 핸들러가 실행을 마친 후 state 업데이트를 처리 = 일괄배칭 +- 일괄처리(배칭)은 많은 리렌더링 없이도 리액트앱을 빠르게 실행할 수 있게 한다. + - 안전한 경우에만 일괄처리를 수행해, 클릭이 어려번 되어 중복된 양식이 제출되지 않도록 +- 이벤트 핸들러 완료→ 리렌더링 실행 → (업데이터 함수 실행)→ 큐 처리 + - 업데이터 함수는 순수해야 하고, 결과만 반환해야한다. + +### 객체 state 업데이트 + +- state는 객체를 포함해 어떤 종류의 js값 저장 가능 +- 객체 업데이트 위해서는 새로운 객체 생성 뒤, 해당 복사본 사용하도록 설정 +- 변이: 기술적으로 객체 자체의 내용을 변경하는 것 +- 하지만 state의 객체는 불변하는 것처럼 취급, 직접 변이하는 대신, 교체하기 +- ⇒ state에 넣는 모든 js 객체를 읽기 전용으로 취급하기 +- 객체 전개 구문을 사용하면 모든 속성을 개별적으로 복사할 필요 X + - 하지만 **************************얕은 구문**************************이므로 한단계 깊이만 복사 +- Immer의 draft: 프록시 유형의 객체, 기록하는 역할, 자유로운 수정 가능 + - lmmer는 내부적으로 변경 사항과 편집 내용이 포함된 새로운 객체 생성 + - state에 중첩이 있고, 코드 반복되는 경우 업데이트 핸들러를 간결하게 유지하는데 유용 + +### 배열 state 업데이트 + +- state 내에서 배열은 변경이 불가능해요 +- 객체와 같이 배열도 업데이트하려면 새 배열 만들어 사용하도록 state 설정 +- state 배열은 재할당 불가, 배열 변이 메서드 사용 불가 +- map(): 새로운 배열을 만들거나 배열의 일부 또는 모든 항목을 변경하기 위해 사용 +- `slice()` 매서드: 배열의 조각을 잘라내, 새 항목과 원래 배열을 펼치는 배열 생성 +- 배열을 복사해도 배열 내부의 기존 항목을 직접 변이할 수는 없다 +- 중첩된 state 업데이트 시 업데이트시점부터 최상위 시점까지 복사본 만들기 +- 변이는 방금 만든 객체만 가능 +- Immer를 사용해 반복적인 중첩배열을 효율적으로 사용하기 \ No newline at end of file diff --git "a/\352\271\200\354\235\264\354\202\255/3\354\243\274\354\260\250/README.md" "b/\352\271\200\354\235\264\354\202\255/3\354\243\274\354\260\250/README.md" new file mode 100644 index 0000000..37aebe8 --- /dev/null +++ "b/\352\271\200\354\235\264\354\202\255/3\354\243\274\354\260\250/README.md" @@ -0,0 +1,70 @@ +# 리액트 공식문서 스터디 3주차 + +## State 관리하기 + +1. state를 사용해 input 관리하기 +- 리액트는 선언적 방식으로 UI조작, 사용자의 입력에 따라 state를 변경한다. +- 컴포넌트의 다양한 시각적 state 확인하기 + - 모형을 만들며 로직을 연결하기 전에 UI에서 테스트 가능 +- 무엇이 state 변화를 유도하는지 알아내기 + - 휴먼 인풋 - 버튼 푸쉬, 필드 입력, 링크 이동 + - 컴퓨터 인풋 - 네트워크 응답, 타임아웃, 이미지 로딩 + - **UI를 업데이트 하기 위해서는 state 변수를 설정해야한다.** + - 휴먼 인풋은 이벤트 핸들러가 필요할 수도 있다! +- 메모리의 state를 `usestate`로 표현하기 + - state는 움직이는 조각과 같아서 적을수록 좋다 +- 불필요한 state 변수 제거하기 + - 리팩토링: 결과의 변경 없이 코드의 구조를 재조정하는 것 + - 리팩토링의 효과: 코드의 간결성을 높이고 불필요한 중복을 삭제한다 +- state설정을 위해 이벤트 핸들러 연결하기 + - 모든 인터랙션을 state로 표현하면 이후 시각적 state가 추가되어도 기존 로직 손상을 방지한다 +1. state 구조 선택하기 +- `state 구조화 원칙: 오류없이 상태를 쉽게 업데이트하기` + - 연관된 state 그룹화하기 - 단일 state 변수로 병합 고려하기 + - state의 모순 피하기 - 여러개의 state가 모순되는 방식으로 구성되면 실수 발생 여지 있음 + - 불필요한 state 피하기 - 계산이 있는 props나 state 변수는 state에 넣으면 안된다 + - state의 중복 피하기 - 동일 데이터가 중복될 경우 동기화 유지 어려움 + - 깊게 중첩된 state 피하기 - 업데이트하기 어려움 + - 평탄하게 만드는 것 (정규화) 고려하기 + - 예를 들어 자식 배열을 가지는 트리 구조 대신 자식 id의 배열을 가지도록.. +1. 컨포넌트 간 state 공유하기 +- state 끌어올리기 + 1. 자신 컴포넌트의 state 제거 + 2. 하드 코딩 값을 공통의 부모로부터 전달 + 3. 공통의 부모에 state 추가, 이벤트 핸들러와 함께 전달 +- 제어 컴포넌트와 비제어 컴포넌트 +1. state를 보존하고 초기화하기 +- state는 렌더 트리의 위치에 연결된다 +- react는 컴포넌트가 UI트리에서 렌더링되는 한 state유지 +- 같은 위치의 같은 컴포넌트는 state 보존 +- 같은 위치의 다른 컴포넌트는 그의 전체 서브 트리 state 초기화 +- 컴포넌트에 다른 key를 주면 하위트리를 초기화하도록 강제할 수 있음 +1. state 로직을 reducer로 작성하기 +- `useState` → `useReducer` 변환하기 + - 이벤트 핸들러에서 action 전달 + - 다음 state 반환하는 reducer 함수 작성 + - `useState`를 `useReducer`로 바꾸기 +- reducer 함수 안에서는 switch문을 사용하는 것이 규칙, 각 case는 return으로 끝낼 것 +- reducer는 디버깅과 테스트에 도움이 되고 반드시 순수해야 한다 +- 각 action은 데이터 안에서 단일 사용자 상호작용을 설명해야 한다 +- reducer를 더 간결하게 작성하려면 lmmer 라이브러리 사용할 것 +1. context를 사용해 데이터를 깊게 전달하기 +- context를 사용하면 명시적으로 props를 전달해주지 않아도 컴포넌트가 트리 아래에 위치한 데이터를 사용할 수 있게 된다 +- context의 사용법 + - context 생성 + - 데이터가 필요한 컴포넌트에서 context 사용 + - 데이터 지정 컴포넌트에서 context 제공 +- 사용하기 전 고려할 것들(먼저 해보기) + - props로 전달하기로 시작하기 + - 컴포넌트를 추출하고 JSX를 자식으로 전달하기 +- context 사용예시 + - 테마 지정하기 + - 상태 관리 +- context는 정적인 값으로 제한되지 X +1. reducer와 context로 앱 확장하기 +- reducer를 사용하면 컴포넌트의 state 로직을 통합할 수 있음 +- reducer와 context를 결합하는 방법 + - context 생성 + - state와 dispatch 함수를 context에 넣기 + - 트리 안에서 context 사용 +- 하나의 파일로 합쳐 컴포넌트 정리 가능