React 상태관리, Context API로

휴먼스케이프

안녕하세요. 휴먼스케이프에서 개발자로 일하고 있는 Hugh 입니다.

React를 사용하는 개발자라면 누구나 상태관리 라이브러리에 대해서 고민을 해봤을 것 입니다.

오늘은 상태관리 라이브러리 중 하나인 Context API를 소개하겠습니다.

Context API가 맘에 들었던 이유를 한 마디로 줄여보면, 심플합니다.

Redux를 사용하려면 알아야 할 개념들이 있고, 설치해야 할 라이브러리들이 많습니다. 그러면서 자연스럽게 폴더 구조도 복잡해 집니다. 하지만 Context API는 React 내장 라이브러리라서 설치할 것도 없고, 알아야할 개념도 없고 Context API의 사용법만 익히면 됩니다.

v16.3부터 사용하기 쉽게 개선된 Context API의 사용법을 알아보겠습니다.

react의 createContext 메소드를 사용하여 Context를 생성하는 기본 구조는 다음과 같습니다.

import { createContext } from 'react';
const ColorContext = createContext({ color: 'black' });
export default ColorContext;

위의 createContext 메소드는 Context의 Consumer와 Provider를 생성해줍니다. Consumer를 이용하여 아래와 같이 color 값을 조회할 수 있습니다.

import ColorContext from './context/color';
const ColorBox = () => {
  return (
    
      {value => 
{value.color}
}
); };

아래와 같이 Provider를 이용하면 state 값을 변경할 수 있습니다.

import ColorBox from './component/ColorBox';
import ColorContext from './context/color';
const App = () => {
  return (
    
      
    
  );
};

위 예제는 고정된 값만 사용이 가능합니다. 하지만 우리는 항상 동적으로 상태관리를 하기때문에 Context 값을 업데이트할 수 있어야 하고, 그러기 위해선 다시 아래와 같이 작성합니다.

import React, { createContext, useState } from 'react';
// Context에서 관리해줄 상태값과 메소드들을 정의합니다.
const UserContext = createContext({
  state: {
    userInfo: {},
    swiperIndex: 0
  },
  actions: {
    setUserInfo: () => {},
    setSwiperIndex: () => {}
  }
});
// Provider를 rendering하면서 상태값과 메소드들을 전달합니다.
const UserProvider = ({ children }) => {
  const [userInfo, setUserInfo] = useState({});
  const [swiperIndex, setSwiperIndex] = useState(0);
const value = {
    state: { userInfo, swiperIndex },
    actions: { setUserInfo, setSwiperIndex }
  };
return (
    
      {children}
    
  );
};
const UserConsumer = UserContext.Consumer;
export { UserProvider, UserConsumer };
export default UserContext;

위에서 생성한 Provider로 아래와 같이 타겟 컴포넌트를 감싸면, 해당 컴포넌트 안에서 Consumer를 사용하여 state와 actions를 전달받아 사용할 수 있습니다.

import { UserProvider } from './context/User';
const App = () => {
  return (
    
      
    
  )
}

Context.Consumer 로 감싸고 그 안에서 state를 조회하는 것이 불편하다면, hooks의 useContext를 사용하면 더욱 간단하게 Context에 접근할 수 있습니다.(이 방법을 추천)

import { useContext } from 'react';
const ColorBox = () => {
  const [state, actions] = useContext(UserContext);
  ...
}

느끼셨겠지만 Provider는 redux의 store와 비슷한 역할을 합니다. 하지만 Context의 Provider는 여러 개를 생성하여 사용할 수 있습니다. 따라서 예제의 UserProvider에서는 User와 관련된 상태와 로직만 관리하고, 다른 모델과 관련된 상태와 로직은 Provider를 추가적으로 생성하여 개별적으로 관리할 수 있습니다.

Provider 수가 많아지면 아래와 같은 모습을 하게되는데요.

import { UserProvider } from './context/User';
import { ProviderA } from './context/A';
import { ProviderB } from './context/B';
import { ProviderC } from './context/A';
const App = () => {
  return (
    
      
        
          
            
          
        
      
    
  );
};

이게 보기 좋지 않다면 아래와 같이 GlobalProvider를 만들어 Provider 들을 모으고, GlobalProvider로 App을 감싸는 것도 나쁘지 않습니다.

const GlobalProvider = ({ children }) => {
  return (
    
      
        {children}
      
    
  );
};
...

  

여기까지 Context API 사용방법에 대해 간략하게 알아보았습니다. 감사합니다.

기업문화 엿볼 때, 더팀스

로그인

/