기본 React Hook

김진효·2026년 7월 30일

[CS] 면접 대비

목록 보기
9/11
post-thumbnail

React Hook

React Hook은 함수 컴포넌트에서 상태 관리생명주기 기능 등을 이용할 수 있도록 도와주는 함수!

React 생애주기: 컴포넌트가 렌더링되기 시작하고, 업데이트되고, 언마운트 되기까지의 일련의 과정
Mount(마운트, 첫 렌더링) → Update(리렌더링) → UnMount(화면에서 사라짐)

🔎 특징

  1. use- 로 시작
  2. 함수 컴포넌트 내부에서만 호출 가능
  3. 조건문, 반복문 내부에서는 호출 불가
    서로 다른 hook 들의 호출 순서가 엉망이 되어버릴 수 있어 내부 오류가 발생할 수 있기 때문
  4. use 라는 접두사를 이용하여 커스텀 훅(custom hook) 제작 가능

대표적인 것들만 정리 해보고 최적화 관련 함수들은 다음에 정리해 볼 예정


useState

상태 관리 hook

const [ state, setState]  = useState(initialState);
//  [새롭게 생성된 state값, state 상태 변경 함수] = useState(초기값)

useEffect

생애 주기 관리 hook

useEffect(setup, dependencies?)
// useEffect(실행할 콜백 함수, 의존성 배열)

배열에 들어가 있는 값이 바뀌게 되면 첫 번째 인수로 전달한 콜백 함수를 실행

useEffect(() => {
  // 모든 렌더링 후에 실행
});

useEffect(() => {
  // 마운트될 때만 실행 (컴포넌트가 나타날 때)
}, []);

useEffect(() => {
 // 마운트될 때 실행, 또한 렌더링 이후에 a 또는 b 중 하나라도 변경된 경우에도 실행됩니다
}, [a, b]);

useEffect 에서 반환된 함수를 클린업(cleanup) 함수라고 부른다

주로 컴포넌트가 언마운트 될 때, effect가 다시 실행되기 전에 이전 effect가 남긴 것을 정리하는 용도로 사용 (리소스 정리)

useEffect(() => {
  const connection = createConnection(); // 컴포넌트가 마운트될 때 실행되는 작업
  connection.connect();

  // cleanup 함수
  return () => {
    connection.disconnect(); // 컴포넌트가 언마운트될 때 실행되는 작업
  };
}, []); 

✔️ 의존성 배열 설정 유의점

  • useEffect 내부에 사용하는 state나 props, 함수 등은 반드시 의존성 배열에 포함시켜야한다
    eslint-plugin-react-hooks 라는 플러그인으로 의존성 배열 누락 여부를 검사할 수 있음 (누락 시 effect가 이전 값을 참조하는 버그 알려줌)
  • 의존성 배열에 객체나 함수, 배열을 넣을 경우 원치 않은 무한 루프나 재실행을 유발하기 쉬우므로 주의하기
    객체 및 함수는 다음에 정리할 useMemo나 useCallback 등으로 참조 유지하거나 useEffect 내부로 이동 추천

      // ❌ 객체 전체를 전달하면 매 렌더링마다 새 참조라 매번 재실행될 수 있음
      useEffect(() => {
        fetchData(user.id);
      }, [user]);
    
      // ⭕ 필요한 값만 전달하여 불필요한 재 실행 방지
      useEffect(() => {
        fetchData(user.id);
      }, [user.id]);
    

useRef

컴포넌트 내부 변수로 일반적인 값들을 저장할 수가 있음
렌더링에 필요하지 않은 값을 참조 → 보여주지 않을 변수 (렌더링 X)

const ref = useRef(initialValue)
//  참조(Reference) 객체 = useRef(초기값)

DOM 접근 가능 → state처럼 값은 유지하지만 변경되어도 리렌더링 안됨

const inputRef = useRef(null);
  const focusInput = () => inputRef.current.focus();
  return <input ref={inputRef} />;

useContext

컴포넌트간 데이터를 전달하는 방법으로
context는 데이터 객체(보관소)라고 보면 된다
보통 변하는 값과, 변하지 않는 값을 구분하여 Context를 분리함
→ 하나의 Context에 다 넣으면 값 하나만 바뀌어도 구독하는 모든 컴포넌트가 리렌더링 되므로

useContext

const SomeContext = createContext(defaultValue) // 생성한 context
const value = useContext(SomeContext) // 호출하는 컴포넌트에 대한 context 값을 반환
const { someValue } = useContext(SomeContext) // 필요한 값만 가져올 수 있음

Context.Provider : Context에 포함된 값을 제공하는 컴포넌트
provider 아래의 모든 컴포넌트들은 해당 Context의 데이터를 공급받을 수 있음

<BoardContext.Provider>
  <CreateForm onCreate={onCreate} />
  <List onUpdate={onUpdate} onDelete={onDelete} boards={boards} />
</BoardContext.Provider>

useReducer

컴포넌트 내부에 새로운 state를 생성하는 hook
모든 useStateuseReducer 로 대체 가능
다른 점은, 상태 변경 로직을 컴포넌트 외부(reducer 함수)로 분리할 수 있다는 것
여러 세부 상태를 하나의 로직으로 묶어서 관리하기 좋음

const [state, dispatch] = useReducer(reducer, initialValue)
// [상태, 상태 변화가 있어야한다는 사실을 알리는 함수] = useReducer(상태를 실제로 변화시키는 변환기, 초기값)

흐름 : 이벤트 발생 → dispatch(action) 호출 → Reducer 실행 → 반환된 새 state로 업데이트

복잡한 구조는 보통 useReducer를 이용해서 관리하고 간단한 상태 변화 코드만 있다면 useState 를 이용

function reducer(state, action) {
  switch (action.type) {
    case "INCREASE":
      return state + action.data;
    case "DECREASE":
      return state - action.data;
    default:
      return state;
  }
}

export default function App() {
  const [state, dispatch] = useReducer(reducer, initialValue);

  const onClickPlus = () => {
        dispatch({
            type:"INCREASE", // 상태를 어떻게 변화시키길 원하는지
            data: 1, // 어느정도 변화시킬지
        })
    }

}


참고

Hooks의 종류
[React AtoZ] useEffect와 의존성 배열, 그리고 EsLint
React useEffect 의존성 배열: 객체 vs 구체적인 값
한 입 크기로 잘라 먹는 리액트

0개의 댓글