React/ReactThreeFiber

useContext

최 수빈 2025. 3. 14. 04:54

 

useContext

 

React의 Context API를 활용해 컴포넌트 트리 전체에서 데이터를 전달하는 방식

→ props 없이도 전역적으로 상태를 공유할 수 있음

→ 부모 컴포넌트에서 Context의 Provider를 설정하면, 해당 Provider 하위의 모든 컴포넌트에서 데이터 공유 가능

 

※ 전역 상태 관리와는 다름

Context Provider 내부의 컴포넌트에서만 상태 공유 가능

 

 

Context API 활용 예

  • 다크 모드 / 라이트 모드 테마 설정
  • 로그인 상태 관리 (Auth Context)
  • 언어 설정 (i18n, 다국어 지원)

 

useContext 사용법

 

  1. createContext로 컨텍스트 생성
  2. Context.Provider에서 value로 상태, 함수 전달
  3. 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