| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- LG유플러스 유레카 프론트엔드 대면
- 유레카
- 멀티캠퍼스it부트캠프
- 입력처리방식
- 상태관리
- 스프링부트
- 엘지유플러스프론트엔드대면
- 멀티캠퍼스부트캠프
- 프론트엔드
- 타입스크립트
- streaming metadata
- 유레카프론트엔드대면
- 마이배티스
- 나눔스퀘어
- 유레카 부트캠프 프론트엔드
- 부트캠프후기
- 유레카프론트엔드
- 유플텍플
- TypeScript
- sentry
- 핏로그
- 유레카 프론트엔드 대면
- LG U+
- 리액트
- 미니프로젝트
- input="password"
- 이미지 파일 관리
- jandi
- 웹시큐리티
- React
- Today
- Total
joooii
[49일차] React Hooks 본문

React Hooks이란?
React Hooks는 v16.8에서 새로 도입되어 함수형 컴포넌트에서도 상태 관리를 가능하게하는 라이브러리이다.
함수형 컴포넌트에 맞게 만들어진 것으로 함수형 컴포넌트에서만 사용이 가능하다.

Hook 규칙
1. Hook은 최상위 레벨에서만 호출해라
Hook은 반복문, 조건문, 중첩 함수, try/catch/finally 블록 내부에서 호출하면 안된다. 그렇기에 React 함수의 최상위 레벨에서 호출하고, Early Return (함수에서 조건문을 만족할 때 일찍 반환하는 것) 이전에 사용해야 한다.
function Counter() {
// ✅ Good: 함수 컴포넌트의 최상위 레벨에서 사용
const [count, setCount] = useState(0);
// ...
}
function useWindowWidth() {
// ✅ Good: 커스텀 Hook의 최상위 레벨에서 사용
const [width, setWidth] = useState(window.innerWidth);
// ...
}
추가적으로 Hook을 호출하면 안되는 위치
- 조건문, 반복문 내부
- 조건문 return 문 이후
- 이벤트 핸들러
- 클래스 컴포넌트
- `useMemo`, `useReducer`, `useEffect`에 전달된 함수 내부
2. Hook을 React 함수에서만 호출해라
Hook은 리액트가 관리하는 생명주기 안에서 사용해야 하기 때문에, 일반 JS 함수에서는 호출하면 안 된다.
대신 React 함수 컴포넌트에서 호출하거나 Custom Hook에서 호출하는 것은 가능하다.
🚫 잘못된 예시 (일반 JS 함수 안에서 사용)
function notAComponent() {
const [count, setCount] = useState(0); // ❌ 에러 발생
}
✅ 올바른 예시 1: React 함수 컴포넌트 안에서 사용
function Counter() {
const [count, setCount] = useState(0); // ✅ 가능
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
✅ 올바른 예시 2: Custom Hook 안에서 사용
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue); // ✅ 가능
return [count, setCount];
}
function Counter() {
const [count, setCount] = useCounter(5); // ✅ 가능
return <div>{count}</div>;
}
3. Hook을 일반 값처럼 전달하지 마라
Hook은 항상 함수로 호출되어야 하며, 일반 값으로 전달하면 안 된다.
함수로 호출해야 컴포넌틀르 독립적으로 이해할 수 있는 '지역 추론'이 가능하다.
이 규칙을 어기면 리액트가 컴포넌트를 자동으로 최적화하지 못한다.
4. Hook을 동적으로 변경/사용하지 마라
Hook은 가능한 한 "정적"으로 유지되어야 한다. 이는 Hook은 항상 같은 순서와 구조로 호출되어야 하기 때문이다.
즉, React가 Hook의 순서를 기준으로 상태를 기억하기 때문이다.
function Counter() {
const [count, setCount] = useState(0); // 첫 번째 Hook
const [text, setText] = useState("hi"); // 두 번째 Hook
}
🚫 잘못된 예시 (Hook을 동적으로 사용한 경우)
function Example({ isLogin }) {
if (isLogin) {
const [user, setUser] = useState(null); // ❌ 조건문 안에서 Hook 호출
}
const [theme, setTheme] = useState("light"); // ⚠️ 순서가 달라질 수 있음
}
✅ 올바른 예시 (항상 같은 순서로 호출)
function Example({ isLogin }) {
const [user, setUser] = useState(null); // ✅ 항상 호출됨
const [theme, setTheme] = useState("light");
if (isLogin) {
// 조건문 안에서는 Hook을 호출하지 말고 로직만 넣기
console.log("로그인 상태");
}
}
자주 사용되는 Hooks
useState()
const [state, setState] = useState(initialState)
useState는 컴포넌트에 state 변수를 추가할 수 있는 훅이다.
useState는 2개의 값을 가진 배열을 반환하는 데, 아래와 같다.
1. 현재 state (상태값)
2. state를 다른 값으로 업데이트하고, 리렌더링을 일으키는 함수
즉, 상태가 바뀌면 React가 자동으로 리렌더링을 하게 된다.
useEffect()
useEffect(() => {콜백함수}, [의존성 배열])
useEffect는 컴포넌트가 렌더링된 후 실행될 코드를 정의할 때 사용한다.
API 요청, 이벤트 등록, 타이머 설정 같은 side effect를 처리할 때 필수이다.
의존성 배열이 빈 배열이라면 첫 렌더링 시 한 번만 실행되며, 의존성 배열의 값이 바뀔 때마다 렌더링된다.
useRef()
const ref = useRef(initialValue)
useRef는 DOM 요소 (focus, scroll)를 직접 제어하거나, 렌더링 없이 값을 저장할 때 사용된다.
useMemo()
const cachedValue = useMemo(() => {콜백함수}, [의존성 배열]);
useMemo는 리렌더링 사이에 계산 결과를 캐싱하여 비용이 많이 드는 계산을 매번 하지 않도록 결과를 기억해주는 훅이다.
예를 들어 배열의 평균값, 필터링, 정렬 같은 연산을 최적화할 때 유용하다.
useMemo는 의존값이 바뀌지 않는 이상 이전 계산 결과를 재사용하기 때문에 성능 최적화에 좋다.
useCallback()
useCallback(() => {콜백함수}, [의존성배열])
useCallback은 컴포넌트가 리렌더링 될 때마다 함수의 불필요한 렌더링을 방지하기 위해 함수를 메모이제이션(Memoization)하는 훅이다.
useCallback 또한 의존값이 바뀌지 않는 이상 함수를 새로 만들지 않기 때문에, 주로 React.memo나 자식 컴포넌트에 함수 props를 넘길 때 함께 사용한다.
그러나 단순한 이벤트 핸들링과 같은 함수나 의존성이 없는 경우에 useCallback을 사용하게 되면 성능 저하로 이어질 가능성이 크다. 따라서 memo로 로 감싸진 컴포넌트에 전달하는 경우 or useEffect 의존성 배열에 존재하는 경우에 사용하는 것이 좋다.
React.memo
export default React.memo(Component)
React.memo는 Hook은 아니지만, Hook들과 함께 자주 사용하는 성능 최적화 도구이다.
React.memo는 컴포넌트 결과를 메모이제이션해서 props가 바뀌지 않으면 리렌더링을 건너뛴다.
특히 React.memo와 useCallback 함수를 같이 사용하는데, React.memo가 props의 얕은 비교(shallow compare)만 수행한다.
그래서 props로 전달되는 함수가 매번 새로 생성되면 memo 효과가 없기 때문에 함수의 불필요한 리렌더링을 방지하는 useCallback 와 자주 사용된다.
useMemo, useCallback, React.memo 사용 방법
프로젝트를 하면서 프론트엔드 팀원과 함께 컴포넌트 렌더링을 최적화하기 위해 이에 관련된 아카이브를 작성한 적이 있다.

