diff --git "a/07\355\232\214/\355\230\204\353\213\244\354\206\234/README.md" "b/07\355\232\214/\355\230\204\353\213\244\354\206\234/README.md" new file mode 100644 index 0000000..2f72e2c --- /dev/null +++ "b/07\355\232\214/\355\230\204\353\213\244\354\206\234/README.md" @@ -0,0 +1,944 @@ +# 7 - useEffect + +# Effect로 동기화하기 + +https://ko.react.dev/learn/synchronizing-with-effects + +일부 컴포넌트에서는 외부 시스템과 동기화해야할 수 있다. 예를들어 리액트의 state를 기준으로 React와 상관없는 구성요소를 제어하거나, 서버 연결을 설정하거나 구성요소가 화면에 나타날 때 분석 목적의 로그를 전송할 수 있다. Effect를 사용하면 렌더링 후 특정코드를 실행하여 react 외부의 시스템과 컴포넌트를 동기화할 수 있다. + +## Effect란 무엇이고 이벤트와 어떻게 다를까? + +effect에 대해 자세히 알아보기 전에 컴포넌트 내부의 2가지 로직 유형에 대해 알아야한다. + +- 렌더링 코드를 주관하는 로직은 컴포넌트의 최상단에 위치하며 props와 state를 적절히 변형해 결과적으로 JSX를 반환한다. 렌더링 코드 로직은 순수해야한다. 수학 공식처럼 결과만 계산해야하고 그외에는 아무것도 하지 않는다. +- 이벤트 핸들러는 단순한 계산 용도가 아닌 무언가를 하는 컴포넌트 내부의 중첩함수이다. 이벤트 핸들러는 입력 필드를 업데이트하거나 제품을 구입하기 위해 HTTP POST 요청을 보내거나 사용자를 다른 화면으로 이동시킬 수 있다. 이벤트 핸들러에는 특정 사용자 입력(클릭 혹은 입력)으로 인해 발생하는 부수효과를 포함한다. + +가끔은 이것만으로는 충분하지 않을 때가 있다. + +예를들어 화면에 보일 때 마다 채팅 서버에 접속해야하는 ChatRoom 컴포넌트를 생각해보자. 서버에 접속하는 것은 순수한 계산이 아니고 부수효과를 발생시키기 때문에 렌더링중에는 할 수 없다. 하지만 클릭한번으로 ChatRoom이 표시되는 특정 이벤트는 하나도 없다. + +Effect는 렌더링 자체에 의해 발생하는 부수 효과를 특정하는 것으로 특정이벤트가 아닌 렌더링에 의해 직접 발생한다. 채팅에서 메세지를 보내는 것은 이벤트이다. 왜냐하면 이건 사용자가 특정 버튼을 클릭함에 따라 직접적으로 발생한다. Effect는 커밋이 끝난 후에 화면 업데이트가 이루어지고 나서 실행된다. 이 시점이 React 컴포넌트를 외부 시스템과 동기화하기 좋은 타이밍이다. + + + +## Effect가 필요 없을지도 모른다. + +컴포넌트에 Effect를 무작정 추가하지 말자. + +Effect는 주로 리액트 코드를 벗어난 특정 외부 시스템과 동기화하기 위해 사용된다. 이는 브라우저 API, 서드파티 위젯, 네트워크 등을 포함한다. 만약 순수하게 다른 상태에 기반하여 일부 상태를 조정하는 경우에는 Effect가 필요하지 않을 수 있다. + +## Effect를 작성하는 방법 + +1. Effect 선언 +2. Effect 의존성 지정 +3. 필요한 경우 클린업 함수 추가 + +### 1단계: Effect 선언 + +기본적으로 Effect는 모든 렌더링 후에 실행된다. + +```jsx +import { useEffect } from "react"; + +function MyComponent() { + useEffect(() => { + // 이 곳의 코드는 모든 렌더링 후에 실행된다 + }); + return
; +} +``` + +컴포넌트가 렌더링될 때마다 리액트는 화면을 업데이트한 다음 useEffect 내부의 코드를 실행한다. 다시말해 `useEffect`는 화면에 렌더링이 반영될 때까지 코드 실행을 “지연”시킨다. + +이제부터 외부 시스템과 동기화하기 위해 어떻게 Effect를 사용할 수 있는지 알아보자. ``라는 React 컴포넌트를 살펴보자. 이 컴포넌트를 `isPlaying` 이라는 props를 통해 재생중인지 일시정지상태인지 제어하는 것이 좋아보인다. + +```jsx + +``` + +커스텀 VideoPlayer 컴포넌트는 내장 브라우저 `