-
useEffect를 life cycle method 처럼 사용하기Web/React 2021. 5. 13. 03:51반응형
useEffect는 componentDidMount, componentDidUpdate,
그리고 componentWillUnmount가 합쳐진 훅이라고 생각하면 편하다.
세 가지 life cycle method를 하나의 훅으로 사용할 수 있어서 상당히 편리하긴 한데,
각각을 따로 사용하고 싶을 때는 어떻게 해야할까?
■ useEffect를 componentDidMount처럼 사용하기
useEffect의 두 번째 인자로는 dependency array가 들어간다.
즉, 컴포넌트가 re-rendering을 하기 전에, 변경되었는지 확인할 변수들이 들어가는 배열이다.
이 배열에 변수가 들어가면 해당 변수가 변경되었을 때
useEffect가 호출되면서 componentDidUpdate의 역할을 할 수 있게 되지만,
해당 배열에 아무것도 넣지 않으면 컴포넌트가 mount되면서 딱 한 번 호출되고,
그 이후로는 해당 useEffect가 호출되지 않는다.
즉, dependency array에 아무 변수도 넣지 않으면 useEffect를 componentDidMount처럼 사용할 수 있다.
useEffect(() => { // ... }, []);
※ componentWillUnmount 는?
마찬가지로 dependency array로 빈 배열을 주되, 원하는 로직을 담은 함수를 return 해주면 된다.
이 함수는 unmount 시에 실행되기 때문에 흔히들 cleanup function 이라고 부른다.
주로 setTimeout, setInterval을 해제하거나, 함께 사라져야할 인스턴스를 제거하거나 하는 용도.
useEffect(() => { return () => { // ... } }, []);
dependency array에 변수를 넣는 순간, 해당 변수에 의존성이 생겨
그 변수를 변경할 때마다 useEffect가 호출된다. 이를 원하지 않는다면 빈 배열을 넣자.
■ componentDidUpdate를 커스텀 훅으로 구현하기
그러면, 컴포넌트가 mount될 때에는 실행되지 않고,
그 이후에 state가 변경될 때만 실행되게 하려면 어떻게 해야할까?
커스텀 훅으로 구현을 할 수 있는데, 사실 코드는 상당히 간단하다.
초기 렌더링(mount)인지 여부를 확인하기 위한 useRef와,
초기 렌더링인지를 검사하는 if문을 가진 useEffect만 있으면 된다.
const useUpdateEffect = (effect, dependencies) => { const isFirstMount = useRef(true); useEffect(() => { if (!isFirstMount.current) effect(); else isFirstMount.current = false; }, dependencies); };
근데, 왜 첫 mount인지를 기억하는 데에 useState가 아닌 useRef를 사용하는걸까?
그 이유는, useRef는 여러 번의 렌더링 속에서도 계속해서 값을 기억하고 있으면서도,
re-rendering을 발생시키지 않기 때문이다.
useState는 값을 기억하긴 하지만 값이 변경되면 re-rendering을 유발하기 때문에
우리가 원하는 동작에는 적합하지 않다.
참고
반응형'Web > React' 카테고리의 다른 글
React.memo와 useCallback, useMemo (0) 2021.12.13 CRA를 Next.js로 마이그레이션하기 (0) 2021.10.06 React에서 setInterval 사용하기 (2) 2021.09.05 React로 Snackbar를 만든 과정 (4) 2021.05.16 PropTypes element vs elementType (2) 2021.05.11