[React] useCallback & useContext 활용

November·2025년 1월 8일
post-thumbnail

useCallback

useMemo 훅과 유사하게 성능 최적화를 위해 사용
콜백함수가 불필요하게 다시 생성되는 것을 방지 ➡️ 컴포넌트가 리렌더링될 때 동일한 콜백함수가 사용되도록 함

  • 콜백 함수가 자식 컴포넌트의 props로 전달되는 경우 유용
const memoizedCallback = useCallback(()=> {...},[의존성배열])

()=> {...} 콜백 함수

TODO 예제

  • React.memo() 로 컴포넌트를 래핑하면, 리액트는 컴포넌트를 렌더링하고 그 결과를 메모이징(Memoizing)해 다음 렌더링이 일어날 때 props가 같으면 메모이징된 내용을 재사용함

  • const addTodo = () => { setTodos([...todos, "할일"]); };
    addTodo 함수의 내용이 변경되지 않았음에도 불구하고, <Todos> 컴포넌트를 리렌더링 함

useCallback을 이용해서 props 변수로 전달되는 함수가 매번 재정의 되지 않도록 수정

const addTodo = useCallback(() => {
  setTodos([...todos, "할일"]);
}, [todos]);


useContext

함수형 컴포넌트에서 Context API를 쉽게 사용할 수 있도록 도와주는 훅

  • Context를 구독해 해당 Context의 현재 값을 가져오는 데 사용
  • 컴포넌트가 Context값을 사용하면, Context의 값이 변경될 때 자동으로 해당 컴포넌트가 리렌더링

Context API

  • 컴포넌트 tree에서 전역적으로 데이터를 공유할 수 있는 방법을 제공
  • 이를 통해 부모 컴포넌트에서 자식 컴포넌트로 데이터를 반복적으로 전달하는 props drilling 문제를 해결

사용법

  • Context 생성 ➡️ React.createContext() 함수
  • Provider 정의 ➡️ Context.Provider를 사용해서 Context 값을 하위 컴포넌트로 전달
  • Context 소비 ➡️ useContext 훅을 사용해서 Context 값을 가져와서 사용

테마가 적용된 페이지 생성 예제

ThemedButton, Blog, News 컴포넌트 생성
테마 변경 버튼을 클릭하면 버튼의 배경색과 글자색을 변경

App.js

ThemedButton 컴포넌트

Blog 컴포넌트

News 컴포넌트

Contents 컴포넌트

Blog와 News를 포함하는 Contents 컴포넌트를 추가 ➡️ Contents 컴포넌트는 theme 변수를 필요로 하지 않지만, 하위 컴포넌트에게 전달하기 위해서 props 변수로 받아서 처리

const Contents = ({ theme }) => {
  return (
    <>
      <Blog theme={theme} />
      <News theme={theme} />
    </>
  );
};

useContext 훅을 이용해서 수정

1️⃣ Context 생성

const ThemeContext = createContext();

2️⃣ Provider 정의

3️⃣ Context 소비

const { theme, changeTheme } = useContext(ThemeContext);
  • ThemeButton 컴포넌트
  • Blog 컴포넌트
  • News 컴포넌트
  • Content 컴포넌트
하위 컴포넌트로 전달을 위한 props 변수 생성(정의)하지 않아도 됨

const Contents = () => {
  return (
    <>
      <Blog />
      <News />
    </>
  );
};
  • App.js
    <ThemeProvider> 로 감싸고, props 변수 삭제

App.js를 ThemeProvider 컴포넌트를 사용하지 않고 Provider를 직접 정의하는 방식으로도 사용할 수 있음

export default function App() {
  const [theme, setTheme] = useState("light");
  const changeTheme = () => setTheme(theme === "light" ? "dark" : "light");

  return (
    <ThemeContext.Provider value={{ theme, changeTheme }}>
      <div>
        <h1>테마가 적용된 페이지</h1>
        <ThemedButton />
        <Contents />
      </div>
    </ThemeContext.Provider>
  );
}

0개의 댓글