훅(React Hooks)이란?
리액트 16.8 버전부터 추가된 기능으로,
클래스 컴포넌트와 생명주기 메서드를 이용하던 기존 방식에서 벗어나
함수형 컴포넌트에서 더 직관적인 함수를 이용할 수 있게 만든 기능입니다.
훅 사용 규칙
1. 훅은 최상위 레벨에서만 호출 가능합니다.
반복문, 조건문, 중첩된 함수 안에서 호출하면 안 됩니다.
2. 훅은 오직 리액트 함수 컴포넌트 내에서만 호출 가능합니다.
훅 종류
- useState (동적 상태 관리)
- useEffect (side effect 수행 -mount/unmount/update)
- useContext (컴포넌트를 중첩하지 않고도 전역 값 쉽게 관리)
- useReducer (복잡한 컴포넌트들의 state를 관리 -분리)
- useCallback (특정 함수 재사용)
- useMemo (연산한 값 재사용)
- useRef (DOM선택, 컴포넌트 안에서 조회/수정할 수 있는 변수 관리)
- useImperativeHandle
- useLayoutEffect
- useDebugValue
위 나열된 훅을 모두 알아보지는 않고, 기본적인 훅만 알아보겠습니다.
useState()
const [state, setState] = useState(initialState);
상태를 설정할 때 사용되고,
클래스 컴포넌트의 생명주기 메소드 constructor()에서
상태를 초기화하는 것과 비슷한 역할을 합니다.
인자로 초기 상태(initialState)를 받고,
현재 상태(state)와 상태를 설정하는 함수(setState)를 반환합니다.
이때, 초기 상태와 현재 상태, 상태를 설정하는 함수는
항상 위와 같은 이름을 가질 필요가 없습니다.
다만, 상태를 설정하는 함수의 이름은 보통 set상태로 짓습니다.
초기 상태는 숫자나 문자열, 배열, 객체 등을 이용하여 설정할 수 있는데요,
이때 콜백 함수를 이용하면
초기 렌더링할 때 콜백 함수가 반환하는 값을 초기 상태로 갖게 됩니다.
이렇게 설정된 상태는 추후에 상태 설정 함수를 이용하여 변경할 수 있으며,
이 훅을 통해 설정된 상태는 컴포넌트가 다시 렌더링 되어도 유지된다는 장점이 있습니다.
또한, 하나의 컴포넌트에 여러개의 상태가 선언될 수 있습니다.
하지만 하나의 상태를 여러 컴포넌트에서 사용하게 되는 경우,
매번 props를 전달해야 하여 불필요한 코드 중복이 발생할 수 있으며
오류가 생길 수 있다는 단점이 있습니다.
이 경우 Redux 또는 Recoil과 같은 전역 상태 라이브러리를 이용하여 관리하는 것이 권장됩니다.
useRef()
const ref = useRef(initialValue);
함수형 컴포넌트에서 ref를 쉽게 사용할 수 있도록 합니다.
const Component = () => {
const ref = useRef(null);
return ( <div ref={ref}>ref</div>; )
}
useRef()는 인자로 받은 값으로 초기화된 변경 가능한 ref 객체를 반환합니다.
이 객체는 컴포넌트의 전 생애주기 동안 유지되며,
ref.current와 같이 current 속성에 접근하여 현재 가리키는 객체에 접근할 수 있습니다.
또한, 가변 값을 유지하기 편리하다는 장점이 있습니다.
useEffect()
useEffect(callback, dependency);
클래스 컴포넌트의 생명주기 메소드인
componentDidMount(),
componentDidUpdate,
componentWillUnmount()를 통합한 것과 같습니다.
side effect를 발생시킵니다.
Side effect란 다른 컴포넌트에 영향을 줄 수 있고
렌더링 과정에서는 구현할 수 없는 작업을 일컫는데요,
그 예로는 컴포넌트 안에서 데이터 가져오기, 구독하기, DOM을 직접 조작하기 등이 있습니다.
useEffect(() => {
// side effect를 발생하는 작업
const timerId = setTimeout( () => console.log('useEffect') );
// side effect를 발생하는 작업을 정리
return () => clearTimeout(timerId);
});
앞서 언급한 클래스 컴포넌트의 생명주기 메서드
componentDidMount()와 componentDidUpdate()는
컴포넌트가 렌더링 될 때마다 side effect를 발생시키고,
componentDidUmount()는
컴포넌트가 언마운트될 때 이 작업을 정리합니다.
이러한 세 메소드를 합친 것과 같은 useEffect()는
첫 번째 인자로 전달받은 콜백 함수 내부에서 side effect가 발생하는 작업을 수행하고,
이에 대한 정리 작업을 수행하는 cleanup 함수를 반환합니다.
또한, 위와 같이 두 번째 인자로 아무것도 넣지 않은 경우,
렌더링 할 때마다 콜백 함수를 실행하고
다음 렌더링이 실행되기 전에 cleanup 함수를 실행합니다.
useEffect(() => {
console.log('useEffect');
}, []);
두 번째 인자에 빈 배열을 넣는 경우,
마운트 될 때 콜백 함수 내부를 실행하고
언마운트 될 때 cleanup 함수를 실행합니다.
이때, 마운트 될 때의 state값과 props값이
언마운트될 때까지 유지된다는 점을 주의하세요.
useEffect(() => {
console.log('useEffect');
}, [state]);
특정 값이 업데이트 되었을 때만 실행하고 싶은 경우,
두 번째 인자에 특정 값을 담은 배열을 넣어주면 됩니다.
배열에는 편의에 따라 해당 값을 안 넣을 수도 있고,
콜백 함수 내부에서 사용하지 않는 값을 넣을 수 있습니다.
이때, setState 함수는 넣어주지 않아도 됩니다.
참고자료 및 출처
'프로그래밍 > React' 카테고리의 다른 글
자바스크립트의 Array 내장 함수 (0) | 2022.08.02 |
---|---|
React에서 반드시 알아야 하는 것들! (0) | 2022.07.30 |
라우팅이 뭘까? (0) | 2022.07.29 |
리덕스란? 새로고침할 때도 리덕스 안의 데이터를 유지하려면? (0) | 2022.07.29 |
DOM이 그래서 정확히 뭘까? (0) | 2022.07.28 |