๐ฎ ๋ฏธ๋ ํ๋ก์ ํธ/๐
๋ฝ๋ชจ๋๋ก
๐ REACT ๋ฝ๋ชจ๋๋ก ํ์ด๋จธ ๋ง๋ค๊ธฐ (3) ๐
์ง๋ฐฉ์ด
2025. 2. 3. 11:01
๋จผ์ ๋์๊ฐ๋ ๋ฐ๋์ ์ ์ธํ Pomodoro ํ์ด์ง๋ฅผ ๋ง๋ค์๋ค.
๊ทธ๋ฌ๊ธฐ ์ํด์ Background ์ปดํฌ๋ํธ์ TomatoBtn ์ปดํฌ๋ํธ๊ฐ ํ์ํ๋ค.
Background ์ปดํฌ๋ํธ
// Background.js
import { useNavigate } from "react-router-dom";
import "./Background.css";
export default function Background(props) {
let navigate = useNavigate();
let goToMenu = () => {
navigate('/'); // "/" ๊ฒฝ๋ก(ํ)๋ก ์ด๋
}
return (
<>
<h1 onClick={goToMenu}>๐
{props.title}๐
</h1>
</>
);
}
- ๋ฐฐ๊ฒฝ์์ ์ง์ ํ๊ณ ํด๋ฆญํ๋ฉด ํ์ผ๋ก ๋์๊ฐ๋ ์ ๋ชฉ์ ํ์ํ๋ ์ปดํฌ๋ํธ์ด๋ค.
- export default๋ฅผ ์ฌ์ฉํด ๋ค๋ฅธ ํ์ผ์์ ์ฌ์ฉํ ์ ์๊ฒ ํ๋ค.
- useNavigate()๋ฅผ ํธ์ถํ์ฌ navigate ํจ์๋ฅผ ์์ฑํ๋ค. ์ด๋ฅผ ํตํด ํ์ด์ง ์ด๋์ด ๊ฐ๋ฅํด์ง๋ค.
- {props.title}์ ์ฌ์ฉํ์ฌ title ๊ฐ์ด ๋์ ์ผ๋ก ํ์๋๋ค. (์ปดํฌ๋ํธ์ props๋ฅผ ํ์ฉํ์ฌ title ๊ฐ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ)
// Background.css
@font-face {
font-family: 'TmoneyRoundWindExtraBold';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_20-07@1.0/TmoneyRoundWindExtraBold.woff') format('woff');
font-weight: normal;
font-style: normal;
}
h1 {
text-align: center;
font-family: 'TmoneyRoundWindExtraBold';
font-weight: bold;
color: #F35D50;
font-size: 80px;
text-shadow: 0px 0px 15px #CF9590;
cursor: pointer;
}
* {
background-color: #D6F4D8;
}
- ํผ๊ทธ๋ง์์๋ Baloo ํฐํธ๋ฅผ ์ฌ์ฉํ๋๋ฐ ์ด ํฐํธ๊ฐ ์ด์ํ๊ฒ ์ ์ฉ์ด ์๋์ด์ ๋ค๋ฅธ ํฐํธ๋ก ๋์ฒดํ๋ค...
TomatoBtn ์ปดํฌ๋ํธ
// TomatoBtn.js
import { useState } from "react";
import "./TomatoBtn.css";
import pic1 from "../Pic/Tomato.png";
import pic11 from "../Pic/Tomatoo.png";
export default function TomatoBtn(props) {
const [isActive, setIsActive] = useState(false);
const MouseOn = () => {
setIsActive(true);
}
const MouseOff = () => {
setIsActive(false);
}
return (
<div
className="Wrap"
onClick={props.onClick}
onMouseEnter={MouseOn}
onMouseLeave={MouseOff}
role="button"
tabIndex="0"
>
<img src={isActive ? pic11 : pic1} alt="" className="Tomato" />
<p>{props.name}</p>
</div>
);
}
- isActive ๋ณ์๋ฅผ ํตํด ์ด๋ฏธ์ง๋ฅผ ์ด์ฉํ ๋ฒํผ์ ๋ง์ฐ์ค๊ฐ ์ฌ๋ผ์ ์๋์ง์ ์ฌ๋ถ๋ฅผ ์ ์ฅํ๋ค. ์ด๊ธฐ๊ฐ์ false๋ก ํด๋์ด ๋ง์ฐ์ค๊ฐ ์ฌ๋ผ์ ์์ผ๋ฉด true๋ฅผ, ์ฌ๋ผ์์์ง ์์ผ๋ฉด false๋ฅผ ์ ์ฅํ๋ค.
- <div>๊ฐ ๋ฒํผ ์ญํ ์ ํ๋ค. ์ ๊ทผ์ฑ ํฅ์์ ์ํด role="button"์ ์ถ๊ฐํ์ผ๋ฉฐ, Tap ํค๋ก ์ด๋ํ๊ณ Enter๋ Space๋ก ํด๋ฆญํ ์ ์๋๋ก tabIndex="0"๋ฅผ ์ถ๊ฐํ๋ค. (๊ทธ๋ฐ๋ฐ ์ ์ ๋ ๊น...)
- isActive๊ฐ true์ผ ๋๋ pic11์ด, false์ผ ๋๋ pic1์ด ํ์๋๋ค. pic11๊ณผ pic1๋ ํ ๋งํ ๊ผญ์ง์๋ง ๋ค๋ฅธ ๊ฐ์ ์ด๋ฏธ์ง์ด๋ค.
- props.name์ ์ฌ์ฉํ์ฌ ๋ฒํผ์ ์ด๋ฆ์ ๋์ ์ผ๋ก ์ค์ ๊ฐ๋ฅํ๋ค.
// TomatoBtn.css
@font-face {
font-family: 'TmoneyRoundWindExtraBold';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_20-07@1.0/TmoneyRoundWindExtraBold.woff') format('woff');
font-weight: normal;
font-style: normal;
}
p {
font-family: 'TmoneyRoundWindExtraBold';
color: #FFF674;
font-size: 40px;
margin: 0 0 35px;
background-color: transparent;
text-align: center;
cursor: default;
position: absolute;
top: 43%;
transform: translateY(-50%);
cursor: pointer;
}
.Tomato {
display: flex;
align-items: center;
justify-content: center;
width: 343px;
height: 153px;
margin: 0 0 35px 0;
}
.Wrap {
display: flex;
position: relative;
align-items: center;
justify-content: center;
flex-direction: column;
width: 100%;
height: auto;
cursor: pointer;
}
- p์ position: absolute;๋ฅผ ํตํด ๋ถ๋ชจ ์์๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ๋ ์์น๋ฅผ ์ง์ ํ๊ณ , ๋ฒํผ ์ ์ฒด ์ปจํ ์ด๋์ Wrap ํด๋์ค์ position: relative;๋ฅผ ํตํด ์์ ์์์ absolute ์์น๋ฅผ ์กฐ์ ํ ๊ธฐ์ค์ด ๋๋ค.
์ดํ Pomodoro ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์๋ค.
Pomodoro ์ปดํฌ๋ํธ
// Pomodoro.js
import { useNavigate } from "react-router-dom";
import Background from "../BackGround/Background";
import TomatoBtn from "../TomatoBtn/TomatoBtn";
import ClockPomo from "./ClockPomo";
import "./Pomodoro.css";
import pic1 from "../Pic/TomatoClock.png";
export default function Pomodoro() {
const navigate = useNavigate();
const goToStudy = () => {
navigate('/study');
}
const goToTodo = () => {
navigate('/todolist');
}
const goToSetting = () => {
navigate('/setting');
}
return (
<>
<Background title='POMODORO' />
<div className="main">
<>
<img src={pic1} alt='picture1' className="img1"/>
<ClockPomo />
</>
<div className="Root">
<TomatoBtn name='START' onClick={goToStudy} />
<TomatoBtn name='TODO' onClick={goToTodo} />
<TomatoBtn name='SETTING' onClick={goToSetting} />
</div>
</div>
</>
);
}
- useNavigate()๋ฅผ ํธ์ถํ์ฌ navigate ํจ์๋ฅผ ์์ฑํ๊ณ ๊ฐ ๊ฒฝ๋ก๋ก ์ด๋ํ ์ ์๊ฒ ํ๋ค.
- ๊ฐ ํ์ด์ง๋ก ์ด๋ํ๋ ํจ์๋ฅผ ์ ์ํ์ฌ TomatoBtn์ onClick์ผ๋ก ์ ๋ฌํ๋ค.
// Pomdoro.css
.Root {
flex-direction: column;
margin: 0 0 0 100px;
}
.main {
display: flex;
}
.img1 {
width: 687.8px;
height: 519px;
}