Add Hooks - a way to use state and other React features without writing a class.
Hook 은 리액트 버전 16.8.0 (2019년 2월 6일) 에서 추가된 기능입니다. 변경 로그를 보면 위처럼, "state 와 다른 여러 리액트의 기능들을 class 없이도 사용할 수 있게 해주는 기능이라고 되어있는데요.
지난 section 1 에서 useState Hook을 활용해 state 를 변경하는 것을 다뤘었다면 이번에는 useEffect 를 활용하는 방법을 공부했습니다. 오늘은 이 useEffect 에 대해 정리해보려고 합니다.
리액트 공식 문서는 주요 개념의 설명과 Hook 의 설명을 아예 분리해서 다루고 있습니다. 아마도 Hook 이 처음부터 있었던 개념이 아니기 때문이 아닐까 싶은데요. 위 링크에서 보실 수 있는 것처럼 Hook 의 4번 항목으로 Effect Hook 에 대해 다루고 있습니다.
공식문서는 useEffect 의 기능을 다음과 같이 안내하고 있습니다.
Effect Hook 을 사용하면 함수 컴포넌트에서 side effect 를 수행할 수 있습니다.
컴퓨터공학에서 side effect는 함수가 결과값 외의 다른 상태를 변경시키는 것을 뜻한다고 하는데요. 리액트에서는 데이터를 fetching 하는 것이나 구독 설정하기, 수동으로 리액트 컴포넌트의 DOM 을 수정하는 것들이 다 side effects 라고 말하고 있습니다. 리액트와 상관 없는 API 를 사용하는 경우라고도 이해할 수 있다고 합니다.
이 useEffect 는 첫 번째 인자로 함수를 가지는데, 이 함수는 1. 컴포넌트가 생성되고 처음으로 화면에 렌더링 될 때, 2. 컴포넌트에 새로운 props 가 전달되면서 렌더링될 때, 3. 컴포넌트의 state 가 바뀌면서 렌더링될 때마다 실행됩니다.
useEffect 는 두 번째 인자로 배열을 가질 수 있습니다. 공식 문서에서는 이 인자를 "effect 가 종속되어 있는 값의 배열" 이라고 설명하고 있는데요. 예를 들어 특정한 state 의 변경 시에만 작동하기를 원한다면 변경되는 state 를 배열에 넣어 [state] 와 같이 전달할 수 있다는 것입니다. 만약 빈 배열을 전달한다면 컴포넌트가 생성되고 처음으로 화면에 렌더링 될 때에만 한 번 작동하게 됩니다.
Hook 은 React 함수 내에서 호출해야 하고, 최상위(at the Top Level) 에서만 호출해야 합니다. 공식문서는 이것을 Hook 을 사용할 때 준수해야 할 두 가지 규칙이라고 설명하고 있습니다.
'React 함수 내에서' 라는 것은 일반적인 Javascript 함수에서 호출하지 말라는 것을 의미합니다. '최상위'라는 것은 반복문, 조건문 혹은 중첩된 함수 내에서 호출하지 말라는 것을 말하는데요. 렌더링 될 때마다 항상 Hook 이 호출되도록 하기 위한 규칙이라고 이해할 수 있겠습니다.
위에서는 useEffect 를 포함하는 모든 Hook 의 활용 시 지켜야 할 규칙을 말했다면, 지금부터는 useEffect 를 사용할 때 주의해야 하는 부분들을 적어보려고 합니다.
앞서 useEffect 가 가지는 함수는 1~3의 조건으로 실행된다는 것을 알 수 있었는데요. 만약 두 번째 인자를 전달하지 않은 채 useEffect 를 활용하게 되면 반복적으로 렌더링을 하면서 무한 루프와 비슷하게 작동할 가능성이 있습니다.
예를 들어서 useEffect 내부에서 어떤 상태를 변경한다고 할 때,
1) useEffect 내부에서 상태 변경 => 2) 상태가 변경되면서 렌더링 => 3) 렌더링되면서 다시 useEffect 실행 => 다시 1) 부터 시작
위와 같은 형태로 반복적으로 useEffect 를 실행하는 것을 확인할 수 있습니다. 따라서 useEffect 를 실행할 때는 가급적 두 번째 인자를 정확하게 전달해 불필요한 반복이 진행되는 것을 막아야 합니다.
리액트를 배우다 보니 재미있으면서도 묘하게 어렵고, 간혹 이해가 되지 않는 것들이 있었습니다. 열심히 자료를 찾아도 원하는 것을 발견하지 못해 스트레스를 받게도 되지만, 한편으로는 깨달음을 얻으면서 생기는 기쁨이 있기도 하네요. useEffect 에 대해 간략한 정리로 오늘의 TIL 을 마치도록 하겠습니다.