230523 - React(useContext, classNames)

๋ฐฑ์Šน์—ฐยท2023๋…„ 5์›” 23์ผ
1

๐Ÿšฉ React

useContext ์‚ฌ์šฉํ•ด์„œ ๋‹คํฌ๋ชจ๋“œ ๊ตฌํ˜„

๐Ÿ“ ์„ค๋ช…

  • useContext๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋‹คํฌ๋ชจ๋“œ toggle๋ฒ„ํŠผ ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ


โœ’๏ธ ์ฝ”๋“œ ์ž‘์„ฑ

์ž…๋ ฅ

App.js

import './App.css';
import Footer from './components/Footer';
import Header from './components/Header';
import Main from './components/Main';
import { DarkmodeProvider } from './context/DarkmodeContext';

function App() { 

  return (
    <div className='app'>
      <DarkmodeProvider>
        <Header />        
        <Main/>
        <Footer />
      </DarkmodeProvider>
    </div>
  );
}

export default App;



App.css

:root { --main-color: rgb(164, 184, 221); --dark-color: darkslategray}
body { margin: 0; padding: 0; height: 100vh; }
/* ๋‹คํฌ๋ชจ๋“œ ์ƒํƒœ */
body.on { background: #000; color: #fff; }
body.onheader,body.onfooter { background: var(--dark-color); color: var(--main-color); }
.app { display: flex; flex-direction: column; justify-content: space-between; height: 100%; border: 5px solid red; }
.header,.footer { display: flex; justify-content: center; background: var(--main-color); color: white; }
.main { padding: 20px; max-width: 700px; margin: auto; }
.section { border: 2px solid lightgray; }



components

// Header.jsx
import React from 'react'

export default function Header() {
  return (
    <div className="header">
      <h1>Header</h1>
    </div>
  )
}


// Main.jsx
import React from 'react'
import Section from './Section'

export default function Main() {
  return (
    <div className='main'>
      <Section />
      <br />
      <Section />
    </div>
  )
}


//Article.jsx
import React, { useContext } from 'react'
import { DarkmodeContext } from '../context/DarkmodeContext'

export default function Article() {
  const { darkmode, toggleDarkMode } = useContext(DarkmodeContext);
  const all = document.querySelector("body");
  
  return (
    <div className='article'>      
      <p>
        {/* <b>Article- </b>{darkmode.toString()} */}
        <b>Article- </b>{darkmode ? all.classList.add("on") : all.classList.remove("on")} <br />
        <button onClick={toggleDarkMode}>Toggle BUTTON</button>
      </p>
    </div>
  )
}


// Footer.jsx
import React from 'react'

export default function Footer() {
  return (
    <div className='footer'>
      <h3>Footer</h3>
    </div>
  )
}

์ถœ๋ ฅ

  • ์ด๋ฏธ์ง€๋กœ ๋Œ€์ฒด


๐Ÿ”— ์ฐธ๊ณ  ๋งํฌ & ๋„์›€์ด ๋˜๋Š” ๋งํฌ






classNames ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

๐Ÿ“ ์„ค๋ช…

  • ๋ฆฌ์•กํŠธ์—์„œ ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ์„ ์ค„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • ํด๋ž˜์Šค๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๋•Œ ํŽธ๋ฆฌํ•จ
  • ์„ค์น˜ ๋ฐฉ๋ฒ•
    • $ yarn add classnames


โœ’๏ธ ์ฝ”๋“œ ์ž‘์„ฑ

์ž…๋ ฅ

App.js

import "./App.scss";
import Button from "./components/Button";

function App() {
  return (
    <div className="App">
      <div className="btnWrap">
        {/* Button.jsx์—์„œ children์œผ๋กœ ๋ณด๋‚ผ ๊ฐ’ */}
        <Button size="large" color="blue">ํŒŒ๋ž€๋ฒ„ํŠผ</Button>
        <Button color="blue">ํŒŒ๋ž€๋ฒ„ํŠผ</Button>
        <Button size="small" color="blue">ํŒŒ๋ž€๋ฒ„ํŠผ</Button>
      </div>

      <div className="btnWrap">
        <Button size="large" color="pink">ํ•‘ํฌ๋ฒ„ํŠผ</Button>
        <Button color="pink">ํ•‘ํฌ๋ฒ„ํŠผ</Button>
        <Button size="small" color="pink">ํ•‘ํฌ๋ฒ„ํŠผ</Button>
      </div>

      <div className="btnWrap">
        <Button size="large" color="lime">๋ผ์ž„๋ฒ„ํŠผ</Button>
        <Button color="lime">๋ผ์ž„๋ฒ„ํŠผ</Button>
        <Button size="small" color="lime">๋ผ์ž„๋ฒ„ํŠผ</Button>
      </div>

      <div className="btnWrap">
        <Button size="large" color="gray">๋ผ์ž„๋ฒ„ํŠผ</Button>
        <Button color="gray">๋ผ์ž„๋ฒ„ํŠผ</Button>
        <Button size="small" color="gray">๋ผ์ž„๋ฒ„ํŠผ</Button>
      </div>
    </div>
  );
}

export default App;



Button.jsx

import React from 'react';
import './Button.scss';
import classNames from "classnames";

const Button = ({children,size,color}) => {
  return (
    <button className={classNames("Button", size, color)} >{children}</button>
  )
}

Button.defaultProps = { size:'medium'} 
export default Button



Button.scss

$blue: #7397e6;
$pink: #e77c8a;
$lime: #a9e34b;
$gray: #adb5bd;

// mixin ์ถ”๊ฐ€
@mixin btnColor($color) {
  background: $color;
  &:hover {
    background: lighten($color, 10%); // lighten ํ•จ์ˆ˜ ์‚ฌ์šฉ (sass/scss ๋‚ด์žฅ ํ•จ์ˆ˜) - ํ•ด๋‹น ์ƒ‰์ƒ์—์„œ 10% ๋” ๋ฐ๊ฒŒ
  }
  &:active {
    background: darken($color, 10%); // darken ํ•จ์ˆ˜ (sass/scss ๋‚ด์žฅ ํ•จ์ˆ˜) - ํ•ด๋‹น ์ƒ‰์ƒ์—์„œ 10% ๋” ์–ด๋‘ก๊ฒŒ
  }
}

.Button {
  color: #fff;
  font-weight: bold;
  cursor: pointer;
  margin: 1rem;
  border: none;
  border-radius: 0.4rem;
  outline: none;

  // ์‚ฌ์ด์ฆˆ ๊ด€๋ฆฌ
  &.large {
    padding: 2rem 4rem;
    font-size: 1.4rem;
  }
  &.medium {
    padding: 1rem 2rem;
    font-size: 1rem;
  }
  &.small {
    padding: 0.5rem 1rem;
    font-size: 0.7rem;
  }

  // ์ƒ‰์ƒ ์ง€์ •
  &.blue { @include btnColor($blue); }
  &.pink { @include btnColor($pink); }
  &.lime { @include btnColor($lime); }
  &.gray { @include btnColor($gray); }
}

์ถœ๋ ฅ

  • ์ด๋ฏธ์ง€๋กœ ๋Œ€์ฒด


๐Ÿ”— ์ฐธ๊ณ  ๋งํฌ & ๋„์›€์ด ๋˜๋Š” ๋งํฌ






profile
๊ณต๋ถ€ํ•˜๋Š” ๋ฒจ๋กœ๊ทธ

0๊ฐœ์˜ ๋Œ“๊ธ€