useEffect 훅은 컴포넌트가 마운트 됐을 때, 언마운트 됐을 때, 업데이트 될 때 (특정 props가 바뀔 때) 사용한다.
useEffect(() => {
fetchUrl()
}, [])
첫번째 파라미터에는 함수, 두번째 파라미터에는 의존 값이 들어있는 배열을 넣는다.
빈 배열을 넘기게 되면 컴포넌트가 처음 나타날 때 (마운트 됐을 때) 만 useEffect에 등록한 함수가 호출 된다.
또한 useEffect는 함수를 반환할 수 있는데, 이를 cleanup 함수라고 한다.
클린업 함수는 useEffect에 대한 뒷정리를 해주는거라고 생각하면 된다.
클린업 함수 또한 의존값에 빈 배열이 들어있는 경우 컴포넌트가 사라질 때 클린업 함수 호출된다.
주로 마운트 시에 하는 작업들은 아래와 같다.
- props로 받은 값을 컴포넌트의 상태로 설정
- 외부 API 요청
- 라이브러리 사용
- setInterval, setTimeout 사용
언마운트 시에 하는 작업들은 아래와 같다.
- setInterval, setTimeout 사용하여 등록한 작업 clear 하기
- 라이브러리 인스턴스 제거
의존값 배열에 특정 값을 넣는다면 컴포넌트가 처음 마운트 될 때에도 호출 되고,
이 값이 바뀔 때도 호출 된다. 또한 언마운트시에도 호출되고, 값이 바뀌기 직전에도 호출 된다.
만약 아예 생략 해버리면 컴포넌트가 리렌더링 될 때마다 호출된다.
주의사항
리액트 hook을 사용할 때에는 최상위에서만 훅을 호출해야 한다.
반복문, 조건문, 중첩된 함수에서 호출하면 안된다.
그 이유는 ko.reactjs.org/docs/hooks-rules.html 여기서 찾아볼 수 있는데
요약해서 말하면 리액트의 훅은 호출되는 순서에 의존한다는 것이다.
// ------------
// 첫 번째 렌더링
// ------------
useState('Mary') // 1. 'Mary'라는 name state 변수를 선언합니다.
useEffect(persistForm) // 2. 폼 데이터를 저장하기 위한 effect를 추가합니다.
useState('Poppins') // 3. 'Poppins'라는 surname state 변수를 선언합니다.
useEffect(updateTitle) // 4. 제목을 업데이트하기 위한 effect를 추가합니다.
// -------------
// 두 번째 렌더링
// -------------
useState('Mary') // 1. name state 변수를 읽습니다.(인자는 무시됩니다)
useEffect(persistForm) // 2. 폼 데이터를 저장하기 위한 effect가 대체됩니다.
useState('Poppins') // 3. surname state 변수를 읽습니다.(인자는 무시됩니다)
useEffect(updateTitle) // 4. 제목을 업데이트하기 위한 effect가 대체됩니다.
하지만 만약에 조건문 안에 훅을 사용하여 규칙을 깨게 되면
// 🔴 조건문에 Hook을 사용함으로써 규칙을 깸
if (name !== '') {
useEffect(function persistForm() {
localStorage.setItem('formData', name);
});
}
name !== '' 조건은 처음 렌더링에서 true이기 때문에 훅은 동작한다.
하지만 그다음 렌더링에서 폼을 초기화 하면서 이 조건이 false가 되기 때문에
해당 훅 호출하는 것을 건너뛰어 Hook 호출 순서가 달라지게 된다.
useState('Mary') // 1. name state 변수를 읽습니다. (인자는 무시됩니다)
// useEffect(persistForm) // 🔴 Hook을 건너뛰었습니다!
useState('Poppins') // 🔴 2 (3이었던). surname state 변수를 읽는 데 실패했습니다.
useEffect(updateTitle) // 🔴 3 (4였던). 제목을 업데이트하기 위한 effect가 대체되는 데 실패했습니다.
그렇다면 조건에 따라 훅을 실행시키고 싶다면 어떻게 해야할까?
useEffect(function persistForm() {
// 👍 더 이상 첫 번째 규칙을 어기지 않습니다
if (name !== '') {
localStorage.setItem('formData', name);
}
});
바로 조건문을 hook안에 넣어주면 된다.
'React' 카테고리의 다른 글
Redux Toolkit (0) | 2021.06.04 |
---|---|
Controlled Component vs UnControlled Component (0) | 2021.05.17 |
useState의 이전 상태값 (0) | 2020.12.28 |
useState의 비동기적 동작 (0) | 2020.12.21 |
redux-promise (0) | 2020.12.18 |
댓글