리액트가 업데이트 되면서 나온 개념
대부분 개발할 때 사용함
생성자 단계에서 state를 정의해서 사용하고 setState()함수를 통해 state를 업데이트할 수 있으며 Lifecycle methods를 제공함
클래스 컴포넌트의 state 사용이 불가하며 Lifecycle methods를 제공하지 않음
코드가 간결하고 짧기 때문에 이를 보완하기 위해서 도입된 개념이 Hooks임
갈고리란 말로 실행 중에 갈고리를 거는 것처럼 끼어들어가 작동하는 것
이런 Hooks의 이름은 앞에 use란 것이 불림
커스텀 Hooks는 마음대로 이름을 붙힐 수 있으나 use를 붙히는 것이 관례임
함수의 인자로 count를 사용할 경우 count가 증가하지만 재렌더링이 일어나지 않아 화면에 표시되지 않음
리턴값으로 배열이 나오고
첫번째는 변수이고 두번째는 set함수명이 나오게 된다.
이렇게 만들면 재렌더링이 일어나서 count가 변경되면서 화면에 표시됨
클래스형 컴포넌트에서는 setState 함수를 통해서 모두 관리가 되었지만 함수형의 경우 변수 하나하나마다 달리 적용됨.
즉 변수 하나당 setState가 따로 나오게 됨
부작용을 의미하나 리액트에서는 효과, 영향이라는 의미로 사용이 됨
서버에서 데이터 받거나 수동으로 돔을 조작하는 것.
클래스형의 컴포넌트의 Lifecycle함수와 동일한 기능을 함
의존성배열은 이 effect가 의존하고 있는 배열(참고하고 있는)로 이 의존성배열이 하나라도 변경 되었을 경우 useEffect가 실행이 됨.
만약 mount, unmount 시에 단 한 번 씩만 실행되게 하려면??
의존성 배열에 빈배열을 넣으면 된다.
업데이트 될때마다 호출이 된다.
예시
document.title은 크롬브라우저의 제목을 말함
useEffect()에 return값은 unMount될 대 호출됨
useEffect()는 여러개 사용할 수 있다.
Memoized value를 리턴하는 Hook
최적화를 사용하기 위해서 사용함
비용이 높은(연산량이 높은) 함수의 호출결과를 저장해 두었다가 같은 값으로 함수를 호출하면 새로 연산하지 않고 이전에 저장되있던 결과를 바로 반환함.
시간도 짧아지고 중복 연산을 하지 않아서 자원을 적게 씀
이 결과값을 Memoized value라고 함
useMemo로 전달된 함수는 렌더링이 일어나는 동안 실행됨
결과적으로 렌더링이 일어나는 동안 실행되어서는 안될 함수는 useMemo에 적어두어서는 안됨
서버에서 데이터 받거나 수동으로 DOM을 조작하는 것 같은 함수는 적으면 안됨
무조건 넣어줘야됨
대부분 사용하지 않음
위의 경우 처럼 useCallback을 사용하지 않고 컴포넌트에 정의된 함수를 props로 내려줄 경우에는 재렌더링 될때마다 매번 함수가 새로 정의됨
위의 경우는 의존성 배열이 변경 된 경우에만 함수가 다시 정의가 되므로 마운트 시에 한 번만 정의하기 때문에 재렌더링 시에는 함수가 다시 정의되지 않는다.
특정 컴포넌트에 접근할 수 있는 객체
refObjcect.current
컴포넌트가 마운트해제 될때까지 유지됨
current가 변경되었을 때 재렌더링이 일어나지 않음
ref에 연결된 것이 변경되거나 분리되었을 경우에는
callback ref를 사용해야 함
예시
자식 컴포넌트가 변경되었을 경우 알림을 받을 수 있음.
반복, 조건, 중첩함수에서는 호출해서는 안됨
조건에 따라 Hook이 호출되는 경우가 달라지므로 잘못된 사용이라고 할 수 있음.
eslint-plugin-react-hooks
훅의 규칙을 따르도록 강제해주는것
반복적인 로직을 Hook으로 만들어서 재사용하기 위해서 사용함
동일한 부분이 발견됨
함수이기 때문에 컴포넌트를 하나 만들어준다.
중복된 로직 추출
그렇다!
암묵적인 룰이고 중요한 규칙이기 때문에
use로 시작하지 않으면 그냥 함수랑 헷갈리기 때문에
어떻게 분리되는지 알까?
Custom Hook은 독립적으로 작동하기 때문에 한 컴포넌트에서 여러개 Custom Hook을 불러올 수 있음