개발새발개발/React

[React] Context 사용해서 props 없이 편하게 데이터 전달하기

birdsfoot 2025. 2. 18.

 

 

 

 

 

Context

  • 컴포넌트간의 데이터를 전달하는 또 다른 방법
  • 기존의 Props가 가지고 있던 단점(Props drilling)을 해결
  • 굳이 부모컴포넌트에서 깊이 있는 자식 컴포넌트까지 갈 필요 없이 바로 가져다 사용 가능(Store와 비슷)

출처 : 인프런 한 입 크기로 잘라 먹는 리액트 강의

 

 

사용해보기

 

1. import createContext 

import {  createContext } from 'react';

 

 

2. Context 생성해서 export

export const TodoContext = createContext();

 

 

3. 사용할 자식 컴포넌트 감싸기

  return (
    <div className="App">
      <Header />
      <TodoContext.Provider value={{ todo, onCreate, onUpdate, onDelete }}>
        <Editor />
        <List />
      </TodoContext.Provider>
    </div>
  );
  • value에 넘겨줄 값 담기(여러개일 경우 객체로 주기)

 

 

 

4. context에서 값 가져오기

import { TodoContext } from '../App';
const Editor = () => {
  const { onCreate } = useContext(TodoContext); }
  • App.jsx에서 export한 context 변수 명을 import
  • useContext에 인수로 전달해주고, 구조분해할당을 이용해 필요한 값을 가져오기
  • `const data = useContext(TodoContext)` 와 같이 data에 전체를 할당해도 됨 

 

 

 

Context 분리하기

  • 한 context에서 모두 꺼내쓰면 context에서 전달하는 데이터 중 하나라도 수정되면
  • context를 사용하는 모든 컴포넌트가 함께 불필요한 리렌더링이 될 수 있음
  • 그러므로 변경될 수 있는 값(todos)과 변경되지 않는 값(onCreate, onUpdate, onDelete)을 구분하여 context를 생성하는 것이 좋음

출처 : 인프런 한 입 크기로 잘라 먹는 리액트

 

 

 

 

1. context 생성

export const TodoStateContext = createContext();
export const TodoDispatchContext = createContext();

 

 

2. 자식 컴포넌트 감싸기

  return (
    <div className="App">
      <Header />
      <TodoStateContext.Provider value={todo}>
        <TodoDispatchContext.Provider value={memoizedDispatch}>
          <Editor />
          <List />
        </TodoDispatchContext.Provider>
      </TodoStateContext.Provider>
    </div>
  );

 

  • 이때 onCreate, onUpdate, onDelete는 리렌더링 될 때마다 값이 갱신될 필요가 없으므로 useMemo를 활용해 마운트 될 때만 변하고 그뒤에는 변하지 않도록 설정
  •  그렇게 설정한 값을 value로 전해주면 최적화가 됨
  //리렌더링 방지
  const memoizedDispatch = useMemo(() => {
    return { onCreate, onUpdate, onDelete };
  }, []);

 

 

 

3. 자식 컴포넌트 수정

import { TodoDispatchContext } from '../App';

const Editor = () => {
  const { onCreate } = useContext(TodoDispatchContext);

 

  • useContext에서 받는 값 수정
import { TodoStateContext } from '../App';

const List = () => {
  const todo = useContext(TodoStateContext);

 

  • TodoStateContext에서는 객체가 아닌 'todo' 값 하나만 전달하고 있으므로 구조분해할당인 {todo}가 아닌 todo 로 값을 받음

댓글