FrontEnd/React

[React] 리액트 컴포넌트간 데이터 전달 : Context 훅에 대한 정리 (feat. createContext + useContext)

모찌바라기 2024. 4. 20. 15:43
728x90
반응형

 

 

 

Context란?

 

1. useContext란?

 

React의 Context란 컴포넌트간의 데이터를 전달하는 방법이다.

props와는 달리 createContext훅과 useContext훅을 이용하여 컴포넌트간 데이터를 전달 할 수 있다.

 

 

2. useContext를 왜 사용하는걸까?

 

그럼 props를 이용해서 컴포넌트간 데이터를 전달하면 되는거 아닌가? 라는 생각이 들 수 있다.

근데 props에는 커다란 문제가 있었는데.. 자기 자식한테만 보낼 수 있다는 문제이다.. 

 

 

뭐 고작 그런거 가지고? 라고 할 수 있는데, 만약 자식컴포넌트가 엄청 많다면?  아래와 같은 문제가 발생한다..

 

 

 

자식의 자식의 자식의 자식까지 계속 props로 전달해야 한다. 즉 한번에 보내지 못한다는 문제..

이런 걸 Props Drilling이라고 한다.. 드릴로 땅을 파서 지하까지 내려가는 것처럼 보이기 때문..

 

이런 Props Drilling 문제를 해결하기 위해 우리는 오늘 배울 Context를 사용한다.

 

Context를 사용하는 경우

 

Context를 사용하는 경우 위 그림과 같이 아무 자식컴포넌트에게나 직접적으로 데이터를 전달 할 수 있다.

이제 Context의 기본적인 사용법과 효율적으로 사용할 수 있는 방법까지 알아보자..

 

 

Context 기본문법

 

createContext 훅을 이용하여 Context 생성

//createContext 훅 import
import { createContext } from "react";

// createContext 훅을 이용하여 Context 컴포넌트 생성
const MyContext = createContext();

// Context에 초기값을 부여할 수도 있음
// const MyContext = createContext({count: 0});

/* 생성한 Context는 컴포넌트이기 때문에 일반적인 컴포넌트를 사용하듯이 사용한다.
단 Provider 프로퍼티를 이용해야함.. <컴포넌트명.Provider>과 같이 작성하고
데이터를 전달 할 컴포넌트들을 감싸면 해당 컴포넌트에 걸쳐있는 모든 컴포넌트들에
데이터를 전할 할 수 있다. */
<MyContext.Provider value={{ count: 0 }}>
  <Child />
</MyContext.Provider>

 

 

useContext 훅을 이용하여 Context 사용

//useContext 훅을 import
import { useContext } from "react";
//createContext훅으로 생성 된 Context import
import { MyContext } from "../App.jsx";

//useContext 함수에 Context명을 파라메터로 넣어 Context 데이터를 사용
const { childData, setChildData } = useContext(MyContext);

 

대충 내용을 요약하자면

 

1. createContext훅을 이용하여 Context 컴포넌트 생성.

2. 데이터를 전달하고자 하는 컴포넌트를 <컴포넌트명.Provider data={}>와 같은 형식으로 감싸준다.

3. 데이터를 받고자 하는 컴포넌트에서 useContext훅을 이용하여 데이터를 받는다.

 

과 같은 로직을 통하여 데이터를 전달한다... 샘플코드를 보면 더 이해하기 쉬울 거 같다..

 

 

Context 샘플코드

 

App.jsx

import { useState } from "react";
import { Child1 } from "./todo/Child1.jsx";
import { createContext } from "react";

//Context 컴포넌트 생성 및 export
export const MyContext = createContext();

const App = () => {
  //테스트를 위한 state 생성
  const [childData, setChildData] = useState([
    { id: 1, data: "Child1 데이터입니다." },
    { id: 2, data: "Child2 데이터입니다." },
  ]);

  return (
    <>
      <div className="App">
        //Context컴포넌트의 Provider 프로퍼티로 자식컴포넌트(Child1)를 감쌈
        //data는 sate와 setState를 보냄
        <MyContext.Provider value={{ childData, setChildData }}>
          <Child1 />
        </MyContext.Provider>
      </div>
    </>
  );
};

export default App;

 

 

Child1.jsx

import { useContext } from "react";
import { MyContext } from "../App.jsx";
import { Child2 } from "./Child2.jsx";

export const Child1 = () => {
  //App.jsx에서 받은 state를 사용하기 위해 useContext훅으로 값을 받음
  const { childData, setChildData } = useContext(MyContext);
  return (
    <>
      //state값 사용
      {childData.find((child) => child.id == 1).data} <br></br>
      //자식 컴포넌트 Child2
      <Child2 />
    </>
  );
};

 

 

Child2.jsx

import { useContext } from "react";
import { MyContext } from "../App.jsx";

export const Child2 = () => {
  //App.jsx에서 state를 받기 위해 useContext 훅을 사용
  const { childData, setChildData } = useContext(MyContext);
  //App.jsx에서 받은 데이터를 사용
  return <>{childData.find((child) => child.id == 2).data}</>;
};

 

 

결과

 

 

대충 위 샘플코드의 로직을 그림으로 표현하면 아래와 같다..

 

 

기존의 props를 사용했다면 App.jsx에서 Child1.jsx로 먼저 데이터를 보내고, Child1.jsx에서 Child2.jsx로

데이터를 보내야 했겠지만, Context를 이용함으로써 App.jsx에서 바로 Child2.jsx까지 데이터를 전달 할 수 있게 되었다.

 

 

글이 길어져서 다음에 Context를 모듈로 분리하는 방법과 모듈로 분리하는 이유에 대해 정리해봐야겠다..

 

 

 

 

728x90
반응형