
๊ธฐ์ด ๊ณต์ฌ ๐ช
font
๊ตฌ๊ธ ํฐํธ๋ณด๋ค ๋ด๊ฐ ์ข์ํ๋ ํฐํธ๊ฐ ๋ง์ ๋๋ ํฐํธ ์ด์ฉ.
https://noonnu.cc/
App.css
@font-face {
font-family: "Humanbumsuk";
src: url("https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2210-2@1.0/Humanbumsuk.woff2")
format("woff2");
font-weight: normal;
font-style: normal;
}
๊ทธ๋ฆฌ๊ณ App.js ์์import "./App.css"; ํ๋ฉด ๋!
๊ฐ๋ค ์ฐ๊ณ ์ถ์ ๊ณณ์ font-family: "Humanbumsuk"์ฐ๋ฉด ๋๋น
images
๋์ ๊ฐ์ ํ์ ์์ด์ฝ์ด๋ค.
๋ณด๋ฆ๋ฌ์ผ์๋ก ๋งค์ฐ ๊ธฐ๋ถ ์ข์ ์ํ :D !

<img src={process.env.PUBLIC_URL + `/assets/emotion1.png`} />
<img src={process.env.PUBLIC_URL + `/assets/emotion2.png`} />
<img src={process.env.PUBLIC_URL + `/assets/emotion3.png`} />
<img src={process.env.PUBLIC_URL + `/assets/emotion4.png`} />
<img src={process.env.PUBLIC_URL + `/assets/emotion5.png`} />
import ๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ ธ์ฌ ์๋ ์์ง๋ง, ๋๋ฌด ๋ง๊ณ ์๋๋ก ์ ๊ธฐ ์ซ์ดํ๋ ์ฌ๋ (๋์ผ๋) ์ด ์๊ธฐ ๋๋ฌธ์...
์๋ฌดํผ..
public ์ด๋ผ๋ ํด๋ ์์ ์๋ฃ๊ฐ ์๋ค๋ฉด,
html ์์๋ %PUBLIC_URL%
js ์์๋ process.env.PUBLIC_URL ์ฐ๋ฉด ๋จ!
Button
MyButton.js
const MyButton = ({ text, type, onClick }) => {
// positive, negative, default ์ธ์ ๋ค๋ฅธ ํ์
์ ๋ฒํผ ์์ฑ์์๋ default๋ก
const btnType = ["positive", "negative"].includes(type) ? type : "default";
return (
<button
className={["MyButton", `MyButton_${btnType}`].join(" ")}
onClick={onClick}
>
{text}
</button>
);
};
MyButton.defaultProps = {
type: "default",
};
export default MyButton;
ํ์ ๋ช ์ด positive, negative๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ๋ชจ๋ default๋ก.
App.js
<MyButton text={"BUTTON"} onClick={() => alert("๋ฒํผ ํด๋ฆญ")} type={"positive"} /> <MyButton text={"BUTTON"} onClick={() => alert("๋ฒํผ ํด๋ฆญ")} type={"negative"} /> <MyButton text={"BUTTON"} onClick={() => alert("๋ฒํผ ํด๋ฆญ")} type={"asdf์๋ฌด๊ฑฐ๋ ์ด๋ฆ์ง์ด"} /> <MyButton text={"BUTTON"} onClick={() => alert("๋ฒํผ ํด๋ฆญ")} />

3,4๋ฒ์งธ ๋ฒํผ์ type๋ช ์ด "asdf์๋ฌด๊ฑฐ๋ ์ด๋ฆ์ง์ด", ์ด๊ฑฐ๋ ์๋๋ฉด type์ด ์๋๋ฐ, ํ์ธํด๋ณด๋ฉด default๋ก ์ ๋ค์ด์์์์ ์ ์ ์๋ค!
/* ๋ฒํผ ๋ด ๊ธ์๊ฐ ์งค๋ ค์ ๋ ์ค์ด ๋์ง ์๊ฒ ํจ */
white-space: nowrap;

๊ณตํต components
Header, Button์ ๋ง๋ค์ด ๋ณธ๋ค.
MyHeader.js
const MyHeader = ({ headtext, leftchild, rightchild }) => {
return (
<header>
<div className="head_btn_left">{leftchild}</div>
<div className="head_text">{headtext}</div>
<div className="head_btn_right">{rightchild}</div>
</header>
);
};
export default MyHeader;
App.js
<MyHeader
headtext={"App"}
leftchild={
<MyButton text={"LEFT"} onClick={() => alert("์ผ์ชฝ ํด๋ฆญ")} />
}
rightchild={
<MyButton text={"RIGHT"} onClick={() => alert("์ค๋ฅธ์ชฝ ํด๋ฆญ")} />
}
/>

