
Hook은 React 버전 16.8부터 React요소로 새로 추가되었습니다. Hook을 이용하여 기존 Class 바탕의 코드를 작성할 필요 없이 상태 값과 여러 React의 가능을 사용할 수 있습니다.
반복문, 조건문, 중첩 함수(nested function) 내에선 hook을 호출하지 않는 것이 좋다. 유지보수성 높은 React 프로젝트 설계를 위해선, React 함수의 최상위(at the top level)에서 hook을 호출하는 것을 권장한다.
이 규칙을 따르지 않으면 컴포넌트가 렌더링 될 때 마다 항상 동일한 순서로 hook이 호출되는 것을 보장 할 수 없다. 그리고 useState와 useEffect가 여러 번 호출되는 중에도 hook의 상태를 올바르게 유지할 수 없다.
React 훅을 일반적인 자바스크립트 함수에서 호출하면 안된다. 아래는 React hook을 호출 할 수 있는 스코프 중 하나이다.
컴포넌트가 가질 수 있는 상태를 state 라고 하는데, 그 상태를 간편하게 생성 및 업데이트 시킬 수 있게 해주는 훅이다.
const [light, setLight] = useState('off');
현재 상태(state)를 나타내는 값을 저장하는 변수이며, state 변수 라고 부른다
state 변수의 값을 변경할 수 있게 접근하는 함수로 set 함수 라고 부른다. 이 함수를 이용해 state 변수의 값이 변경되면, 해당 컴포넌트는 화면에 다시 리렌더링된다.
이 함수의 아규먼트로 전달하는 값이 state 변수의 초기값이 된다.

어떤 값이 변경될 때 마다 특정 코드를 실행하고, 리렌더링하는 리액트 훅이다. 컴포넌트의 생명 주기 중 마운트, 언마운트, 업데이트 주기에 해당하는 생명 주기 메소드를 훅 레벨에서 지원한다.
useEffect(callback, [deps])
두 번째 인수로 전달한 배열을 의존성 배열(dependency array)이라 한다. 이 의존성 배열에 속한 원소의 값이 변경되면, 첫 번째 인수로 전달한 콜백 함수가 실행된다.
// (1) 컴포넌트의 마운트 시점에 실행되는 코드
useEffect(() => {
console.log("mounted");
}, []);
// (2) 컴포넌트의 마운트 시점, 또는 업데이트 시점에 실행되는 코드
useEffect(() => {
console.log("mounted or updated");
if(/*...mounted?...*/){
console.log("mounted");
}
else{
console.log("updated");
}
});
// (3) light 변수의 값이 변경 됬을 때, 실행되는 코드
useEffect(() => {
console.log("light status : ", light);
}, [light]);
// (4) 컴포넌트의 언마운트 시점에 실행되는 코드
useEffect(() => {
const ID = /*...resource...*/
return () => {
console.log("cleanUp");
/*... release code...*/
};
});
의존성 배열로 빈 배열을 전달하는 경우, 컴포넌트의 생명 주기중 마운트 시점에만 콜백 함수를 실행한다.
의존성 배열에 아무 값도 전달하지 않으면, 컴포넌트를 렌더링 할 때 마다 콜백 함수를 실행한다. 즉 컴포넌트의 생명 주기중 마운트와 업데이트 시점 둘 다 해당되기 때문에, 분기 로직으로 마운트 시점과 업데이트 시점을 구분해서 사용해야 할 필요를 고민해야 한다.
이 의존성 배열에 속한 원소의 값이 변경되면, 첫 번째 인수로 전달한 콜백 함수가 실행된다.
런타임 중 개발자가 직접 리소스를 릴리즈 해야 하는 클린업(clean-up)기능이 필요한 경우, 다음과 같이 사용한다.
(java의 try-catch-finally 블록 중 finally 블록이라 이해하면 편할 것 같다.)
컴포넌트가 가질 수 있는 상태를 state 라고 하는데, 그 상태를 간편하게 참조 및 업데이트 시킬 수 있게 해주는 훅이다.
useState 훅과의 가장 큰 차이점은, useState 훅은 state 변수에 직접 접근하여 값을 변경하여도 의미가 없고, set 함수를 이용해 접근해야 하는데 set 함수를 이용해 state 변수의 값이 변경되면 해당 컴포넌트는 리렌더링 된다.
그러나 useRef는 값이 변경되어도 리렌더링 되지 않는다.
React 공식 문서에서 말하는 useRef를 사용해야 할 바람직한 상황은 다음과 같다.
const textRef = useRef();
const interval = useRef();
useEffect(() => {
...
return () => {
clearInterval(interval.current);
}
});
...
if(text.length < 5){
textRef.current.focus();
}
컴포넌트가 가질 수 있는 상태를 state 라고 하는데, 그 상태를 간편하게 생성 및 업데이트 시킬 수 있게 해주는 훅이 useState 훅이다. useReducer 훅은 useState 훅보다 좀 더 복잡한 상태 관리가 필요하여, 상태 변화 코드를 외부 혹은 다른 파일에 분리해야 하는 경우 자주 사용된다.
const [state, dispatch] = useReducer(reducer, initState);
state 변수
상태 변화 촉발 함수
상태 변화 함수
state 변수 초기값
메모이제이션(memoization)은 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술이다. 동적 계획법의 핵심이 되는 기술이다.
const [count, setCount] = useState(0);
...
const value = useMemo(() => {
return count * count;
}, [count]);
React에서 컴포넌트는 자신의 상태 변경(state update)으로 인해 리렌더링 될 수도 있지만, 부모 컴포넌트에서 상태 변경이 일어나 같이 리랜더링 되는 경우도 잦다. 따라서 복잡한 로직을 가진 컴포넌트가 자주 리렌더링 된다면, 사용자는 속도 이슈를 겪게 된다.
이 때 자주 사용되는 로직의 함수(count * count)를 특정 값(count)이 변경될 때만 다시 호출하고, 값이 변경되지 않았을 경우 기존에 함수의 리턴값을 저장해놓았다가 그대로 리턴하는 기능을 useMemo훅이 제공한다.
const value = useMemo(callback, deps);
의존성 배열에 담긴 값이 바뀌면 실행 할 콜백 함수.
의존성 배열
한 입 크기로 잘라 먹는 리액트
이정환 저자(글) · 인사이트 · 2023년 04월 06일