[React] Udemy 강의 노트 10-1

2023. 1. 26. 23:38WEB Dev/StudyNote

728x90

 

모듈 소개

- 세 가지 매우 중요한 개념이자 고급 기능

- 이펙트, 리듀서, 컨텍스트

 

 

"Side Effects"이란 무엇이며 useEffect를 소개합니다

- 이펙트 == 사이드이펙트

- 리액트 앱의 컴포넌트는 주요한 임무가 하나 있다 -> UI를 렌더링

- 화면에 무언가를 가져오고 사용자가 상호작용하게 하는 것 -> 버튼이 클릭되거나 텍스트가 입력되는 것

- 사용자 이벤트에 리액트를 사용하여 컴포넌트를 재평가하고 실제 DOM을 조작한다.

- 이펙트는 앱에서 일어나는 모든 것을 말한다.

- http 리퀘스트를 보내거나 브라우저 로컬 스토리지에 무언가를 저장하거나 하는 작업들은 화면에 무언가를 그리는 것과는 관계가 없다. 이것은 리액트가 화면에 무언가 그릴 필요가 없기 때문에 리액트와 관련이 없다.

- 일반적인 컴포넌트 함수 밖에서 일어나야 한다. 

- http 리퀘스트를 직접 보내면 state가 변경될 때 마다 리퀘스트를 보내게 된다.

- 이렇게 되면 무한 루프에 빠질 수 있다.

- 그렇기 떄문에 사이드이펙트를 처리하는 더 좋은 방법이 있다 useEffect 훅이다.

- 컴포넌트 내에서 실행할 수 있는 함수인데 두 개의 매개변수와 함께 호출된다. 첫번째 인수는 함수인데 모든 컴포넌트 평가 후에 실행되는 함수이며 지정된 의존성을 두 번째 인수로 넣어주고 지정된 의존성이 변경되면 실행된다.

- 의존성으로 구성된 배열로 의존성이 변경될 때 마다 함수가 재실행된다. 

- 컴포넌트가 재렌더링 될때는 실행되지 않는다.

 

 

useEffect() 훅 사용하기

- 현실에서는 로그인하면 백엔드에 리퀘스트를 보내서 로그인 데이터를 가지고 온다.

- 서버가 없는 상태에서 로그인 하면 새로고침 할 때 상태를 잃어버린다. -> 인증모듈에서 자세히

- 현재는 리액트가 자바스크립트로 일종의 state 인 로그인 상태를 관리한다. 그렇기 때문에 새로고침을 하면 가장 최근 실행에서 얻은 모든 변수는 사라진다. 

- 앱이 시작할 때 데이터가 유지되었는지 확인하고 자동로그인도 시킬 수 있다.

- 이것은 useEffect를 활용한다.

- 브라우저에서는 쿠키나 로컬 저장소를 사용할 수 있다. 

- 사용자가 페이지를 새로고침하거나 나갔다 올 때 로컬 저장소에 키-값 쌍이 있는지 확인하려고 한다면 useEffect를 쓸 수 있다.

- 간혹 무한 루프를 생성할 수도 있다 

- useEffect()에는 두 개의 인자가 들어간다.

- 하나는 함수이다. 그리고 두 번째 인수는 의존성 배열이다. useEffect(()=>{},[])

- useEffect내의 함수는 리액트에 의해 실행되고  모든 컴포넌트 재평가 후에 실행된다.

- 즉, return의 JSX까지 다 출력되고 나서 실행되는 함수이다. 

- 모든 경우에 재렌더링이 되는 것은 아니고 의존성 배열에서 변경이 생긴 경우에만 실행된다. 

- []의 경우 앱이 처음 시작한 경우 실행된다.(의존성이 없는 것으로 판단)

- 이 데이터 가져오기는 사이드 이펙트고 UI와는 관련 없다.

- 로컬 저장소에 정보를 저장하는 함수들은 리소스를 많이 쓰기 때문에 여러번 반복해서 쓰면 안된다.

 

 

useEffect & 종속성

- 의존성이 필요한 경우가 있음

- 사이드 이펙트 함수에서 사용하는 것을 의존성으로 추가한다.

- 함수를 의존성으로 추가할 때는 함수() 로 실행하지 않고 함수 만 입력해서 함수의 포인터를 추가해 본질적으로 함수 그 자체를 의존성으로 추가할 수 있다.

- 일반적으로 특정 데이터, 예를 들어 어떤 스테이트나 프롭스가 변경될 때 로직을 다시 실행하기 위해 사용된다.

- useEffect의 주요 임무는 사이드이펙트를 처리하는 것이고 사이드 이펙트는 보통 http 리퀘스트다 

- 사이드 이펙트에는 키 입력과 입력 데이터 저장, 응답으로 다른 액션을 실행하는 것도 있다 (로그인 폼 등)

 

종속성으로 추가할 항목 및 추가하지 않을 항목

