Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

useContext 훅에 대하여 본문

🎨 프론트엔드/React.js

useContext 훅에 대하여

Chamming2 2021. 1. 5. 13:32

리액트에서는 일반적으로 상태를 위에서 아래로밖에 전달할 수 없지만, 컨텍스트(context)를 활용하면 전역으로 상태값을 활용할 수 있게 된다. (리액트의 컨텍스트는 자바스크립트와는 달리 '데이터 저장소' 라고 생각하면 된다.)

 

[context의 기본 사용법]

import React, { Component } from 'react'

// 컨텍스트(데이터 저장소) 생성
const MyContext = React.createContext(defaultValue);

// Provider 생성
<MyContext.Provider value={/* 전역으로 사용하고자 하는 값 */}>
  <하위 컴포넌트 1>
  <하위 컴포넌트 2>
  ...
</MyContext.Provider>

-----------------------------------------------------------

// <하위 컴포넌트> 에서
<MyContext.Consumer>
  {value => /* context 값을 이용한 렌더링 */}
</MyContext.Consumer>

1. 컨텍스트를 활용하기 위해서는 전역 값을 활용하고자 하는 컴포넌트를 Context.Provider로 감싼다.

2. 하위 컴포넌트에서는 Context.Consumer를 사용해 컨텍스트에 담긴 전역 값을 활용할 수 있다.

(이 때 Context.Consumer의 자식은 반드시 함수여야 하는데, 함수의 인자는 전역 값이며 리턴값은 렌더링할 리액트 노드가 된다.)

 

버튼을 클릭해 색상 테마를 변경하는 코드를 통해 컨텍스트를 활용하는 예를 살펴보자.

// UseContext.js
import React, { useContext, useState } from "react";
import ClassContextComponent from "./context/ClassContextComponent";

export const ThemeContext = React.createContext();

function UseContext() {
  const [darkTheme, setDarkTheme] = useState(false);

  const toggleTheme = () => {
    setDarkTheme((prevDarkTheme) => !prevDarkTheme);
  };

  return (
    <ThemeContext.Provider value={darkTheme}>
      <button onClick={toggleTheme}>Toggle Theme</button>
      <ClassContextComponent></ClassContextComponent>
    </ThemeContext.Provider>
  );
}

export default UseContext;
// ClassContextComponent.js
import { React, Component } from "react";
import { ThemeContext } from "../UseContext";

export default class ClassContextComponent extends Component {
  themeStyles(dark) {
    return {
      backgroundColor: dark ? "#333" : "#CCC",
      color: dark ? "#CCC" : "#333",
      padding: "2rem",
      margin: "2rem",
    };
  }

  render() {
    return (
      <ThemeContext.Consumer>
        {(darkTheme) => {
          return <div style={this.themeStyles(darkTheme)}>Class Theme</div>;
        }}
      </ThemeContext.Consumer>
    );
  }
}

React.createContext() 로 컨텍스트(데이터 저장소)를 생성한 뒤 ThemeContext.Provider로 하위 컴포넌트를 감싼 다음 하위 컴포넌트에서는 ThemeContext.Consumer를 통해 전역으로 관리되는 테마 값을 활용한 모습이다.

 

함수형 컴포넌트에서 useContext훅을 활용하면 코드를 보다 간결하게 작성할 수 있다.

 

[useContext 훅의 기본 형태]

import React, { useContext } from 'useContext';

// 훅을 사용할 때도 React.createContext로 컨텍스트를 생성하는 과정은 동일하다.
const MyContext = React.createContext(defaultValue);

const value = useContext(MyContext);

useContext 훅은 컨텍스트를 인자로 받아 컨텍스트에 담긴 (전역으로 관리할) 값을 반환한다.

따라서 클래스 컴포넌트에서 사용했던 Context.Consumer 없이도 간결하게 컨텍스트를 활용할 수 있게 되었는데, 코드로 살펴보자.

import React, { useContext, useState } from "react";
import FunctionContextComponent from "./context/FunctionContextComponent";

export const ThemeContext = React.createContext();

function UseContext() {
  const [darkTheme, setDarkTheme] = useState(false);

  const toggleTheme = () => {
    setDarkTheme((prevDarkTheme) => !prevDarkTheme);
  };

  return (
    <ThemeContext.Provider value={darkTheme}>
      <button onClick={toggleTheme}>Toggle Theme</button>
      <FunctionContextComponent></FunctionContextComponent>
    </ThemeContext.Provider>
  );
}

export default UseContext;
import React, { useContext } from "react";
import { ThemeContext } from "../UseContext";

function FunctionContextComponent() {
  const darkTheme = useContext(ThemeContext);
  
  const themeStyles = {
    backgroundColor: darkTheme ? "#333" : "#CCC",
    color: darkTheme ? "#CCC" : "#333",
    margin: "2rem",
    padding: "2rem",
  };
  return <div style={themeStyles}>Function Theme</div>;
}

export default FunctionContextComponent;

React.createContext() 로 컨텍스트를 생성하고 Context.Provider로 컨텍스트를 제공하는 것은 동일하다.

다만 함수 컴포넌트에서는 Context.Consumer와 자식 함수를 활용하는 대신, useContext 훅을 활용해 보다 직관적인 코드를 작성할 수 있다.

 

반응형

'🎨 프론트엔드 > React.js' 카테고리의 다른 글

useLayoutEffect 훅에 대하여  (10) 2021.02.15
defaultProps에 대한 짧은 고찰  (0) 2021.01.31
useRef 훅에 대하여  (1) 2021.01.01
useMemo 훅에 대하여  (0) 2020.12.30
Portal 사용하기  (0) 2020.12.28
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