[React] props 계속 전달하기 귀찮을 때 #useContext

일반적으로 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달할 때 `props`를 사용해서 전달한다. 하지만 깊이가 깊어질 수록 prop drilling이 발생한다. 쉽게 말해 드릴로 뚫어버리듯 prop의 전달이 너무 깊어진다는 의미이다. 

 

아래 발로 만든 구조를 보자. 

prop drilling

 

대충 저런 구조에서 더 타고 내려가면 어떤 문제가 발생할까? 사실 아무런 문제도 발생하지 않는다. 물론 컴퓨터가 해석 할 때 아무 문제가 생기지 않는다는 것이고, 사람이 인지하는데는 어려움이 발생할 수 있다. 

 

문제점

  • 깊이가 깊어질수록 어떤 컴포넌트로부터 props가 내려왔는지 파악이 어렵다. 
  • 특정 컴포넌트에서 오류가 발생할 경우 디버깅이 어려워진다.

 

prop drilling의 예시 코드를 작성해보고 후에 context를 사용해서 리팩토링을 진행해보자. 간단한 구조이다. 할아버지 컴포넌트, 아빠 컴포넌트, 자식 컴포넌트를 생성하고 할아버지에서 자식 컴포넌트로 props를 전달해보자.

 

할아버지 컴포넌트

const GrandFather = () => {

    const houseName = '좋은 가문';
    const pocketMoney = 10000;

    return (
        <Father houseName={houseName} pocketMoney={pocketMoney} />
    )
}

 

아빠 컴포넌트

const Father = ({ houseName, pocketMoney }) => {
    return (
        <Child houseName={houseName} pocketMoney={pocketMoney} />
    )
}

 

자식 컴포넌트

const Child = ({ houseName, pocketMoney }) => {
    return (
        <div>
            나는 이 집안의 막내다.
            <br />
            할아버지가 우리 집 이름은 {houseName} 이라고 하셨다.
            <br />
            용돈은 {pocketMoney} 원 받았다.
        </div>
    )
}

 

위의 코드 구조에서 문제될 건 없지만 그래도 굳이 뽑아보자면 Father 컴포넌트가 불필요한 작업을 하고 있는 것 같다. Father 컴포넌트는 `houseName`과 `pocketMoney` 가 필요 없는데 전달만 해주고 있을 뿐이다. 저런 불필요한 작업을 context를 이용해서 변경을 시켜보자. (아래에서)

 

💡 context API

context를 사용하면  특정 영역 안에서 State를 공유할 수 있게 된다.

 

context 개념들

  • `createContext`: context를 생성한다. 
  • `useContext`: context를 구독하고 해당 context의 현재 값을 읽는다.
  • `Provider`: context를 하위 컴포넌트에 전달한다. 

 

이번엔 위에서 작성했던 코드를 context를 사용해서 변경해보자. 우선 `FamilyContext.js` 파일을 생성한다. 파일 위치는 `src/context` 하위에 생성했다. 

 

FamilyContext.js

import { createContext } from "react";

export const FamilyContext = createContext(null);

createContext의 초기값은 우선 `null` 로 지정했다.

 

할아버지 컴포넌트

import { FamilyContext } from '../context/FamilyContext';

const GrandFather = () => {

    const houseName = '좋은 가문';
    const pocketMoney = 10000;

    return (
        <FamilyContext.Provider value={{houseName,pocketMoney,}}>
            <Father />
        </FamilyContext.Provider>
    )
}
  • 방금 생성한 `FamilyContext`  를import한다.
  •  `FamilyContext`를 공유할 컴포넌트들을 감싸주면 그 내부의 컴포넌트들은 전부 context를 공유하게 된다.
  • `FamilyContext`안에서 공유할 value를 전달해준다.
    • 이때 초기값으로 `null`을 전달한 부분이 value값으로 반영 된다. 

 

아빠 컴포넌트

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

props를 받아서 전달하는 코드가 필요 없어졌다. 지워버리면 된다.

 

자식 컴포넌트 

import React, { useContext } from 'react'
import { FamilyContext } from '../context/FamilyContext'

const Child = () => {
    const data = useContext(FamilyContext);
//    const { houseName, pocketMoney } = useContext(FamilyContext);
    return (
        <div>
            나는 이 집안의 막내다.
            <br />
            할아버지가 우리 집 이름은 {data.houseName} 이라고 하셨다.
            <br />
            용돈은 {data.pocketMoney} 원 받았다.
        </div>
    )
}
  • `useContext`와 `FamilyContext`를 import 한다
  • `useContext`의 인자로 공유할 context('FamilyContext')를 전달 한다. 
  • 편하게 쓰면 된다. 

댓글

Designed by JB FACTORY