본문 바로가기

프로그래밍 언어/React

React : Context API

반응형

context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다.

 

Context를 써야 하는 이유

1. props을 명시적으로 넘겨주고 있는 예시

class App extends React.Component {
  render() {
    return <Toolbar theme="dark" />;
  }
}

function Toolbar(props) {
  // Toolbar 컴포넌트는 불필요한 테마 prop를 받아서 ThemeButton에 전달해야 합니다.  
  // 앱 안의 모든 버튼이 테마를 알아야 한다면 이 정보를 일일이 넘기는 과정은 매우 곤혹스러울 수 있습니다.  
  return (
    <div>
      <ThemedButton theme={props.theme} />    
    </div>
  );
}

class ThemedButton extends React.Component {
  render() {
    return <Button theme={this.props.theme} />;
  }
}

  • Props(Properties): 부모 컴포넌트와 자식 컴포넌트 또는 한 컴포넌트 안에서 데이터를 다루기 위해 사용
  • 즉, 위에서 아래로 데이터가 흐름
  • 흐름을 비교적 알기 쉬워서 이해가 빠르게 된다는 장점
  • 여러 레벨 존재 시 → 매번 공통 부모 컴포넌트를 수정하고 하위 모든 컴포넌트에 데이터를 props로 전달하는 것은 매우 비효율적이라는 단점

 

 

2. context를 사용한 예시

  • 부모 컴포넌트로부터 자식 컴포넌트로 전달되는 데이터의 흐름과는 상관 없이 전역적(global)인 데이터를 다룰 때 사용
  • context를 사용하면 중간에 있는 엘리먼트들에게 props를 넘겨주지 않아도 됨.
  • 전역 데이터를 context에 저장한 후, 데이터가 필요한 컴포넌트에서 해당 데이터를 불러와 사용
// context를 사용하면 모든 컴포넌트를 일일이 통하지 않고도
// 원하는 값을 컴포넌트 트리 깊숙한 곳까지 보낼 수 있습니다.
// light를 기본값으로 하는 테마 context를 만들어 봅시다.

const ThemeContext = React.createContext('light');

