react Context api

yonghee·2022년 12월 10일
1
import { createContext, useState } from "react";

export type State = {
  darkMode: boolean;
  toggleDarkMode: () => void;
};

//1.데이터를 담고 있는 컨텍스트
export const DarkModeContext = createContext<State>({
  darkMode: false,
  toggleDarkMode: () => {},
});

//2.데이터를 보여주도록하는 우산 --> 부모 우산 컴포넌트
export function DarkModeProvider({ children }: { children: React.ReactNode }) {
  console.log(children);
  const [darkMode, setDarkMode] = useState(false);
  const toggleDarkMode = () => setDarkMode((mode) => !mode);
  return (
    //3. Provider로 감싸고 난뒤
    //4 자식 컴포넌트와 공유하고 싶은 데이터가 있다면 value={{ darkMode, toggleDarkMode }}에 지정하면 됩니다.
    <DarkModeContext.Provider value={{ darkMode, toggleDarkMode }}>
      {children}
    </DarkModeContext.Provider>
  );
}

로직 설명 : 우리는 다크모드인지 아닌지 토글링하는 것 까지 자식 컴포넌트에서 다 활용하기를 원하므로 다크모드인지 아닌지 알 수 있는 상태 변수(darkMode)과 이것을 토글링하는 함수까지 전부 children에 제공하는 구조

import React, { useContext } from "react";
import { DarkModeContext, DarkModeProvider } from "./context/DarkModeContext";
import "./AppTheme.css";

//이용하고자하는 자식 컴포넌트에 우산을 씌우면 된다. DarkModeProvider
//최대한 필요한 곳에만 우산을 씌우자
const AppTheme = () => {
  return (
    <>
      <Header />
      <DarkModeProvider>
        <Main />
      </DarkModeProvider>
      <Footer />
    </>
  );
};

function Header() {
  return <header className='header'>Header</header>;
}

function Main() {
  return (
    <main>
      Main
      <Profile />
      <Products />
    </main>
  );
}

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

function User() {
  return <div>User</div>;
}

function Products() {
  return (
    <div>
      Products
      <ProductDetail />
    </div>
  );
}

function ProductDetail() {
  //useContext를 사용하여 DarkModeContext를 사용할 것이라 명시해줍니다.
  const { darkMode, toggleDarkMode } = useContext(DarkModeContext);
  return (
    <div>
      Product Detail
      <p>
        DarkMode:
        {darkMode ? (
          <span style={{ backgroundColor: "black", color: "white" }}>Dark Mode</span>
        ) : (
          <span>Light Mode</span>
        )}
      </p>
      <button onClick={() => toggleDarkMode()}>Toggle</button>
    </div>
  );
}

function Footer() {
  return <footer className='footer'>Footer</footer>;
}

export default AppTheme;

profile
필요할 때 남기는 날것의 기록 공간

0개의 댓글