[React] Props Drilling 과 Context API

Brandon·2023년 5월 26일
2

props drilling은 무엇이고 어떻게 피할 수 있나요?

상위 컴포넌트의 데이터를 하위 컴포넌트에 props로 전달하는 방식은 아주 좋은 방법입니다.

그러나 하위 컴포넌트에서 직접 그 데이터를 사용하지 않고 하위 컴포넌트의 하위 컴포넌트에서 사용하게 된다면, 그것이 하위의, 하위의, 하위의 컴포넌트가 사용하는 깊이까지 내려간다면 원래 컴포넌트에서 해당 props가 어떤 의미인지, 어떤 맥락에서 쓰이는지 찾기 어려울 것입니다. 또, 중간에 props를 전달만 해주는 컴포넌트들은, 이렇게 전달만 하는 props가 한두개라면 괜찮지만 많아진다면 관심사의 분리가 이뤄지지 않고 지저분한 코드가 될 수 있습니다.

이렇게, 연속된 props 전달을 통해 원 컴포넌트와 props를 사용하는 하위 컴포넌트 사이가 멀어지면서 생기는 현상을 ‘props drilling’이라고 합니다. 마치 props가 원 컴포넌트에서 드릴을 파고 하위의 하위 컴포넌트까지 깊게 들어가는데서 유래했습니다.

이러한 Props drilling을 피할 수 있는 방법으론 무엇이 있을까요?

1. 전역상태관리 사용

React에서 직접 만들고 권장하는 Context API, 그 외 Redux, Recoil 등의 상태관리 라이브러리가 있습니다. 처음에 전역적으로 관리가 필요한 상태를 상위 컴포넌트에서 등록해주면, 해당 상태가 필요한 컴포넌트에서 상태를 불러오는 코드를 통해 props drilling 없이 접근할 수 있습니다.

2. { Children } 활용

Children을 활용하여 props 전달을 깔끔하게 해낼 수 있습니다.

import './App.css';
import { Boy } from './Boy';
import { Parent } from './Parent';

function App() {
  const userName = 'Crocs';
	
	const Parent = ({ children }) => {
	  return (
	    <div>
	      {children}
	    </div>
		);
	};

	export const Boy = ({ userName }) => {
	  return (
	  <div>
	    <p>
	      `I'm a boy, My name is {userName}`
	    </p>
	  </div>
	  );
	};

  return (
    <div className="App">
      <Parent>
        <Boy userName={userName} />
      </Parent>
    </div>
  );
// 결과 : `I'm a boy, My name is Crocs`
}

export default App;
  • 기존 방식대로라면 App → Parent → Boy 형태로 userName props를 전달해야했습니다.
  • 하지만 예제에서 Parent의 Children을 활용함으로써 App 컴포넌트에서 Boy 컴포넌트로 바로 userName props를 전달할 수 있었습니다.

React context는 무엇인가요?

React Context는 React에 내장된 전역 상태관리 도구로써, 별도의 라이브러리 설치 없이 사용가능하며, props 전달없이 특정 상태 값을 공유할 수 있습니다.

Context 생성

import { createContext } from 'react';

const Context = createContext(defaultValue);

Context 사용

import { useContext } from 'react';
import { context } from './context.js';

export default function Section({ children }) {
  const state = useContext(Context); // useContext로 상태 불러오기
  return (
    <section className="section">
      <Context.Provider value={level + 1}> // Provider로 감싸주기
        {children}
      </Context.Provider>
    </section>
  );
}

useContext를 통해 context 값을 불러와, Context.Provider로 사용하려는 컴포넌트에 감싸줍니다. Provider 는 반드시 value 속성값이 필요한데, 컴포넌트 간에 공유하고자 하는 값을 넣어주면 됩니다.


Context API를 사용하면 좋은 경우는 언제인가요?

  1. Theming
    다크모드와 같이 사용자가 테마 변경을 할 수 있는 어플리케이션의 경우, 전체 컴포넌트에 Theme Context Provider를 사용한다면 편리하게 테마를 조정할 수 있습니다.
  2. Current account
    많은 경우에서 컴포넌트가 로그인된 사용자를 식별하는 일에 관심이 있습니다. 그럴 때 nesting하는 Provider를 통해 현재 계정에 대한 상태정보를 전달하면 효율적입니다.
  3. Routing
    많은 라우팅 솔루션들이 내부적으로 Context 를 활용하고 있습니다. 그것이 라우팅 링크들이 어떻게 자신이 활성화된 상태인지, 아닌지 알 수 있는 이유입니다.
  4. Managing state
    어플리케이션이 성장하면서 전역 상태 관리가 필요할 일이 점점 늘어납니다. 이때, useReducer와 Context API를 결합하여 사용하면 더욱 편리하게 전역 상태관리가 가능합니다.

참고한 글

React 공식문서

profile
메인 블로그 이관하였습니다. https://dr-dev.tistory.com/

0개의 댓글