- effect 함수에서 사용하는 "모든 것"을 종속성으로 추가해야 함

- 하지만 몇 가지 예외가 있음

- 상태 업데이트 기능을 추가할 필요는 없다 (리액트는 set등의 state를 변경하는 함수가 절대 변경되지 않도록 보장하므로 종속성으로 추가할 필요가 없다.)

- 내장 API 또는 함수를 추가할 필요가 없다. (fetch() 나 localStorage 등) 브라우저 내장 API나 전역 기능은 리액트의 구성요소 렌더링 주기와 관련이 없으며 변경되지 않음

- 변수나 함수를 추가할 필요가 없다.

- 결론적으로 effect 함수에서 사용하는 모든 것들을 추갛야 한다. 구성요소 (또는 일부 상위 구성 요소)가 다시 렌더링 되어 이러한 것들이 변경될 수 있는 경우. 컴포넌트 함수에 정의된 변수나 상태 컴포넌트 함수에 정의된 props 또는 함수는 종속성으로 추가되어야 한다.

 

useEffect에서 Cleanup 함수 사용하기

- useEffect의 내장 기능 clean up effect

- 기본적으로 사용자 입력을 그룹화 하는 것을 디바운싱이라고 한다. 이것은 useEffect로 구현할 수 있다.

- setTimeout은 타이머가 한 번에 하나만 실행되도록 타이머를 지운다.

- 따라서 입력을 계속하면 마지막 타이머만 남기고 이전 타이머는 지운다.

- useEffect에서 첫 번째로 전달되는 함수는 무언가를 반환할 수 있다. 

- 클린업 함수는 모든 새로운 사이드이펙트 함수가 실행되기 전에 그리고 컴포넌트가 제거되기 전에 실행되며 첫 번째 사이드이펙트 함수가 실행되기 전에는 실행되지 않고 그 이후에 실행된다.

 

 

useEffect 요약

- useEffect 함수는 모든 컴포넌트 렌더링 주기 후에 실행된다.

- 의존성으로 빈 배열[]을 추가하면 컴포넌트가 처음 마운트되고 렌더링될 때만 실행된다.

- 의존성을 추가하면 컴포넌트가 재평가 될 때마다 재평가되며, state가 변경될 때 마다 실행된다.

- 클린업 함수는 이 state 함수가 전체적으로 실행되기 전에 실행된다. 그러나 처음 시작될 때는 실행되지 않는다.

 

 

useReducer 및 Reducers 일반 소개

- useReducer는 state 관리를 도와주며 useState와 비슷하지만 더 복잡한 기능을 가지고 있다.

- 여러 개의 state를 관리해야 할 때 useReducer를 useState 대신 쓸 수 있다.

- 대부분의 경우에는 useState를 사용한다.

- 리액트가 state 업데이트를 스케쥴링하는 방식 때문에, 실제로는 매우 드물지만 state가 처리되기 이전에 코드가 실행될 수 있다. (가장 최근의 스냅샷이 아닐 수 있다.)

- 다른 state에 의존하여 state를 업데이트 하는 것은 해서는 안되는 일이다.

- 이런 경우에는 useReducer를 이용하는 것이 좋다.

- 다른 state를 기반으로 하는 state를 업데이트하면 그 경우에는 하나의 state로 병합하는 것도 좋은 방법이다.

- 여러 state가 복잡하게 얽혀있다면 useReducer를 사용한다.

 

 

useReducer() 훅 사용

- useReducer도 항상 두 개의 값이 있는 배열을 반환하기 때문에 배열 디스트럭쳐링을 사용할 수 있다.

const [state, dispatchFn] = useReducer(reducerFn, initialState, initFn);

- 배열의 첫 번째는 최신 state 스냅샷이다.

- 새로운 state를 설정하는 대신 액션을 dispatch 한다.

- 그 액션은 useReducer의 첫 번째 인수가 소비하는데 리듀서 함수라고 한다.

- 최신 state 스냅샷을 자동으로 가지고 오는 함수이다. (리액트가 호출)

- 리액트는 새 액션이 디스패치될 때마다 이 리듀서 함수를 호출한다.

- 이 리듀서 함수는 또 새로운 업데이트된 state를 반환한다.

- useState의 함수 폼과 비슷하나 액션이 있기 때문에 확장된 형태이다.

- 또한 초기 state나 함수도 설정할 수 있다.

- state가 전부 들어있는 큰 state 한 개 또는 작은 state 여러 개로 값을 관리할 수 있다.

- 리듀서 함수는 컴포넌트 함수 바깥에 선언해서 사용하거나 익명 함수로 사용할 수 있다. (리듀서 함수 내부에서는 컴포넌트 내 함수에서 만들어진 어떤 값도 필요없기 때문이다.)

- 보통 dispatch 함수에 전달하는 값은 객체이다. 

- 액션은 항상 일관된 형태를 가져야 한다.

728x90