๊ธฐ๋ณธ ๊ณต์ฌ ๐ท๐ปโ๏ธ

์ํ ๊ด๋ฆฌ ๋ก์ง
์ ๋ฐ์ ์ผ๋ก ์ฐ๊ฒ ๋ ์ํ๊ด๋ฆฌ ๋ก์ง ๊ตฌํ
useReducer๋ฅผ ์ด์ฉํ๋ค.
App.js
import React, { useReducer, useRef } from "react";
..
const reducer = (state, action) => {
let newState = [];
switch (action.type) {
case "INIT": {
return action.data;
}
case "CREATE": {
// const newItem = {
// ...action.data,
// };
// newState = [newItem, ...state];
newState = [action.data, ...state];
break;
}
case "REMOVE": {
newState = state.filter((it) => it.id !== action.targetId);
break;
}
case "EDIT": {
newState = state.map((it) =>
it.id === action.data.id ? { ...action.data } : it
);
}
// eslint-disable-next-line no-fallthrough
default:
return state;
}
return newState;
};
function App() {
const [data, dispatch] = useReducer(reducer, []);
const dataId = useRef(0);
// CREATE
const onCreate = (date, content, emotion) => {
dispatch({
type: "CREATE",
data: {
id: dataId.current,
date: new Date(date).getTime(),
content,
emotion,
},
});
dataId.current++;
};
// REMOVE
const onRemove = (targetId) => {
dispatch({ type: "REMOVE", targetId });
};
// EDIT
const onEdit = (targetId, date, content, emotion) => {
dispatch({
type: "EDIT",
data: {
id: targetId,
date: new Date(date).getTime(),
content,
emotion,
},
});
};
return (...
์ฐธ๊ณ : https://www.zerocho.com/category/React/post/5fa63fc6301d080004c4e32b
state context
ํ๋ก์ ํธ state context ์ธํ
ํ๊ธฐ
์ผ๊ธฐ ๋ฐ์ดํฐ state ๋ฅผ ๊ณต๊ธํ context๋ฅผ ๋ง๋ค๊ณ , provider๋ก ๊ณต๊ธํ๋ค.
// data state๋ฅผ ์ปดํฌ๋ํธ ํธ๋ฆฌ ์ ์ญ์ ๊ณต๊ธ
export const DiaryStateContext = React.createContext();
...
return (
// ์ ์ญ์ ์ฃผ๊ธฐ ์ํด์ provider ๋ก ๊ฐ์ธ์ค๋ค.
<DiaryStateContext.Provider value={data}>
...
</DiaryStateContext.Provider>


Dispatch context
์ผ๊ธฐ state ์ dispatchํจ์๋ฅผ ๊ณต๊ธํ context๋ฅผ ๋ง๋ค๊ณ provider๋ก ๊ณต๊ธ
(state context ์์ ๊ณต๊ธํ๋น)
//dispatch ํจ์๋ค๋ context๋ก ๊ณต๊ธ
export const DiaryDispatchContext = React.createContext();
...
return (
<DiaryDispatchContext.Provider value={{ onCreate, onEdit, onRemove }}>
...
</DiaryDispatchContext.Provider>


'Project > Toy-project' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๊ฐ์ ์ผ๊ธฐ์ฅ ๋ง๋ค๊ธฐ 3 - ์ค๋ฅ ์์ & Local Storage (0) | 2023.05.19 |
---|---|
๊ฐ์ ์ผ๊ธฐ์ฅ ๋ง๋ค๊ธฐ 2 - CRUD ๊ธฐ๋ฅ ๊ตฌํ (4) ์์ธ (0) | 2023.05.19 |
๊ฐ์ ์ผ๊ธฐ์ฅ ๋ง๋ค๊ธฐ 2 - CRUD ๊ธฐ๋ฅ ๊ตฌํ (3) ์์ (0) | 2023.05.19 |
๊ฐ์ ์ผ๊ธฐ์ฅ ๋ง๋ค๊ธฐ 2 - CRUD ๊ธฐ๋ฅ ๊ตฌํ (2) ์์ฑ (0) | 2023.05.19 |
๊ฐ์ ์ผ๊ธฐ์ฅ ๋ง๋ค๊ธฐ 2 - CRUD ๊ธฐ๋ฅ ๊ตฌํ (1) HOME (0) | 2023.05.19 |