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개의 댓글

관련 채용 정보