Frontend/React

React 리액트 - useContext()

Ayel 2025. 12. 29. 21:57

 

 

context

 

 

리액트의 컨텍스트(Context)

 

- Context: 컨테이너 내에서 컨텍스트로 둘러싸인 컴포넌트 사용가능한 전역변수라고 이해할 수 있다
- Provider(공급자) -> Consumer(수요자)

 

Context API란?


- Props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 처리할 수 있도록 제공해주는 API
- 리액의 내장 API(16버전 이상) 중 하나
-> 내장되어 있기 때문에 별도로 설치하지 않아도 사용 가능

 


Props의 드릴링


- 드릴링: 부모 컴포넌트부터 최하위 컴포넌트까지 Props를 보내는 과정
-> A.jsx ~ Z.jsx까지 있다고 가정할 때 부모 A컴포넌트부터 최하위 Z컴포넌트까지 Props를 보내는 과정

 


Context API의 사용


- 변화가 없는 것. 즉 다크모드 화이트모드 등 값이 선언되어 있는 상태로 변화가 없는 상태의 변수를 지정할 때 사용
- Context는 변화를 시켜주는 API가 아니다
- 변화를 주면 안되지만 혹시나 변화를 생길것을 대비하여 만들어져 있다

 


Context의 단점


- Provider 컴포넌트는 value Props를 받아서 하위 컴포넌트에게 전달한다
- value가 업데이트 되었을 때 Context로 감싸진 모든 컴포넌트가 리랜더링 된다

 

 

context 기본 구조

 

 

 

드릴링 상태의 컴포넌트 구조를 해소하기 위해

context를 사용

 

 

 

 

<CharContainer.jsx>

import React from 'react';
import A from './A';
import CharContext from './CharContext';

const CharContainer = () => {
  return (
    <CharContext.Provider value={{color: "red", fontSize: "50px"}}>
      <A />
    </CharContext.Provider>
  );
};

export default CharContainer;<A />

 

 

<A.jsx>

import React from 'react';
import B from './B';

const A = () => {
  return (
    <div>
      <B />
    </div>
  );
};

export default A;

 

 

<B.jsx>

import React from 'react';
import C from './C';
import CharContext from './CharContext';

const B = () => {
  return (
    <div>
      <CharContext.Consumer>
        {
          ({fontSize}) => {
            <h1 style={{fontSize}}>
              B: Context 활용해보기
            </h1>
          }
        }
      </CharContext.Consumer>
      <C />
      <button>B: 버튼을 누르면 글자 크기 변경</button>
    </div>
  );
};

export default B;

 

 

<C.jsx>

import React from 'react';
import CharContext from './CharContext';

const C = () => {
  return (
    <div>
      <CharContext.Consumer>
        {(context) => {
          console.log("context", context)
          return <p style={{color: context.color}}>C: REACT context API</p>
        }}

      </CharContext.Consumer>
    </div>
  );
};

export default C;

 

 

- context를 사용해 컨테이너의 스타일을 불러옴

-> A>B>C 순서대로 드릴링하지 않고 상위의 컨테이너를 불러올 수 있음

 

 

<결과화면>

 

 

useContext()

 

 

이전의 구조에서는 useState()사용이 어려움

-> 컨텍스트를 이용해 상태를 바꾸는 방법

 

 

버튼을 누르면 글자 크기 변경

 

 

<FontContext.js>

import { createContext, useState } from "react";

const FontContext = createContext({
  state: { fontSize: ""},
  actions: { setFontSize: () => {}}
})

export const FontProvider = ({children}) => {

  const [fontSize, setFontSize] = useState("2rem")

  const value = {
    state: { fontSize: fontSize },
    actions: { setFontSize: setFontSize }
  }

  return (
    <FontContext.Provider value={value}>
      {children}
    </FontContext.Provider>
  )

}

export default FontContext;

 

 

<FontContainer.jsx>

import React from 'react';
import FontParent from './FontParent';
import { FontProvider } from './FontContext';

const FontContainer = () => {
  return (
    <div>
      <FontProvider>
        <FontParent />
      </FontProvider>
    </div>
  );
};

export default FontContainer;

 

 

- Provider로 하위 컴포넌트를 감싸 불러옴

-> FontProvider 안에 있는 모든 컴포넌트는 value에 담긴 데이터를 직접 꺼내서 쓸 수 있다

 

 

<FontParent.jsx>

import React from 'react';
import FontChild from './FontChild';

const FontParent = () => {
  return (
    <div>
      <FontChild />
    </div>
  );
};

export default FontParent;

 

 

- 드릴링 발생

 

 

<FontChild.jsx>

import React, { useContext } from 'react';
import FontContext from './FontContext';

const FontChild = () => {

  // useContext 
  const {state, actions} = useContext(FontContext)
  const {fontSize} = state

  return (
    <div>
      <h1 style={{fontSize}}>useContext() 활용</h1>
      <button onClick={() => {
        actions.setFontSize("100px")
      }}>글자 크기 바꾸기</button>
    </div>
  );
};

export default FontChild;

 

 

- useContext() 사용이 가능해짐

-> useContext()로 useState()의 value값을 공유받아 사용한다

 

=> FontProvider 안에 있는 모든 컴포넌트는 value에 담긴 데이터를 직접 꺼내서 쓸 수 있으므로

=> FontChild는 props 없이도 fontSize에 접근 가능

 

 

<결과화면>

 

 

- 버튼을 누르면 글자가 커지게 된다

 

 

<기능추가>
사용자가 글자크기를 입력하고 엔터를 누르면 글자크기 변경
글자크기 입력 예시: 200px

 

 

<FontParent.jsx>

import React, { useContext } from 'react';
import FontChild from './FontChild';
import FontContext from './FontContext';

const FontParent = () => {

  const {state, actions} = useContext(FontContext)
  const {fontSize} = state
  const {setFontSize} = actions

  const handleFontSizeOnKeyDown = (e) => {
    if(e.key === "Enter"){
      setFontSize(e.target.value)
    }
  }

  return (
    <div>
      <FontChild />
      <h2 style={{fontSize}}>
        context 글자 크기 적용
      </h2>
      <input type="text" onKeyDown={handleFontSizeOnKeyDown} />
    </div>
  );
};

export default FontParent;

 

 

- 이전의 방식과 마찬가지로 useContext()를 사용해

fontContext.js의 기능을 FontParent.jsx에서 바로 사용 가능

 

 

<결과화면>