bytrustu tech blog

[React] Context API 이해하기 본문

React

[React] Context API 이해하기

bytrustu 2023. 1. 1. 00:23

 

전역 상태관리

 

리액트를 다루는 기술 Context API 전역 상태 흐름 그림

링크

React의 Context API 는 컴포넌트 트리 안에서 전역적으로 접근 가능한 데이터를 관리할 수 있는 방법을 제공한다.

이것은 컴포넌트가 상위 컴포넌트에게서 Props를 전달받아야 하는 경우보다 편리하게 전역 상태를 관리할 수 있게 해 준다.

 

Props로 데이터를 전달할 경우 발생할 수 있는 문제

 

리액트는 컴포넌트에게 데이터를 전달해주어야 할 때 Props를 통해 전달한다.

부모와 자식 컴포넌트 간의 depth가 깊어질수록 여러 컴포넌트를 거쳐 연달아서 Props를 설정해주어야 하는 불편함이 있다.

이러한 경우를 Props Drilling이라고 부른다.

Context API는 이와 같은 문제해결을 하기 위해 Context를 생성하여 컴포넌트 계층 간의 데이터 전달을 쉽게 해주는 기능을 한다.

 

 

사용법

 

Context API를 사용하기 위해서는 먼저 React.createContext 함수를 사용해서 context 객체를 생성해야 한다.

이 객체는 Provider와 Consumer 컴포넌트를 제공한다.

context의 값을 사용하기 위해서는 가장 가까운 Provicer 컴포넌트를 찾아서 그 안에서 Consumer를 사용해야 한다.

 

Provider

Provider 컴포넌트는 context 값을 제공하는 역할을 한다. 이 컴포넌트를 사용하기 위해서는 value prop을 사용해서 context 값을 전달해야 한다. Provider 컴포넌트가 컴포넌트 트리 상에서 있는 곳까지 context 값을 전파할 수 있기 때문에, 이 컴포넌트는 전역 상태를 관리하는 역할을 할 수 있다.

 

Consumer

Consumer 컴포넌트는 context 값을 소비하는 역할을 한다. 이 컴포넌트는 컴포넌트의 children 속성으로 함수를 전달하였고, 이 함수의 인자로 context의 값이 전달된다. 이 함수는 context의 값을 사용하여 컴포넌트를 렌더링 한다.

Consumer 컴포넌트는 가장 가까운 Provider 컴포넌트의 값을 읽어오기 때문에, context의 값을 사용하고 싶은 컴포넌트가 Provider 컴포넌트 안에 있지 않으면 Consumer 컴포넌트를 사용할 수 없다.

const MyContext = React.createContext();

function App() {
  return (
    <MyContext.Provider value={/* context 값 */}>
      <MyContext.Consumer>
        {value => /* context value 값을 기반으로 렌더링 된다. */}
      </MyContext.Consumer>
    </MyContext.Provider>
  );
}

 

useContext hook

React.useContext은 컴포넌트 트리에서 context의 값을 쉽게 접근할 수 있도록 해주는 기능을 제공한다.

일반적으로 Context API를 사용할 때는 Consumer 컴포넌트를 사용하여 context의 값을 접근하지만, useContext hook을 사용하면 Consumer 컴포넌트를 사용하지 않고도 context의 값에 접근할 수 있다.

import {createContext, useState} from "react";

const ColorContext = createContext({
    state: { color: 'black', subColor: 'red' },
    actions: {
        setColor: () => {},
        setSubColor: () => {},
    }
});

const ColorProvider = ({ children }) => {
    const [color, setColor] = useState('black');
    const [subColor, setSubColor] = useState('red');

    const value = {
        state: { color, subColor },
        actions: { setColor, setSubColor }
    };

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

const { Consumer: ColorConsumer } = ColorContext;
export { ColorProvider, ColorConsumer };
export default ColorContext;
const ColorBox = () => {
    const { state } = useContext(ColorContext);
    return (
        <>
            <div style={{ width: "64px", height: "64px", background: state.color }}>
                {state.color}
            </div>
            <div style={{ width: "64px", height: "64px", background: state.subColor }}>
                {state.subColor}
            </div>
        </>
    );
};

 

Context API와 전역 상태 관리 라이브러리의 차이

 

React는 다양한 전역 상태 관리 라이브러리가 있다. (대표적으로 Redux, Mobx, Recoil,... )

Context API로도 전역 상태를 관리할 수 있는데 전역 상태 관리 라이브러리를 쓰는 이유가 뭘까?

Context API는 상태 관리를 위한 기능을 제공하지 않는다. 컴포넌트 계층 간의 데이터 전달을 쉽게 해주는 기능만 제공하고, 상태가 변경되면 하위 컴포넌트들이 전부 리렌더링 된다.

반면에 상태 전역 상태 관리 라이브러리는 상태 관리를 더욱 편하게 해주는 기능들을 제공하여 일관성과 유지보수 면에서 쉬워진다.

예를 들면 Redux의 경우, actionreducer를 사용하여 상태 업데이트 로직을 컴포넌트 밖으로 분리할 수 있으며, 상태가 업데이트되면 실제로 의존하는 값이 바뀔 때만 컴포넌트가 리렌더링 되도록 최적화를 해준다.

 

 

마무리

 

Context API와 전역 상태 관리 라이브러리의 차이점에 대해서 명확하게 알지 못했었다.

어떤 경우에 구분해서 써야 할지?

그리고 두 개의 명확한 차이가 무엇인지?

결국엔 전역 상태 라이브러리도 전역 상태를 관리하게 쉽게 하는 것이고, 상황에 맞게 사용하면 좋을 것 같다. 🤔

Comments