072DATA

`React` useContext ( prop Drilling 문제 해결 ) 본문

FrontEnd/React

`React` useContext ( prop Drilling 문제 해결 )

0720 2024. 8. 20. 22:45

안녕

 

 

오늘은 부모 -> 자식 -> 자식의 자식의 형태로 내려오면 나타나는 prop Drilling을

해결할 수 있는 Context API의 useContext를 사용하고 정리해봄

 

 

Prop drilling

 

리액트 애플리케이션에서 데이터 전달은 주로 props를 통해 이루어짐

하지만 컴포넌트 구조가 깊어질수록 데이터 전달 과정에서 Prop Drilling 문제가 발생할 수 있고

Prop Drilling은 데이터를 필요로 하지 않는 중간 컴포넌트가 단순히 데이터를 전달하기 위해

props를 받게 되는 비효율적인 구조를 의미함

이는 컴포넌트의 구조를 복잡하게 만들고, 유지보수와 디버깅을 어렵게 만듦

 

이 문제를 해결하기 위해 리액트는 Context API를 제공하고

Context API는 특정 컴포넌트 트리 내에서 전역적으로 상태를 관리하고 공유할 수 있음

 

 

Context API 주요 개념

Context API를 사용하면, 상태가 변경될 때 Context를 사용하는

모든 컴포넌트가 자동으로 리렌더링되어 상태를 공유하고 업데이트하는 작업이 매우 간단해짐

아래는 Context API의 세가지 주요 개념임

 

 

  • createContext: 새로운 Context를 생성하고  Context는 React 컴포넌트가 구독할 수 있는 값을 가짐

  • useContext: Context를 구독하고 해당 Context의 현재 값을 읽음 useContext를 사용하면 컴포넌트는
    Context.Provider가 제공하는 값을 쉽게 접근할 수 있음

  • Provider: Context를 구독하는 하위 컴포넌트들에게 값을 전달함  Provider는 value prop을 통해 전달할 데이터를 설정함

 

 

예시 코드

// FamilyContext 자바스크립트
import { createContext } from "react";
export const FamilyContext = createContext(null);

// GrandFather 컴포넌트
import React from "react";
import Father from "./Father";
import { FamilyContext } from "../context/FamilyContext";

const GrandFather = () => {
  const houseName = "스파르타";
  const pocketMoney = 10000;

  return (
    <FamilyContext.Provider value={{ houseName, pocketMoney }}>
      <Father />
    </FamilyContext.Provider>
  );
};

export default GrandFather;

// Father 컴포넌트
import React from "react";
import Child from "./Child";

const Father = () => {
  return (
    <div>
      <Child />
    </div>
  );
};

export default Father;

// Child 컴포넌트
import React, { useContext } from "react";
import { FamilyContext } from "../context/FamilyContext";

const Child = () => {
  const { houseName, pocketMoney } = useContext(FamilyContext);

  return (
    <div>
      나는 이 집안의 막내에요.
      <br />
      할아버지가 우리 집 이름은 <span style={{ color: "red", fontWeight: "900" }}>{houseName}</span>라고 하셨어요.
      <br />
      게다가 용돈도 <span style={{ color: "red", fontWeight: "900" }}>{pocketMoney}</span>원 만큼이나 주셨답니다.
    </div>
  );
};

export default Child;

 

 

 

 

Context API와 useContext를 사용하여 컴포넌트 간 데이터를 쉽게 공유하는 방법을 사용함

  • GrandFather 컴포넌트에서 houseName과 pocketMoney의 데이터를
    FamilyContext.Provider를 통해 자식 컴포넌트에 전달됨
  • Child 컴포넌트는 useContext를 사용하여 FamilyContext에서 값을 가져와 화면에 렌더링함

 

 

UseContext 주의점

 

useContext를 사용할 떄 provider에서 제공한 value가 달라지게 되면 
useContext를 사용하고 있는 모든 컴포넌트가 리렌더링 됨

 

 

 

마무리

리액트를 사용하면서 복잡한 트리 구조에서 내려오는 props가 버겁다고도 생각했는데

useContext를 사용해 prop drilling을 해결하여 효율적인 데이터 전달과 관리가 가능할 것 같다

나중에 리덕스를 배우게 되면 이 개념들이 매우 중요하다고 하셔서 정리해보았다. ㅎㅇㅌ