Props Drilling의 해결 : Context API

NohWookJin·2023년 4월 16일
0

React 

목록 보기
1/3

Context API란 무엇일까?

Context API란 전역 상태 관리를 하기 위해서 사용합니다. 먼저 기존 리액트에서 Context API와 Redux와 같은 상태 관리 라이브러리가 없을 때 어떻게 최상위 컴포넌트와 최하단 컴포넌트가 데이터를 주고 받는지 생각해볼 필요가 있습니다. 먼저 Props Drilling에 대한 개념을 살펴봐야 합니다.

Props Drilling을 알아보자

Props Drilling이란 props를 오로지 하위 컴포넌트에 전달하는 용도로만 쓰는 상황을 의미합니다. React Component 트리의 한 부분에서 다른 부분으로 데이터를 전달하는 과정에서 자주 발생합니다.

다음과 같은 상황에서 예시를 들겠습니다.

1. G 컴포넌트는 전역 상태를 업데이트 시킨다.
2. F 컴포넌트와 J 컴포넌트는 업데이트 된 상태를 렌더링시킨다.

App이 지닌 value 값이 F, J 컴포넌트에 전달하려면 여러 컴포넌트를 거쳐야 합니다.
또한 G 컴포넌트에 상태 업데이트 함수를 전달하는 경우 또한 마찬가지입니다.

[F] App => A => B => F
[J] App => H => J

[G] App => A => B => E => G

위와 같은 방식으로 props를 전달하면 불필요한 과정이 너무 많습니다. 또한 이러한 방식은 유지 보수성이 매우 낮을 수 밖에 없습니다.
이러한 Props Rendering 문제를 어떻게 해결해야 할까요? 답은 전역적으로 상태 관리를 하면 된다 입니다.
다음과 같이 Context API를 사용하면 됩니다.

위와 같이 Context를 만들어서 안에 데이터를 관리한다면 각 컴포넌트에 원하는 값을 전달할 때 매우 수월합니다. 또한 유지 보수성도 높아집니다.

Context API를 어떻게 사용할까?

Context API를 사용할 때는 세 가지를 기억하면 됩니다.

  • createContext
  • Provider
  • Consumer
1. 새로운 context를 createContext 함수로 만들어주고 파라미터에는 해당 context의 default state를 지정해줍니다.
2. 사용하고자 하는 Component에서 Consumer 사이에 Render Props 패턴을 사용합니다.
3. Provider로 Context의 value값을 변경합니다. 이때 Provider는 Consumer를 감싼 형태여야만 합니다.
주의) createContext에서 파라미터로 default state를 지정해주었는데, 이 값은 Provider를 사용하지 않았을 때만 사용됩니다!

동적으로 Context API를 사용해보자

Context의 value에는 상태 값 뿐만 아니라 함수를 전달해줄 수도 있는데요. 앞선 예시에서 G 컴포넌트에 상태 업데이트 함수를 전달할 때처럼 함수를 전달할 수 있습니다.
함수를 전달할 때는 다음과 같은 방식으로 전달합니다.

Provider의 value에 상태는 state로, 업데이트 함수는 actions로 묶어서 전달합니다.
createContext의 기본값 또한 Provider의 value에 넣는 객체의 형태와 일치시켜 줍니다.
<contexts/theme.js>

import {createContext, useState} from 'react';

const ThemeContext = createContext({
	state { color: 'black', bgColor: 'white' },
    actions: {
    	setColor: () => {},
        setBgColor: () => {},
    }
})

const ThemeProvider = ({children}) => {
	const [color, setColor] = useState('black');
    const [bgColor, setBgColor] = useState('white');
    
    const value = {
    	state : {color, bgColor},
        actions: {setColor, setBgColor}
    };
    
    return (
    	<ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
    );
}

const {Consumer: ThemeConsumer} = ThemeContext;

export {ThemeProvider, ThemeConsumber, ThemeConsumer}
export default ThemeContext;

Consumer 꼭 사용해야 하나?

리액트에 내장되어 있는 Hooks 중 useContext라는 Hook을 사용한다면 Consumer를 사용할 필요 없이, 필요로 하는 데이터를 사용할 수 있습니다.

const { state } = useContext(#만든 Context)

useContext 방식은 함수를 전달하는 Render Props 패턴이 불편할 때 사용하면 좋습니다.
하지만 오직 함수형 컴포넌트에서만 사용이 가능합니다.

Context API와 Redux 언제 어떤 것을 사용하면 좋을까?

  • 전역적으로 여기저기 사용되는 상태가 있고 컴포넌트의 개수가 많아질 때 사용하면 좋습니다.
  • 단순한 전역 상태 관리라면(테마 등) Context API로 해결하는 것이 좋습니다.
  • 리액트 v16.3에서 Context API가 개선되었습니다. 이전에는 주로 리덕스를 사용하여 전역 상태를 관리했습니다.
  • 리덕스는 더욱 향상된 성능, 미들웨어 기능, 리덕스 개발자 도구, 높은 유지 보수성을 제공합니다.
    때문에 복잡한 전역 상태 관리 혹은 프로젝트 규모에서는 리덕스와 같은 라이브러리가 더 나은 선택이 됩니다.

해당 글은 리액트를 다루는 기술(김민준, 벨로퍼트)을 정리한 요약본입니다.

  • 리액트를 다루는 기술 - Context API
profile
프론트엔드 개발을 공부하고 있습니다.

0개의 댓글