codinghatso

useContext - React Hooks 본문

WEB/React

useContext - React Hooks

hatso 2023. 11. 3. 00:55

React에서 제공해 주는 Context API에 대해서 정리해 봅시다.

React가 props를 내려줘 상위 컴포넌트의 요소를 하위 컴포넌트에서 가져다가 사용하는 상황에서 너무 많은 컴포넌트를 통과하여 전달하는 것을 막고자 Context를 사용합니다

 

기존의 React의 props를 활용해 전역데이터를 사용했을 때 도중에 오류가 발생했다면 모든 컴포넌트에서 오류가 발생하는 현상이 나타날 것이며, 오류를 수정하는 것 또한 엄청난 작업이 될 것입니다.

 

context를 사용하기 전에 고려할 것

  • context의 주된 용도는 다양한 레벨에 배치된 많은 컴포넌트에게 데이터를 전달하는 것입니다. context를 사용하면 컴포넌트를 재사용하기가 어려워지므로 꼭 필요할 때만 사용합시다.
  • prop drilling을 피하기 위한 목적이라면 Component Composition (컴포넌트 합성)을 먼저 고려해 보자

 

예를 들어 여러 단계 아래에 있는 Link와 Avatar 컴포넌트에게 user와 avatarSize라는 props를 전달해야 하는 Page 컴포넌트를 생각해 봅시다.

<Page user={user} avatarSize={avatarSize} />
// ... 그 아래에 ...
<PageLayout user={user} avatarSize={avatarSize} />
// ... 그 아래에 ...
<NavigationBar user={user} avatarSize={avatarSize} />
// ... 그 아래에 ...
<Link href={user.permalink}>
  <Avatar user={user} size={avatarSize} />
</Link>

실제로 사용되는 곳은 Avatar컴포넌트뿐인데 props를 여러 단계에 걸쳐 보내줘야 한다는 게 번거로워 보입니다.

Avatar 컴포넌트 자체를 넘겨주면 context를 사용하지 않고 이를 해결할 수 있습니다. 그러면 중간에 있는 컴포넌트들이 user나 avatarSize에 대해 전혀 알 필요가 없습니다.

function Page(props) {
  const user = props.user;
  const userLink = (
    <Link href={user.permalink}>
      <Avatar user={user} size={props.avatarSize} />
    </Link>
  );
  return <PageLayout userLink={userLink} />;
}

// 이제 이렇게 쓸 수 있습니다.
<Page user={user} avatarSize={avatarSize} />
// ... 그 아래에 ...
<PageLayout userLink={...} />
// ... 그 아래에 ...
<NavigationBar userLink={...} />
// ... 그 아래에 ...
{props.userLink}

이렇게 바꾸면 Link와 Avatar 컴포넌트가 user와 avatarSize props를 쓴다는 걸 알아야 하는 건 가장 위에 있는 page 뿐입니다.

 

이러한 제어의 역전(inversion of control)을 이용하면 넘겨줘야 하는 props의 수는 줄고 최상위 컴포넌트의 제어력은 더 커지기 때문에 더 깔끔한 코드를 쓸 수 있는 경우가 많습니다. 하지만 이러한 역전이 항상 옳은 것은 아닙니다. 복잡한 로직을 상위로 옮기면 이 상위 컴포넌트들은 더난해 해지기 마련이고 하위 컴포넌트들은 필요 이상으로 유연해져야 합니다.

 

사용법

API

React.createContext

const MyContext = React.createContext(defaultValue);

Context 객체를 만듭니다.

Context 객체를 구독하고 있는 컴포넌트를 렌더링 할 때, React는 트리 상위에서 가장 가까이 있는 짝이 맞는 provider로부터 현재값을 읽습니다.

 

defaultValue 매개변수는 트리 안에서 적절한 Provider를 찾지 못했을 때만 쓰이는 값입니다. 이 기본값은 컴포넌트를 독립적으로 테스트할 때 유용한 값입니다.

 

Context.Provider

<MyContext.Provider value={/* 어떤 값 */}>
  • Provider는 context를 구독하는 컴포넌트들에게 context의 변화를 알리는 역할을 합니다.
  • value prop을 받아서 이 값을 하위 컴포넌트에게 전달합니다.
  • 값을 전달받을 수 있는 컴포넌트의 수에 제한은 없습니다.
  • Provider 하위에 또 다른 provider를 배치하는 것도 가능합니다. (이 경우 하위 Provider의 값이 우선시 됨)
  • context를 구독하는 모든 컴포넌트는 Provider의 value prop가 바뀔 때마다 다시 렌더링 됩니다.

 

'WEB > React' 카테고리의 다른 글

useReducer - React Hooks  (0) 2023.11.30
useMemo -React Hooks  (0) 2023.11.09
useRef - React Hooks  (0) 2023.11.01
useEffect - React Hooks  (0) 2023.11.01
React Hook이란?  (0) 2023.10.23
Comments