이때 팀원과 각각 언제 사용하면 좋을지 논의한 결과 아래처럼 사용하기로 했던 적이 있다.

Custom Hook
Custom Hook은 Reack의 Hook 기능을 재사용 가능한 로직으로 캡슐화한 함수이다.
사용하는 방법은 Hook 컴포넌트를 생성하고, 다른 hook들과 동일하게 사용하고자 하는 컴포넌트에서 호출해서 사용하면 된다.
Custom Hook 장점
1. 로직 재사용성 증가
- 여러 컴포넌트에서 동일한 상태 관리나 비즈니스 로직 재사용 가능
2. 컴포넌트 코드 간소화
- 복잡한 로직을 컴포넌트에서 분리하여 코드 가독성을 높임
3. 테스트와 유지보수 용이
- 훅을 독립적으로 테스트할 수 있어 유지보수가 쉬움
4. 구조화된 로직 분리
- 상태관리, API 호출, 이벤트 핸들링 등 명확히 분리 가능
Custom Hook 작성 시 고려사항
1. use 로 시작
- 리액트가 훅으로 인식하기 위해 이름을 use로 시작해야 함
2. React Hook 규칙 준수
- 커스텀 훅 내부에서도 최상위 레벨에서만 호출, 리액트 컴포넌트 또는 다른 훅 내부에서만 호출해야 한다는 hook 규칙 만족
3. 훅의 책임 분리
- 한 커스텀 훅은 하나의 책임만 가지도록 설계
4. 매개변수와 반환값 명확화
- 커스텀 훅이 어떤 데이터를 소비하고, 어떤 값을 반환할지 명확히 설계해야 함
회고
항상 그래왔듯이 Hooks의 개념은 알지만, 실제로 적용하기는 어려운 것 같다.
그래서 최대한 빨리 프로젝트에서 적용해보고 싶다!

그리고 맥북 앱 중에 깃허브 커밋과 관련된 좋은 앱을 하나 추천해보려고 한다.
사실 프로젝트 팀원이 쓰는 것을 봐서 찾아보게 되었는데 개발할 때 좋은 동기부여가 될 것 같아서 바로 설치했다
앱 이름은 'Jandi - 깃헙 잔디를 상태바에서 손쉽게 보자' 이다.

아래 사진처럼 상단바에 커밋 수가 잔디와 함께 표시가 되는데, 약간의 생기를 더해줄 수 있다.
참고로 0일 때는 빨간 색으로 표시된다 !!
이제 다시 개발 화이팅해보자 ~~


참고
https://ko.react.dev/reference/react/hooks#state-hooks
내장 React Hook – React
The library for web and native user interfaces
ko.react.dev
'TIL' 카테고리의 다른 글
| [58일차] Zustand (0) | 2025.11.24 |
|---|---|
| [53일차] TypeScript와 Vite (1) | 2025.11.17 |
| [45일차] React 기초 (0) | 2025.11.04 |
| [40일차] CX 디자인 및 Figma (0) | 2025.10.28 |
| [33~35일차] 미니 프로젝트 - 백엔드 (0) | 2025.10.21 |