-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
571 additions
and
0 deletions.
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
...185f-3af8-4840-9980-fd694b6d2f8e/react Hook 204516ad229d4c79a2032c4dfb3d6fd8.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# react Hook | ||
|
||
## React Hooks란? | ||
|
||
--- | ||
|
||
<aside> | ||
💡 react의 함수형 컴포넌트에서 상태(state) 및 생명주기(lifecycle) 기능을 사용할 수 있게 해주는 라이브러리 | ||
|
||
</aside> | ||
|
||
## React Hooks의 규칙 | ||
|
||
--- | ||
|
||
1. 최상위에서만 Hook을 호출해야 한다. | ||
|
||
→ 반복문이나 조건문 혹은 중첩된 함수 내에서 Hook을 호출할 수 없다. | ||
|
||
- 이유 | ||
|
||
react Hook은 호출되는 순서에 의존하기 때문에 조건문이나 반복문 안에서 실행될 경우 해당 부분을 건너뛰는 일이 발생할 수도 있기 때문이다. | ||
|
||
1. react 함수 내에서만 Hook을 호출해야 한다. | ||
|
||
→ Hook은 일반적인 js함수에서는 호출할 수 없다. | ||
|
||
→ 함수형 컴포넌트나 Custom Hook에서는 호출 가능하다. | ||
|
||
## React Hooks의 장점 | ||
|
||
1. 코드 재사용과 가독성 향상 | ||
|
||
→ 상태 로직을 여러 컴포넌트에서 추상화할 수 있다. | ||
|
||
1. 클래스 컴포넌트의 단점 극복 | ||
|
||
→ 클래스 컴포넌트는 복잡한 상태 로직을 가질 경우 코드가 복잡해지고 이해하기 어려울 수 있다.(Hooks를 사용하면 함수형 컴포넌트에서도 클래스 컴포넌트의 기능을 사용할 수 있다.) | ||
|
||
1. 테스트 용이성 | ||
|
||
→ 컴포넌트 로직을 더 작은 함수 단위로 분리할 수 있다. | ||
|
||
1. 함수형 프로그래밍 모델 강화 | ||
|
||
→ 함수형 프로그래밍 모델을 강화하고, 순수 함수를 사용해 상태를 변경할 수 있도록 한다. | ||
|
||
1. React 최적화 | ||
|
||
→ Hooks를 사용하면 React는 함수형 컴포넌트와 관련된 최적화를 수행할 수 있다. | ||
|
||
1. 비즈니스 로직 분리 | ||
|
||
→ 컴포넌트의 상태 관리와 렌더링 로직을 분리할 수 있다. | ||
|
||
## Hooks의 종류 | ||
|
||
--- | ||
|
||
1. useState: 상태를 관리하는 Hook | ||
2. useEffect: 컴포넌트가 렌더링될 떄 특정한 동작을 수행하도록 하는 Hook | ||
3. useRef: 특정 DOM에 접근해 DOM 조작을 가능하게 하는 Hook | ||
4. useCallback: 메모이제이션된 콜백함수를 생성하는 데 사용되는 Hook | ||
5. useMemo: 계산 비용이 많이 드는 함수의 반환 값을 기억하여, 동일한 계산을 반복하지 않고, 이전에 계산된 값을 재사용할 때 사용된다. |
37 changes: 37 additions & 0 deletions
37
...-4e46-9e28-6c24e4c49cac/react 작동 방식 742738e1cca64a8db6954509e55fec9a.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# react 작동 방식 | ||
|
||
## react란? | ||
|
||
--- | ||
|
||
<aside> | ||
💡 react는 사용자 인터페이스를 구축하기 위한 선언적이고 효율적이며 유연한 javascript 라이브러리이다. | ||
|
||
”컴포넌트”라고 불리는 파편을 이용해 복잡한 UI를 구성하도록 돕는다. | ||
|
||
</aside> | ||
|
||
## react 동작 요소 | ||
|
||
--- | ||
|
||
1. components: react는 이러한 components를 수용해서 사용자 인터페이스를 효과적으로 구성하게 된다. | ||
|
||
그리고 이렇게 구성된 사용자 인터페이스를 효과적으로 업데이트하게된다. | ||
|
||
1. react dom: 웹 브라우저와 javascript가 HTML을 이해하기 쉽도록 트리구조로 파싱하여 만든 객 | ||
|
||
## 작동 방식 | ||
|
||
--- | ||
|
||
<aside> | ||
💡 react는 컴포넌트를 관리하는 라이브러리일 뿐이고 이렇게 변경된 모든 사항에 대해서 reactdom에 전달해줍니다. 이렇게 reactdom은 실제 화면이 어떨게 보여질지에 대한 것이다. react dom에서는 이를 가상으로 비교한다. 가상의 메모리 안에서 비교가 이루어지기 때문에 브라우저에 렌더린되는 실제 dom에 접근해서 비교하는 기존의 방식과는 계산 차이가 많이 나게 됩니다. 실제로 반영될 화면이 재구성이 될지 안될지는 virtual dom을 통해서 리렌더링 여부를 결정한다. | ||
|
||
</aside> | ||
|
||
> 1. HTML parser가 HTML을 바탕으로 DOM tree를 그린다. | ||
2.CSS parser가 CSS를 바탕으로 CSSOM을 그린다. | ||
3.DOM에 CSSOM을 적용해 Render Tree를 그린다. | ||
4.Render Tree를 바탕으로 Painting 하여 실제 화면에 렌더링 한다. | ||
> |
274 changes: 274 additions & 0 deletions
274
...870c1-f0d0-4de1-b250-c1ffeabb2666/useEffect 932f607816bd464fa8d15189ae34e3d4.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,274 @@ | ||
# useEffect | ||
|
||
## useEffect의 개요 | ||
|
||
--- | ||
|
||
<aside> | ||
💡 side effect를 처리하기 위해 useEffect를 사용한다 | ||
|
||
</aside> | ||
|
||
> **side effect란?** | ||
-함수 내 특정 동작이 함수 외부에 영향을 끼쳐, 프로그램의 동작을 이해하기 어렵게 만드는 행위 | ||
> | ||
## side effect가 의미 하는 것 | ||
|
||
--- | ||
|
||
- **순수함수** | ||
|
||
순수함수란 외부와 전혀 관련이 없고, 함수 외부에 영향을 주지 않는 함수 | ||
|
||
→ 이런 식으로 함수를 구현해야 컴포넌트 재사용성이 증가하고 예측 및 테스트를 쉽게 할 수 있다. | ||
|
||
|
||
해당 함수가 같은 입력임에도 불구하고 다른 결과를 내거나, 함수 외부에 영향을 미치게 될 때, side effect가 있다고 하며, 이러한 함수들을 참조에 불투명하다고 한다. | ||
|
||
## side effect가 생길 때? | ||
|
||
--- | ||
|
||
-side effect가 생길 때 react는 useEffect를 제공한다. | ||
|
||
-useEffect는 컴포넌트가 최대한 순수 함수가 될 수 있도록 side effect를 따로 관리 할 수 있도록 한다. | ||
|
||
<aside> | ||
💡 **useEffect란?** | ||
매번 컴포넌트가 렌더링 될 때 특정 조건에 의존하여 수행되며, 컴포넌트가 최대한 순수 함수를 유지할 수 있도록 도와주는 함수 | ||
|
||
</aside> | ||
|
||
## useEffect 사용법 | ||
|
||
--- | ||
|
||
```jsx | ||
import { useEffect } from "react"; //useEffect를 사용하기 위해 import | ||
|
||
export default function App() { | ||
console.log("useEffect 전"); | ||
|
||
// useEffect도 함수기 때문에 함수 호출 | ||
useEffect(() => { | ||
console.log("메롱으로 바꿀거지롱"); | ||
const hi = document.getElementById("hi"); | ||
hi.innerText = "메롱"; | ||
}); | ||
|
||
console.log("useEffect 후"); | ||
|
||
return ( | ||
<div className="App"> | ||
<h1 id="hi">안녕하세요.</h1> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
> 위 코드는 렌더링 이후 react 외부에 있는 document 객체와 상호작용한다. 결과적으로 안녕하세요라는 내용이 메롱으로 바뀌게 된 것이다. | ||
*console에 useEffect가 가장 마지막에 호출된 것으로 보아 useEffect가 실행되는 시점은 컴포넌트가 **렌더링**된 이후라는 것을 알 수 있다. | ||
|
||
→여기서 말하는 렌더링이란? | ||
1. 맨 처음 컴포넌트가 렌더링되어 화면에 마운트되는 시점 | ||
2. state나 prop이 변하여 컴포넌트가 재렌더링되는 시점 | ||
> | ||
## 왜 useEffect는 렌더링이 일어난 후에 실행되는 것인가? | ||
|
||
--- | ||
|
||
<aside> | ||
💡 만약 컴포넌트 외부에 존재하는 DOM에 접근한다고 했을 때 렌더링이 다 이루어지기 전에 useEffect가 동작해서 해당 DOM을 찾지 못하는 상황이 발생할 수 있다. react는 이러한 side effect가 발생하는 시점이 렌더링이 발생하는 이후가 적당하다고 판단하였다. | ||
|
||
</aside> | ||
|
||
### useEffect가 작동하는 방식 | ||
|
||
1. 무한반복 | ||
|
||
```jsx | ||
import { useState, useEffect } from "react"; | ||
|
||
export default function App() { | ||
const [count, setCounter] = useState(0); | ||
|
||
useEffect(() => { | ||
console.log(`useEffect: ${Date()}`); | ||
}); | ||
|
||
const countHandler = (e) => { | ||
setCounter((s) => s + 1); | ||
}; | ||
|
||
return ( | ||
<div className="App"> | ||
<h1 id="hi">{count}</h1> | ||
<button onClick={countHandler}>카운터 증가</button> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
1. 처음에만 실행 | ||
|
||
```jsx | ||
import { useState, useEffect } from "react"; | ||
|
||
export default function App() { | ||
const [count, setCounter] = useState(0); | ||
|
||
useEffect(() => { | ||
console.log(`useEffect: ${Date()}`); | ||
}, []); | ||
|
||
const countHandler = (e) => { | ||
setCounter((s) => s + 1); | ||
}; | ||
|
||
return ( | ||
<div className="App"> | ||
<h1 id="hi">{count}</h1> | ||
<button onClick={countHandler}>카운터 증가</button> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
1. 의존성 배열 사용 | ||
|
||
```jsx | ||
import { useState, useEffect } from "react"; | ||
|
||
export default function App() { | ||
const [firstCount, setFirstCounter] = useState(0); | ||
const [secondCount, setSecondCounter] = useState(0); | ||
|
||
useEffect(() => { | ||
console.log(`useEffect: ${Date()}`); | ||
}, [firstCount]); | ||
|
||
const firstCountHandler = (e) => { | ||
setFirstCounter((s) => s + 1); | ||
}; | ||
|
||
const secondCountHandler = (e) => { | ||
setSecondCounter((s) => s + 1); | ||
}; | ||
|
||
return ( | ||
<div className="App"> | ||
<h1>{firstCount}</h1> | ||
<button onClick={firstCountHandler}>카운터 증가</button> | ||
<h1 id="hi">{secondCount}</h1> | ||
<button onClick={secondCountHandler}>카운터 증가</button> | ||
</div> | ||
); | ||
} | ||
|
||
``` | ||
|
||
→firstCount가 배열에 들어있다. 이를 의존성 배열이라고 부르며, 이것이 의미하는 것은 단순히 해당 컴포넌트가 재렌더링될 때 useEffect를 실행하는 것이 아닌, 의존성 배열에 존재하는 데이터가 변경될 때만 실행하라는 것을 나타낸다. | ||
|
||
→즉 위 코드의 useEffect는 firstcount가 변경되는 firstCountHandler 이벤트 핸들러가 호출될 때만 실행될 것이다. | ||
|
||
**`정리`** | ||
|
||
```jsx | ||
useEffect(() => { | ||
// 매 렌더링마다 실행 | ||
}); | ||
|
||
useEffect(() => { | ||
// 컴포넌트가 처음 렌더링된 실행 | ||
}, []); | ||
|
||
useEffect(() => { | ||
// 컴포넌트가 처음 렌더링된 이후 실행 | ||
// a나 b가 변경되어 컴포넌트가 재렌더링된 이후 실행 | ||
}, [a, b]); | ||
``` | ||
|
||
## useEffect 사용할 때 주의할 점 | ||
|
||
--- | ||
|
||
→useEffect는 기본적으로 컴포넌트가 재렌더링될 때 실행된다고 했다. API 요청으로 인한 데이터 획득, 로깅, DOM 조작 등의 행위는 일반적으로 문제가 되지 않지만, 특정 작업의 경우엔 메모리 누수등의 문제를 해결하기 위한 방법이 필요하다. | ||
|
||
<aside> | ||
💡 **`setInterval`**이나 **`setTimeout`** 등과 같은 이벤트는 등록되고 나서 **`clearInterval`**, **`clearTimeout`** 등이 호출되지 않으면 사라지지 않는다. | ||
|
||
</aside> | ||
|
||
**`clearInterval` 사용하지 않았을 때** | ||
|
||
```jsx | ||
import { useState, useEffect } from "react"; | ||
|
||
export default function App() { | ||
const [count, setCount] = useState(1000); | ||
|
||
useEffect(() => { | ||
setInterval(() => console.log(count), count); | ||
}, [count]); | ||
|
||
const countHander = (e) => { | ||
setCount((c) => c + 1000); | ||
}; | ||
|
||
return ( | ||
<div className="App"> | ||
<h1>{count}</h1> | ||
<button onClick={countHander}>카운트 증가</button> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
> 위 코드는 사용자가 버튼을 클릭할 때마다 해당 count를 기준으로 setInterval을 지정한다. 그러나 매번 useEffect가 실행될 때마다 기존의 seInterval이 사라지지 않는다. 이는 새로운 setInterval을 실행할 때마다 clearInterval을 호출하지 않았기 떄문이다. | ||
> | ||
**`clearInterval` 사용 했을 때** | ||
|
||
```jsx | ||
import { useState, useEffect } from "react"; | ||
|
||
export default function App() { | ||
const [count, setCount] = useState(1000); | ||
|
||
useEffect(() => { | ||
console.log("useEffect"); | ||
const interval = setInterval(() => console.log(count), count); | ||
|
||
return () => { | ||
clearInterval(interval); | ||
console.log("clearInterval"); | ||
}; | ||
}, [count]); | ||
|
||
const countHander = (e) => { | ||
setCount((c) => c + 1000); | ||
}; | ||
|
||
return ( | ||
<div className="App"> | ||
<h1>{count}</h1> | ||
<button onClick={countHander}>카운트 증가</button> | ||
</div> | ||
); | ||
} | ||
``` | ||
|
||
> 위 코드는 useEffect가 다시 호출되기 전에 useEffect의 return에 작성한 콜백이 실행된다. 이러한 콜백을 **clearnup 함수**라고 부른다. 결과를 확인해보면 useEffect가 실행되기 전에 clearInterval이 실행되는 것을 확인할 수 있다. | ||
> | ||
<aside> | ||
💡 return을 사용하지 않으면 새로운 useEffect를 수행하기 전에 아무런 작업을 하지 않는 것으로 인식한다. | ||
또한 의존성 배열도 주의해야 하는데, 만약 의존성 배열이 []로 되어있으면 해당 useEffect는 첫 렌더링 시에만 동작할 것이다. | ||
|
||
→ 따라서 return에 작성된 내용은 컴포넌트가 최종적으로 DOM에서 unmount되는 시점에만 수행될 것이다. | ||
→ 의존성 배열 내에 특정 변수가 존재하면 해당 변수들의 변경이 감지될 때마다 useEffect가 재수행될 것이기 때문에 clearnup 함수 또한 계속 실행될 것이다. | ||
|
||
</aside> |
Oops, something went wrong.