본문 바로가기
Next.js

[next.js] useContext(다크모드)

by 남민섭 2023. 12. 4.
728x90
반응형

 

다크모드 적용

 

context 파일 만들기

context/ThemeContext.js

import { createContext, useEffect, useState } from "react";

export const ThemeContext = createContext();

export default function ThemeProvider({ children }) {
  const [theme, setTheme] = useState("dark");

  useEffect(() => {
    document.body.classList.add(theme);
    return () => {
      document.body.classList.remove(theme);
    };
  }, [theme]);
  
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

 

_app.js 전역 context 값 지정

_app.js

import ThemeProvider from "@/context/ThemeContext";
import "@/styles/global.css";

export default function App({ Component, pageProps }) {
  return (
    <ThemeProvider>
      <Component {...pageProps} />
    </ThemeProvider>
  );
}

 

global.css 스타일 적용

styles/global.css

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body.dark {
  background-color: #121212;
}

body.dark,
body.dark a {
  color: #f9f9f9;
}

body.light {
  background-color: #ededed;
}

body.light,
body.light a {
  color: #1e1e1e;
}

 

select 요소, onclick 함수 적용 

pages/index.js

import { ThemeContext } from "@/context/ThemeContext";
import Link from "next/link";
import { useRouter } from "next/router";
import { useContext, useState } from "react";

export default function Home() {
  const [value, setValue] = useState("");
  const { theme, setTheme } = useContext(ThemeContext);

  const router = useRouter();

  function handleChange(e) {
    setValue(e.target.value);
  }
  function handleSubmit(e) {
    e.preventDefault();
    return router.push(`/test?s=${value}`);
  }
  function handleClick(e) {
    setTheme(e.target.value);
  }
  return (
    <>
      <Link href={"/test?s=ss&h=sss"}>이동</Link>
      <form onSubmit={handleSubmit}>
        <input name="id" value={value} onChange={handleChange} />
      </form>
      <select onClick={handleClick}>
        <option name={"dark"} value={"dark"}>
          dark
        </option>
        <option name={"light"} value={"light"}>
          light
        </option>
      </select>
    </>
  );
}

 

 

728x90
반응형

댓글