Frameworks/React
React 상태 관리
newclass
2025. 4. 1. 00:41
React 상태 관리 - Context API와 Redux
상태 관리의 필요성
React 애플리케이션이 커지고 복잡해질수록 컴포넌트 간 데이터 공유와 상태 관리는 중요한 과제가 됩니다. 간단한 애플리케이션에서는 props를 통해 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하는 방식이 충분할 수 있지만, 컴포넌트 트리가 깊어지면 다음과 같은 문제가 발생합니다:
- Props 드릴링(Prop Drilling): 여러 계층의 컴포넌트를 통해 데이터를 전달해야 할 때 발생하는 코드 복잡성
- 상태 동기화: 여러 컴포넌트에서 동일한 상태를 사용할 때 일관성 유지 문제
- 코드 유지보수: 상태 로직이 여러 컴포넌트에 분산될 때 발생하는 유지보수 어려움
이러한 문제를 해결하기 위해 다양한 상태 관리 기법과 라이브러리가 등장했으며, 그 중 가장 많이 사용되는 것이 React의 Context API와 Redux입니다.
React Context API
Context API는 React에 내장된 기능으로, 컴포넌트 트리 전체에 데이터를 제공할 수 있는 방법을 제공합니다.
Context API의 주요 개념
- Context: 공유할 데이터를 저장하는 객체
- Provider: Context 값을 하위 컴포넌트에 제공하는 컴포넌트
- Consumer: Context 값을 사용하는 컴포넌트 (현대 React에서는 주로 useContext 훅 사용)
Context API 사용 방법
1. Context 생성
// UserContext.js
import React, { createContext, useState } from 'react';
// Context 생성
export const UserContext = createContext(null);
// Provider 컴포넌트
export function UserProvider({ children }) {
const [user, setUser] = useState(null);
// 로그인 함수
const login = (userData) => {
setUser(userData);
};
// 로그아웃 함수
const logout = () => {
setUser(null);
};
// Provider를 통해 값과 함수 제공
return (
<UserContext.Provider value={{ user, login, logout }}>
{children}
</UserContext.Provider>
);
}
2. Provider로 애플리케이션 감싸기
// App.js
import React from 'react';
import { UserProvider } from './UserContext';
import Dashboard from './components/Dashboard';
import LoginPage from './components/LoginPage';
function App() {
return (
<UserProvider>
<div className="app">
<h1>My Application</h1>
<LoginPage />
<Dashboard />
</div>
</UserProvider>
);
}
export default App;
3. Context 값 사용하기
// LoginPage.js
import React, { useState, useContext } from 'react';
import { UserContext } from '../UserContext';
function LoginPage() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const { user, login } = useContext(UserContext);
const handleSubmit = (e) => {
e.preventDefault();
login({ username });
};
if (user) {
return <p>이미 로그인되었습니다, {user.username}님!</p>;
}
return (
<form onSubmit={handleSubmit}>
<h2>로그인</h2>
<input
type="text"
placeholder="사용자명"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<input
type="password"
placeholder="비밀번호"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">로그인</button>
</form>
);
}
export default LoginPage;
// Dashboard.js
import React, { useContext } from 'react';
import { UserContext } from '../UserContext';
function Dashboard() {
const { user, logout } = useContext(UserContext);
if (!user) {
return <p>대시보드를 보려면 로그인하세요.</p>;
}
return (
<div>
<h2>대시보드</h2>
<p>안녕하세요, {user.username}님!</p>
<button onClick={logout}>로그아웃</button>
</div>
);
}
export default Dashboard;
Context API의 장점과 한계
장점:
- React에 내장되어 있어 추가 라이브러리 불필요
- 간단한 설정으로 전역 상태 관리 가능
- 컴포넌트 트리 어디서나 상태에 접근 가능
한계:
- 복잡한 상태 로직에는 관리가 어려울 수 있음
- 상태 변경의 추적과 디버깅이 어려울 수 있음
- 잦은 렌더링 최적화 필요
- 여러 Context를 사용할 때 Provider 중첩 문제