useContext
React의 Context API를 활용해 컴포넌트 트리 전체에서 데이터를 전달하는 방식
→ props 없이도 전역적으로 상태를 공유할 수 있음
→ 부모 컴포넌트에서 Context의 Provider를 설정하면, 해당 Provider 하위의 모든 컴포넌트에서 데이터 공유 가능
※ 전역 상태 관리와는 다름
Context Provider 내부의 컴포넌트에서만 상태 공유 가능
Context API 활용 예
- 다크 모드 / 라이트 모드 테마 설정
- 로그인 상태 관리 (Auth Context)
- 언어 설정 (i18n, 다국어 지원)
useContext 사용법
- createContext로 컨텍스트 생성
- Context.Provider에서 value로 상태, 함수 전달
- useContext(Context)로 데이터 접근
TodoContext.jsx - Context 생성
import React, { createContext, useState } from "react";
export const TodoContext = createContext(null); // 새로운 컨텍스트 생성
export const TodoProvider = ({ children }) => {
const [todos, setTodos] = useState([]);
const [task, setTask] = useState("");
const addTodo = () => {
const newTodo = {
id: crypto.randomUUID(),
text: task,
isCompleted: false,
};
setTodos([...todos, newTodo]);
setTask("");
};
const deleteTodo = (id) => {
setTodos(todos.filter((todo) => todo.id !== id));
};
const toggleComplete = (id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, isCompleted: !todo.isCompleted } : todo
)
);
};
const handleOnChange = (e) => {
setTask(e.target.value);
};
{/*
TodoProvider :
• useState로 todos(할 일 목록)와 task(입력값) 관리
• addTodo, deleteTodo, toggleComplete, handleOnChange 함수 제공
• TodoContext.Provider의 value에 상태와 함수를 담아 전달
*/}
return (
<TodoContext.Provider
value={{
todos,
task,
addTodo,
toggleComplete,
deleteTodo,
handleOnChange,
}}
>
{children}
</TodoContext.Provider>
);
};
App.jsx - Context 사용
import { useContext } from "react";
import "./App.css";
import { TodoList } from "./components/TodoList";
import { TodoContext } from "./context/TodoContext";
function App() {
const { task, addTodo, handleOnChange } = useContext(TodoContext);
{/*
• useContext(TodoContext)로 task, addTodo, handleOnChange 가져옴
• 입력창에 텍스트 입력 → handleOnChange 호출 → task 업데이트
• Add 버튼 클릭 시 addTodo 실행 → 새로운 할 일 추가
*/}
return (
<div className="app-container">
<input
value={task}
onChange={handleOnChange}
className="todo-input"
type="text"
/>
<button onClick={addTodo} className="add-btn">
Add
</button>
<TodoList />
</div>
);
}
export default App;
TodoList.jsx - 할 일 목록 표시
import { useContext } from "react";
import { TodoItem } from "./TodoItem";
import { TodoContext } from "../context/TodoContext";
{/*
• useContext(TodoContext)로 todos 가져와서 TodoItem으로 렌더링
*/}
export const TodoList = () => {
const { todos } = useContext(TodoContext);
return (
<>
{todos.map((todo) => (
<TodoItem key={todo.id} {...todo} />
))}
</>
);
};
TodoItem.jsx - 할 일 개별 아이템
import { useContext } from "react";
import { TodoContext } from "../context/TodoContext";
{/*
• toggleComplete 클릭 → 완료 여부 토글
• deleteTodo 클릭 → 해당 아이템 삭제
*/}
export const TodoItem = ({ id, text, isCompleted }) => {
const { toggleComplete, deleteTodo } = useContext(TodoContext);
return (
<div className="todo-item">
<input className="checkbox" type="checkbox" checked={isCompleted} />
<p
className="todo-text"
onClick={() => toggleComplete(id)}
style={{
textDecoration: isCompleted ? "line-through" : "none",
}}
>
{text}
</p>
<button onClick={() => deleteTodo(id)} className="delete-btn">
Delete
</button>
</div>
);
};
모든 상태를 Context로 관리하면 성능이 저하될 우려가 있음
→ 자주 변경되는 값(ex: 입력 필드 상태)은 useState로 관리하는 것이 좋음
'React > ReactThreeFiber' 카테고리의 다른 글
오브젝트 위치 조정 및 애니메이션 적용 (0) | 2025.03.14 |
---|---|
3D 오브젝트 불러오기 (0) | 2025.03.14 |
useEffect & useRef (2) | 2025.03.14 |
React로 사고하기 (1) | 2025.03.13 |
Component (0) | 2025.03.12 |