context API

HSKwon·2023년 3월 30일
0
post-thumbnail

상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할 때, 속성값이 사용되는데 가까운 거리에 있는 몇 개의 하위 컴포넌트로 전달할 때는 속성값으로 충분하다.

하지만, 부모 컴포넌트와 가장 말단에 있는 컴포넌트 사이에 수천개의 컴포넌트가 있는 경우, 속성값을 내려주는 코드를 반복적으로 작성해야 하는 문제가 발생할 수 있다.

import React from 'react';

function App() {
  return (
    <div>
      <div>상단메뉴</div>
      <Profile username="mike"/>
      <div>하단메뉴</div>
    </div>
  );
}

function Profile({username}) {
    return(
        <div>
            <Greeting username={username}/>
        </div>
    )
}

function Greeting ({username}) {
    return(
        <p>{`${username}님 안녕하세요!`}</p>
    )
}

🚩 이때, 전역적으로 상태를 관리하는 라이브러리를 사용하거나, React에 내장되어 있는 context API를 사용하면, 컴포넌트의 중첩 구조가 복잡한 경우에도 손쉽게 데이터를 전달할 수 있다. 위의 코드를 context API를 사용해서 고칠 수 있다.

import React from 'react';
const UserContext = createContext('');

function App() {
  return (
    <div>
      <UserContext.Provider value="mike">
        <div>상단메뉴</div>
        <Profile username="mike" />
        <div>하단메뉴</div>
      </UserContext.Provider>
    </div>
  );
}

function Profile() {
  return (
    <div>
      <Greeting />
    </div>
  );
}

function Greeting() {
  return (
    <UserContext.Consumer>
      <p>{`${username}님 안녕하세요!`}</p>
    </UserContext.Consumer>
  );
}

createContext 함수를 호출하면 context 객체가 생성된다.
createContext 함수의 구조는 다음과 같다.

createContext(defaultValue) => {Provider, Consumer}
  1. 상위 컴포넌트에서는 Provider 컴포넌트를 이용해서 데이터를 전달한다.
  2. 하위 컴포넌트에서는 Consumer 컴포넌트를 이용해서 데이터를 사용한다.
  3. Consumer 컴포넌트는 데이터를 찾기 위해 상위로 올라가면서 가장 가까운 Provider 컴포넌트를 찾는다.
    • 만약 최상위에 도달할 때까지 Provider 컴포넌트를 찾지 못한다면, 기본값이 사용된다.

Provider 컴포넌트의 속성값이 변경되면 하위의 모든 Consumer 컴포넌트는 다시 렌더링된다.

생각해 볼 점

import React, {useState} from 'react';
const UserContext = createContext('');

function App() {
    const [username, setUsername] = useState("");
  return (
    <div>
      <UserContext.Provider value={username}>
        <Profile/>
      </UserContext.Provider>
      <input type="text" value={username} onChange={e => setUsername(e.target.value)}
    </div>
  );
}

const Profile = React.memo(() => {
 return(
    <div>
        <Greeting/>
    </div>
 )   
})

function Greeting() {
  return (
    <UserContext.Consumer>
      <p>{`${username}님 안녕하세요!`}</p>
    </UserContext.Consumer>
  );
}
1. username의 state가 변경되면 App 컴포넌트는 리렌더링된다.
2. Profile 컴포넌트는 React.memo로 만들어졌고, 리렌더를 유발하는 속성값이 없기 때문에 최초 한 번만 렌더링된다.
3. Profile 컴포넌트의 렌더링 여부와 상관 없이 Greeting 컴포넌트의 Consumer 컴포넌트는 다시 렌더링된다.

즉, 중간 컴포넌트 ( Profile )의 렌더링 여부와 상관 없이 Provider 컴포넌트로 새로운 데이터가 입력되면, Consumer 컴포넌트가 다시 렌더링되는 것이 보장된다.

profile
공부한 내용이나 관심 있는 정보를 글로 정리하며 익숙하게 만들고자 합니다.

0개의 댓글