class App extends React.Component {
  render() {
    // Provider를 이용해 하위 트리에 테마 값을 보내줍니다.    
    // 아무리 깊숙히 있어도, 모든 컴포넌트가 이 값을 읽을 수 있습니다.    
    // 아래 예시에서는 dark를 현재 선택된 테마 값으로 보내고 있습니다.    
    return (
      <ThemeContext.Provider value="dark">        
      	<Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// 이젠 중간에 있는 컴포넌트가 일일이 테마를 넘겨줄 필요가 없습니다.
function Toolbar() { 
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

class ThemedButton extends React.Component {
  // 현재 선택된 테마 값을 읽기 위해 contextType을 지정합니다.  
  // React는 가장 가까이 있는 테마 Provider를 찾아 그 값을 사용할 것입니다.  
  // 이 예시에서 현재 선택된 테마는 dark입니다.  
  static contextType = ThemeContext;
  render() {
    return <Button theme={this.context} />;  
    }
}

 

Context API

React에서 context를 사용하기 위해서는 context api를 사용해야 하며,  Context의 Provider와 Consumer를 사용해야 합니다.

  1. 공통 부모 컴포넌트에 Context의 Provider를 사용하여 데이터 제공
  2. 데이터를 사용하려는 컴포넌트에서 Context의 Consumer를 사용하여 실제로 데이터를 사용
  3. 로그인 데이터, 웹 내 사용자가 쓰는 설정 파일, 테마, 언어 등 다양하게 컴포넌트간 공유되어야 할 데이터로 사용하면 좋음

 

Context 사용법

React.createContext

import { createContext } from "react";

const MyContext = createContext(defaultValue);

React에서 Context를 생성하기 위해서는 createContext를 사용하여 Context를 생성

 

defaultValue

→ 전역 변수로 사용될 데이터의 초기값을 설정

트리 안에서 적절한 Provider를 찾지 못했을 때만 쓰이는 값

 

Context.Provider

<MyContext.Provider value={/* 어떤 값 */}>
class App extends Component {
  render() {
    return (
      <MyContext.Provider value={/* 어떤 값 */}>
        <Button/>
        <Title />
        <Message />
      </MyContext.Provider>
    );
  }
}

Context를 사용하여 전역 데이터를 사용하려면 공통 부모 컴포넌트에 Context의 Provider를 사용
Provider를 전달하는 변수는 꼭 value를 사용해야 함

전달받는 컴포넌트의 제한 수는 없음

provider에 하위 provider 배치가 가능하며, 그럴 경우 하위 provider 값이 우선시됨

 

Provider로 감싼 후, 그 하위에 있는 모든 컴포넌트(Button, Title, Message)

Provider의 value는 하위의 모든 컴포넌트에서 사용 가능

value 속성값을 지정하지 않았을 경우, context를 생성할 때 넘겼던 디폴트 값이 사용됨.

 

전역 데이터를 하위 컴포넌트에서 접근하는 방법

Consumer로 Context 접근하기

  • Provide의 value의 변경 사항을 구독
  • context에서 가장 가까운 provider의 value를 참조함
  • 단, 이 방법은 함수 컴포넌트에서만 사용 가능
import React from "react";
import MyContext from "./MyContext"

function Title() {
  return (
    <MyContext.Consumer>
      {(lang) => {
        const text = lang;
        return <h1>{text}</h1>;
      }}
    </MyContext.Consumer>
  );
}

 

useContext로 Context 접근하기

  • Hook의 useContext로 Context 객체의 value 가져올 수 있음
  • 단, 이 방법은 함수 컴포넌트에서만 사용 가능
import React, { useContext } from "react";
import MyContext from "./MyContext";

function Button() {
  const lang = useContext(MyContext);
  return <button>{lang}</button>;
}

 

contextType으로 Context 접근하기

  • Class의 contextType에 Context 객체 할당 가능
  • this.context로 해당 Context의 value 참조 가능
  • 단, 이 방법은 클래스 컴포넌트에서만 사용 가능
import React, { Component } from "react";
import MyContext from "./MyContext";

class Message extends Component {
  static contextType = MyContext;

  render() {
    const num = this.context;
    if (num === 1)
      return (
        <p>
          "Context provides a way to pass data through the component tree
          without having to pass props down manually at every level"
        </p>
      );
    else
      return (
        <p>
          "컨텍스트는 모든 레벨에서 일일이 props를 넘기지 않고도 컴포넌트 트리에
          걸쳐서 데이터를 전달할 수 있는 방법을 제공합니다."
        </p>
      );
  }
}

 

context API 장단점

장점

  • 기존에는 컴포넌트 간에 상태를 교로해야 하는 경우 무조건 부모 → 자식 흐름으로 props를 통해 전달해주었지만, Context API를 통해 더욱 쉽게 상태를 고류할 수 있게 됨
  • 프로젝트의 컴포넌트 구조가 복잡하고 전역적으로 많이 사용되는 데이터가 많으며, 컴포넌트 개수가 많다면 Context API 사용

 

단점

  • context api에서 상태 값을 변경하면, provider로 감싼 모든 자식 컴포넌트들이 리렌더링 됨.(업데이트)
  • React context를 사용하면 해당 컴포넌트는 해당 context가 없이는 재사용이 불가능
  • 따라서 단순하고 다루는 상태의 종류가 적다면 사용하지 말자!

 

 

 

참고 블로그

https://dev-yakuza.posstree.com/ko/react/context-api/

 

[React] Context API

React에서 데이터를 다루는 개념중 하나인 Context API를 사용하는 방법에 대해서 알아봅시다.

dev-yakuza.posstree.com

https://ko.reactjs.org/docs/context.html

 

Context – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

반응형

'프로그래밍 언어 > React' 카테고리의 다른 글

FCMToken이란? (1)  (0) 2022.11.18
Javascript VS Typescript  (0) 2022.11.07
React : cookie / localStorage / SessionStorage  (0) 2022.05.17
React의 기초  (0) 2021.08.11
자바스크립트의 기초  (0) 2021.08.11