민희의 코딩일지

[React] Hooks-useContext, Context API 본문

WEB FE/React

[React] Hooks-useContext, Context API

heehminh 2023. 3. 4. 10:46
반응형

1- useContext란?

React 에서 데이터의 흐름은 위 → 아래 (부모 → 자식)로 Props 를 통해 전달한다.

Props 를 사용하여 데이터를 전달할 때는 부모 컴포넌트가 자식 컴포넌트 태그에 일일이 Props 를 넣어 단계별로 전달해줘야 한다. (Prop Drilling: 가장 아랫단에 있는 컴포넌트만 데이터가 필요해도 전달하는 과정에서 데이터는 중간 컴포넌트를 거쳐야 한다. Main 컴포넌트는 데이터가 필요없는데도 Profile 컴포넌트에 데이터를 전달하기 위해서 데이터를 Props 로 받은 뒤 다시 Props 로 넘겨주어야 한다.)

 

부모 컴포넌트 (App)

<Header user={user} />

자식 컴포넌트 (Header)

<SearchBar user={user} />

앱 내부에서 수많은 컴포넌트들이 공통적으로 필요한 전역적인 데이터가 있을 때 Props 를 이용해서 데이터를 전달하는 것은 비효율적이다. ⇒ 해결: Context API

전역적인 데이터 (Global Data): User(현재 로그인된 사용자 정보), Theme, Language

 

2- Context API란?

앱 안에서 전역적으로 사용되는 데이터들을 여러 컴포넌트들끼리 쉽게 공유할 수 있는 방법을 제공 (Props X)

  • Context는 꼭 필요할때만 사용해야 한다. (Context를 사용하면 컴포넌트를 재사용하기 어려워질 수 있다.)
  • Prop drilling 을 피하기 위한 목적이라면 Component Composition (컴포넌트 합성)을 먼저 고려해보자

 

3- 예제 코드

1. Props 를 사용해서 Dark Mode 구현하기

function App() {
  const [isDark, setIsDark] = useState(false);
  return <Page isDark={isDark} setIsDark={setIsDark} />;
}

부모 (App) →자식 (Page) Props로 데이터 전달 (isDark, setIsDark)

 

Page 컴포넌트 (App의 자식 컴포넌트이자 Header, Content, Footer의 부모 컴포넌트) 

const Page = ({ isDark, setIsDark }) => {
  return (
    <div className="page">
      <Header isDark={isDark} />
      <Content isDark={isDark} />
      <Footer isDark={isDark} setIsDark={setIsDark} />
    </div>
  );
};

Page 컴포넌트는 isDark, setIsDark 데이터를 필요로 하지 않는 중간 컴포넌트이지만, 자식 컴포넌트에게 데이터를 전달하기 위해 Props로 받아온 뒤 다시 자식 컴포넌트에게 전달한다.

 

Header 

const Header = ({ isDark }) => {
  return (
    <header
      className="header"
      style={{
        backgroundColor: isDark ? "black" : "white",
        color: isDark ? "white" : "black",
      }}
    >
      <h1>Welcome 민희!</h1>
    </header>
  );
};

Content

const Content = ({ isDark }) => {
  return (
    <header
      className="content"
      style={{
        backgroundColor: isDark ? "black" : "lightgray",
        color: isDark ? "white" : "black",
      }}
    >
      <h1>민희님, 좋은 하루 되세요</h1>
    </header>
  );
};

Footer

const Footer = ({ isDark, setIsDark }) => {
  const toggleTheme = () => {
    setIsDark(!isDark);
  };

  return (
    <footer
      className="footer"
      style={{
        backgroundColor: isDark ? "black" : "lightgray",
      }}
    >
      <button className="button" onClick={toggleTheme}>
        Dark Mode
      </button>
    </footer>
  );
};

Footer의 Dark Mode 버튼을 누르면 다음과 같이 바뀐다.

2. useContext 를 사용해서 Theme 적용

context/ThemeContext.js

import { createContext } from "react";

export const ThemeContext = createContext(null);

App.js

function App() {
  const [isDark, setIsDark] = useState(false);

  return (
    <ThemeContext.Provider value={{ isDark, setIsDark }}>
      <Page />; // props 로 전달하지 않음!
    </ThemeContext.Provider>
  );
}

Page

const Page = () => {

  return (
    <div className="page">
      <Header />
      <Content />
      <Footer />
    </div>
  );
};

data 가 필요하지 않으므로 아무것도 받아오지 않음

 

Header, Content, Footer 모두 동일

const { isDark } = useContext(ThemeContext); 

data 중 받고 싶은 인자만 받아옴

 

 

3. useContext 이용해서 User 정보 적용

context/UserContext.js

import { createContext } from "react";

export const UserContext = createContext(null);

App.js

function App() {
  const [isDark, setIsDark] = useState(false);

  return (
    <UserContext.Provider value={"사용자"}>
      <ThemeContext.Provider value={{ isDark, setIsDark }}>
        <Page />
      </ThemeContext.Provider>
    </UserContext.Provider>
  );
}

Header, Content

const user = useContext(UserContext);
<h1>Welcome {user}</h1>

 

 

 

 

React Hooks에 취한다 - useContext + Context API | 리액트 훅스 시리즈 를 참고하여 작성하였습니다. 

https://github.com/heehminh/React-JS-Study/tree/main/hooks-use-context

 

GitHub - heehminh/React-JS-Study

Contribute to heehminh/React-JS-Study development by creating an account on GitHub.

github.com

 

반응형

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

[React] Ajax와 Axios, fetch 차이점과 비교  (0) 2023.02.20
[React] TailWindCSS  (0) 2023.02.03
[React] 구조 분해 할당 (Destructuring)  (0) 2023.02.03
[React] Component, State와 Props  (0) 2023.02.03
[React] React Hooks  (0) 2023.02.03
Comments