FrontEnd Develop

🌐 Context로 상태와 함수를 글로벌하게 관리하며 성능 개선하기

Frisbeen 2025. 1. 21. 20:17

서론

 

React 프로젝트에서 컴포넌트 간 상태를 공유하고 관리하는 일은 자주 발생합니다. 그러나 여러 컴포넌트가 공통된 상태를 사용해야 할 때, props drilling이라는 문제가 발생하곤 합니다.

 

props drilling이란 상태나 함수를 필요한 컴포넌트로 전달하기 위해 여러 중간 컴포넌트를 거쳐야 하는 상황을 말합니다. 이는 코드의 복잡도를 증가시키고 유지보수성을 떨어뜨립니다.

 

React의 Context API는 이러한 문제를 해결하고 성능까지 개선할 수 있는 강력한 도구입니다. 이번 포스팅에서는 props drilling이 있는 상황과 Context로 이를 해결하여 성능을 개선하는 방법을 살펴보겠습니다.

 

문제상황

 

1. Props Drilling의 문제

 

 props drilling이 있는 상황을 살펴보겠습니다. 예를 들어, 사이드바 상태(isSidebarOpen)와 상태 변경 함수(toggleSidebar)를 전달해야 한다고 가정해보겠습니다.

 

Props Drilling 예제 코드

// App.js
import React, { useState } from 'react';
import Layout from './components/Layout';

const App = () => {
  const [isSidebarOpen, setIsSidebarOpen] = useState(false);

  const toggleSidebar = () => {
    setIsSidebarOpen((prev) => !prev);
  };

  return (
    <Layout isSidebarOpen={isSidebarOpen} toggleSidebar={toggleSidebar} />
  );
};

export default App;

 

// Layout.js
import React from 'react';
import Navbar from './Navbar';
import HamburgerBtn from './HamburgerBtn';

const Layout = ({ isSidebarOpen, toggleSidebar }) => {
  return (
    <div className="layout-container">
      <Navbar isSidebarOpen={isSidebarOpen} />
      <HamburgerBtn isSidebarOpen={isSidebarOpen} toggleSidebar={toggleSidebar} />
    </div>
  );
};

export default Layout;
// HamburgerBtn.js
import React from 'react';

const HamburgerBtn = ({ isSidebarOpen, toggleSidebar }) => {
  return (
    <button
      className={`hamburger-button ${isSidebarOpen ? 'shifted' : ''}`}
      onClick={toggleSidebar}
    >
      ☰
    </button>
  );
};

export default HamburgerBtn;

 

 

Props Drilling의 문제점 -> 연결다리가 생김에 따라 코드가 복잡해짐

 

App -> Layout -> HamburgetBtn

 

햄버거버튼을 클릭하면 사이드바의 상태가 변화해야하기에 기능을 추가하는 건 좋으나 이 화살표가 많아지면, props를 추가해주는 곳이 너 무 많아지기에 코드의 가독성도 어려워지며 유지 보수도 어려워진다.

 

 

1. 중간 컴포넌트의 역할 증가

Layout은 단순히 NavbarHamburgerBtn을 렌더링하지만, isSidebarOpentoggleSidebar를 전달하는 추가 역할을 합니다. 이로 인해 코드가 복잡해집니다.

 

2. 컴포넌트 간 결합도 증가

isSidebarOpen이나 toggleSidebar를 필요로 하지 않는 컴포넌트(Layout)도 props를 받아야 하므로 컴포넌트 간 결합도가 높아집니다.

 

3. 유지보수 어려움

상태나 함수가 더 깊은 계층의 컴포넌트에서 필요해지면, 모든 중간 컴포넌트에 props를 추가해야 합니다.

 

 

 Context로 Props Drilling 해결하기

 

이제 Context를 사용해 props drilling 문제를 해결하고, 코드의 복잡도를 줄이겠습니다.

 

Context 적용 후 구조

1. SidebarContext: 글로벌 상태와 상태 변경 함수 정의.

2. SidebarProvider: 상태를 전역적으로 제공.

3. HamburgerBtn: useContext로 상태와 함수를 직접 가져옴

 

Context 적용 코드

 

1) SidebarContext 생성

// src/context/SidebarContext.jsx
import React, { createContext, useState } from 'react';

export const SidebarContext = createContext();

export const SidebarProvider = ({ children }) => {
  const [isSidebarOpen, setIsSidebarOpen] = useState(false);

  const toggleSidebar = () => {
    setIsSidebarOpen((prev) => !prev);
  };

  return (
    <SidebarContext.Provider value={{ isSidebarOpen, toggleSidebar }}>
      {children}
    </SidebarContext.Provider>
  );
};

 

2) Context Provider 적용

 

App.js에서 SidebarProvider로 전체 컴포넌트를 감쌉니다

 

// App.js
import React from 'react';
import { SidebarProvider } from './context/SidebarContext';
import Layout from './components/Layout';

const App = () => (
  <SidebarProvider>
    <Layout />
  </SidebarProvider>
);

export default App;

 

3) Context 사용

 

HamburgerBtn에서 useContext를 사용해 글로벌 상태를 가져옵니다.

 

// src/components/HamburgerBtn.jsx
import React, { useContext } from 'react';
import { SidebarContext } from '../context/SidebarContext';

const HamburgerBtn = () => {
  const { isSidebarOpen, toggleSidebar } = useContext(SidebarContext);

  return (
    <button
      className={`hamburger-button ${isSidebarOpen ? 'shifted' : ''}`}
      onClick={toggleSidebar}
    >
      ☰
    </button>
  );
};

export default HamburgerBtn;

 

 

성능 개선 포인트

1. props drilling 제거

상태와 함수를 중간 컴포넌트로 전달할 필요가 없어, 코드가 간결해지고 컴포넌트 간 결합도가 낮아집니다.

 

2. 불필요한 렌더링 방지

Context를 구독하지 않는 컴포넌트는 리렌더링되지 않습니다. 

 

3. 유지보수 용이성

상태 관리 로직이 Context로 중앙화되므로, 로직 변경이나 확장이 용이합니다.

 

 

 최종 코드 구조

src/
|-- context/
|   |-- SidebarContext.jsx
|
|-- components/
|   |-- Layout.jsx
|   |-- HamburgerBtn.jsx
|   |-- Navbar.jsx
|
|-- App.js

 

결론

 

React Context는 props drilling 문제를 해결하는, State 그리고 함수를 중앙화 시켜서 성능 개선을 하는 방식입니다.

전역 상태 관리상태 변경 함수의 공유를 통해 코드의 간결함과 재사용성을 높일 수 있습니다.