[TIL 221126] Context

ponyo·2022년 11월 26일
0

Today I Learned

목록 보기
4/30

참고한 영상: 별코딩님의 'React Hooks에 취한다 - useContext + Context API | 리액트 훅스 시리즈'

Context란 무엇일까? 🤔

  • context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다.
  • context는 React 컴포넌트 트리 안에서 전역적(global)이라고 볼 수 있는 데이터를 공유할 수 있도록 고안된 방법입니다.
  • context의 주된 용도는 다양한 레벨에 네스팅된 많은 컴포넌트에게 데이터를 전달하는 것입니다.
  • 출처 : Context - React 공식 문서

리액트 공식 문서

키워드내용
컴포넌트 트리 제약Props drilling의 한계 해소
재사용성Context를 사용하면 재사용하기 어려움
APIcreateContext/Provider/Consumer
useContextConsumer 대체

Context를 사용하는 이유

props 를 전달할 때는 부모컴포넌트가 자식 컴포넌트에게 일일이 props를 넣어서 단계별로 전달을 해줘야 한다.

Global Data를 자식들에게 전달해야하는 상황에 일일이 전달을 하려면 코드도 복잡해지고 props를 수정해줘야할 때 전부 다 바꿔줘야하는 문제점이 있다.


App이 Data props를 C와 E에게 전달해줘야 할 때
우선 A와 B에게 props를 전달하고 그리고 C 와 D, 그리고 E에게 전달할 수 있다.

App이 context를 통해 방송을 하게 되고, 아래와 같이 useContext hook을 이용하여 필요한 Data를 받아올 수 있다!

Context는 꼭 필요할 때만 !

  • Context를 사용하면 컴포넌트를 재사용하기 어려워질 수 있다
  • Prop drilling을 피하기 위한 목적이라면 Componenet Composition (컴포넌트 합성)을 먼저 고려해보자

Context 예시

Context 사용 전

// App.js

import "./styles.css";
import React, { useState } from "react";
import Page from "./components/Page";

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

import React from "react";
import Content from "./Content";
import Footer from "./Footer";
import Header from "./Header";

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

export default Page;
// Header.js

import React from "react";

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

export default Header;
// Content.js

import React from "react";

const Content = ({ isDark }) => {
  return (
    <div
      className="content"
      style={{
        backgroundColor: isDark ? "black" : "white",
        color: isDark ? "white" : "black"
      }}
    >
      <p>홍길동님, 좋은 하루 되세요</p>
    </div>
  );
};

export default Content;
// Footer.js

import React from "react";
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>
  );
};

export default Footer;

App에서 useState hook을 사용하여 isDark state 생성하고 자식 컴포넌트에서 isDark를 사용하기 위해 props를 개별적으로 전달


Context 사용

가장 먼저, context 폴더를 만들고 그 안에 ThemeContext.js 파일을 만든다.

1️⃣ createContext import 해온다.

2️⃣ createContext를 사용하여 ThemeContext를 만든다.

import { createContext } from 'react';

export const ThemeContext = createContext(null);

App 컴포넌트로 가서 위에서 생성한 context를 import 한다.

// App.js

import "./styles.css";
import React, { useState } from "react";
import Page from "./components/Page";
import { ThemeContext } from "./context/ThemeContext";

export default function App() {
  const [isDark, setIsDark] = useState(false);
  return (
    <ThemeContext.Provider value={{ isDark, setIsDark }}>
      <Page />)
    </ThemeContext.Provider>
  );
}

3️⃣ Provider를 사용하여 value={{ isDark, setIsDark}} 필요한 사람~ 하고 방송한다.

// Header.jsx 

import React, { useContext } from "react";
import { ThemeContext } from "../context/ThemeContext";

const Header = () => {
  const { isDark } = useContext(ThemeContext);
  console.log(isDark);
  return (
    <header
      className="header"
      style={{
        backgroundColor: isDark ? "black" : "lightgray",
        color: isDark ? "white" : "black"
      }}
    >
      <h1>Welcome 홍길동!</h1>
    </header>
  );
};

export default Header;

4️⃣ isDark가 필요한 HeaderContentuseContext를 사용하여 받아온다.

const { isDark } = useContext(ThemeContext);

5️⃣ isDark와 setIsDark 가 필요한 FooteruseContext를 사용하여 받아온다.

const { isDark, setIsDark } = useContext(ThemeContext);

Context 사용 완성본


Context 초기값

// ThemeContext.js

import { createContext } from 'react;

export const ThemeContext = createContext(null);

createContext(초기값) 을 설정할 수 있다.

만약 상위 컴포넌트에서 Provider로 감싸주지 않아서 value값이 없는 상태라고 하면 설정한 초기값이 사용된다.

// ThemeContext.js

import { createContext } from 'react;

export const ThemeContext = createContext('메롱');
// Page.js

// ...생략...
const data = useContext(ThemeContext);
console.log(data);
// ...생략...
// console.log(data) 출력결과

'메롱'

Practice

홍길동이 아닌 '사용자'라는 userContext 를 생성하여 필요한 곳에 사용해보자!!

정답

Edit Context 사용

profile
😁

0개의 댓글