const conceptList = require('../../../public/data/concept.json')
require
์ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ๊ฒ ์ฌ์ฉํ ์ ์๋ค. parse
์ํด๋ ๋ฐ๋ก object ํํ๋ก ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
import classNames from 'classnames';
...
className={classNames({[styles.conceptitem]: true, [styles.active]: selectedItem === item})}
react
์์๋ ๊ณต๋ฐฑ์ผ๋ก ๋์์ ์ฌ๋ฌ๊ฐ๋ฅผ ์ฌ์ฉํ ์ ์์ง๋ง, next.js
๋ ์ง์๋์ง ์๋๋ค. ์ข ๊ดด์ํด๋ณด์ด๋ ๋ชจ์ต์ด์ง๋ง, ์ ์ฒ๋ผ ์ฌ์ฉํ๋ฉด ์กฐ๊ฑด๋ถ ์คํ์ผ๋ง์ด ๊ฐ๋ฅํ๋ค.
โ Bad
<ConceptItem selectedItem={selectedItem} onclick={() => clickItem()} item={ele} key={ ele.title }/>
๐ข Good
<ConceptItem selectedItem={selectedItem} clickItem={clickItem} item={ele} key={ ele.title }/> // ๋ถ๋ชจ
...
<div onClick={() => clickItem(item)}></div> // ์์
์ปดํฌ๋ํธ์ onclickItem
์ ์ฌ์ฉํ๋ฉด, ์ด๋ฅผ props
๋ก ์ธ์ํ๋ค. ์ด๋ฒคํธ ํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ์ ์ฒด๋ฅผ div
๋ฑ์ html ํ๊ทธ๋ก ๋ฌถ๊ฑฐ๋, ์์ ์ปดํฌ๋ํธ์ ํจ์ ์์ฒด๋ฅผ props
๋ด๋ ค์ ์ฌ์ฉํด์ผ ํ๋ค.
ํ๋ก์ ํธ ์์ํ๊ธฐ
npm creat-react-app <app name>
<StyledPeopleSayImg src={ `assets/peopleSay/${item.name}.png` }/>
react์์๋ image
๋ผ๋ ํ๊ทธ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, ์ด๋ฏธ์ง์ ๊ฒฝ๋ก๋ฅผ import ํ์ฌ ๊ฐ์ฒด๋ก ๊ฐ์ ธ์ค๋ ๊ฒ์ ๊ถ์ฅํ๋ค.
ํ์ง๋ง ์ด๋ ๊ฒ ํ๋ฉด ์ด๋ฏธ์ง๋ฅผ ๋์ ์ผ๋ก ๊ฐ์ ธ์ค๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ค. ์๋ฅผ ๋ค๋ฉด, ์ปดํฌ๋ํธ๋ฅผ ๋ฐ๋ณตํ๋ฉด์ ์์ดํ
์ ๋ณด์ฌ์ฃผ๋ ค๊ณ ํ ๋, ๋ฐ๋ณต๋๋ ๋ชจ๋ ์์ดํ
์ ์ฌ์ง์ ๋ชจ๋ import
ํด์ผํ๋ ๊ฒ์ด๋ค.
์ด๋ ๊ฒ ํ์ง ์๊ณ , ์ด๋ฏธ์ง๋ฅผ ๋์ ์ผ๋ก ๊ฐ์ ธ์ค๊ธฐ ์ํด์๋ ๋ฐฑํฑ
์ ์ฌ์ฉํด์ Template literals ์ ์ฌ์ฉํ๋ค. ์ํ๊น์ด ์ ์, react์์๋ ์ด ๋ฐฉ์์ ๊ถ์ฅํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ฒฝ๊ณ ๋ฌธ๊ตฌ๋ฅผ ๋ฟ์ด๋ธ๋ค๋ ๊ฒ์ด๋ค. ๋ฐ๋ก ์๋์ ๊ฐ์ ๋ฉ์์ง๋ฅผ ๋ฑ์ด๋ธ๋ค.
Line 17:17: img elements must have an alt prop, either with meang for decorative images jsx-a11y/alt-text
์ด๊ฒ๋ง๊ณ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฐพ์ง ๋ชปํด์, ์ผ๋จ์ ๊ฒฝ๊ณ ๋ฌธ๊ตฌ๋ฅผ ๋ฌด์ํ๋ฉด์ ์งํ์ค์ด๋ค.
์ง๊ธ ํ๋ ์์
์ ์๋ฒ์์ด ํ๋ก ํธ + ์ ์ ํ์ผ(json, assests)๋ก๋ง ๊ตฌ์ฑํ๊ณ ์๋ค. ๊ฐ๋จํ ํ๋ก ํธ ํ๋ก์ ํธ๋ฅผ ๋ฐฐํฌํ๋ ๋ฐ ๊ตณ์ด ํ๋ฆฌํฐ์ด ์จ๊ฐ๋ฉด์ aws๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์๋ค. Netlify
๋ฅผ ์ฌ์ฉํด๋ ์ข์ง๋ง, ์ด๋ฒ์๋ github page๋ก ์ด์ด์ด์ด ๊ฐ๋จํ๊ฒ ํด๋ดค๋ค. ์ฐธ๊ณ ํ ๋ธ๋ก๊ทธ๋ ์ฌ๊ธฐ
-
github์ ํ๋ก์ ํธ๋ฅผ ์ฌ๋ฆฐ๋ค.
-
local์์
gh-pages
๋ฅผ ์ค์นํ๋ค. -
scripts
์ ์๋ ๋ด์ฉ์ ์ถ๊ฐ or ์์ ํ๋ค."predeploy": "npm run build", "deploy": "gh-pages -d build"
-
๋งจ์์ homepage๋ฅผ
https://<๋ด id>.github.io/<๋ด ๋ ํฌ ์ด๋ฆ>
์ผ๋ก ์์ ํ๋ค. ์ด ์ฃผ์๋ ๋ด ํ๋ก์ ํธ ๋ ํฌ์งํ ๋ฆฌ์์setting > GitHub Pages
์ ์๋ ๋งํฌ์ ๋์ผํ๋ค. ex)"homepage": "https://parkjisu6239.github.io/2021_Portfolio",
-
์ ์ ๋ฆฌ์์ค base_url์ ์์ ํด์ผ, ํ์ด์ง์ ์ ์์ ์ผ๋ก ๋๋๋๋ค. ์ด๋ฅผ ์ํด
router
๋ฅผ ์ ์ํ ์ปดํฌ๋ํธ(์ผ๋ฐ์ ์ผ๋ก App.js) ๋ก ๊ฐ์ ์๋ ์ฒ๋ผ ์์ ํ๋ค.import './App.css'; ... import { BrowserRouter, Route, Switch } from 'react-router-dom' function App() { return ( <BrowserRouter basename={process.env.PUBLIC_URL}> <div className="App"> ... </div> </BrowserRouter> ); } export default App;
-
์ดํ terminal์์
npm run develop
๋ฅผ ํ๋ฉด, ๋ด ๋ ํฌ์งํ ๋ฆฌ์gh-pages
๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ธ๋์น๊ฐ ์๋ ์์ฑ๋๊ณ , build ํ์ผ์ด push ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์์ ์ค์ ํ homepage ์ฃผ์๋ก ์ ์ํ๋ฉด, ๋ฐฐํฌ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
react์์ ์คํ์ผ์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๊ฝค๋ ๋ค์ํ๋ค. ์ด๋ฒ ํ๋ก์ ํธ์์ ์ฌ์ฉํ ๋ฐฉ๋ฒ์ ํฌ๊ฒ 3๊ฐ์ง๋ก, ์ฌ์ค ์ ํํ ๋ญ๊ฐ ๋ซ๋ค๊ฑฐ๋ ๋ฌด์์ด ์ณ๋ค๋ ๋ชจ๋ฅด๊ฒ ๊ณ , ์ด๋ฐ ๋ฐฉ๋ฒ๋ค์ด ์๋ค๋ ๊ฒ์ ์ ๋ฆฌํ๊ณ ์ ํ๋ค.
์ฌ๋ ํ๋ก ํธ์๋ ํน์ ํ๋ ์์ํฌ ์์ด html์ ์ฌ์ฉํ๋ ๊ฒ์ฒ๋ผ, element์ class
(react์์๋ className)์ ์ง์ ํ๊ณ , ์คํ์ผ์ํธ(.css) ํ์ผ์ ๋ง๋ค์ด์ ์ ์ฉํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ. ํด๋์ค๋ฅผ ๋ฌธ์์ด๋ก ์ง์ ํ๋ฉฐ, ์ฌ๋ฌ๊ฐ์ผ ๊ฒฝ์ฐ ๋์ด์ฐ๊ธฐ๋ฅผ ํ๋ฉด ๋๊ณ , ๋ฐฑํฑ์ ์ฌ์ฉํด์ ์กฐ๊ฑด๋ถ ํด๋์ค ์ง์ ๋ ๊ฐ๋ฅํ๋ค.
- ์ฅ์ : js์ css ๋ถ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค. ์ฌ์ฉ์ด ์ฝ๋ค.
- ๋จ์ : ๋์ผํ ์ด๋ฆ์ class๊ฐ ์๋ค๋ฉด, ์ด์ ์ ์ฉ๋ ์คํ์ผ์ด ์ค์ฒฉ๋๋ค. ์ค์ฝํ๋ฅผ ๊ณ ๋ คํด์ผํ๋ฉฐ, ๊ทธ๊ฒ ์๋๋ผ๋ฉด ์ด๋ฆ์ unique ํ๊ฒ ์ง๋ ๊ฒ์ด ์์ ํ๋ค.
1๋ฒ์ ๋จ์ ์ ๋ณด์ํ๊ณ ์, ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ธ ๊ฒ ๊ฐ๋ค. style
๋ ๋ชจ๋ํํ์ฌ ์ฌ์ฉํ๋ ๊ฒ. ์ฌ์ฉ๋ฐฉ๋ฒ์ js ํ์ผ์์ ์๋์ ๊ฐ์ ํ์์ผ๋ก importํ๊ณ ์ฌ์ฉํ๋ค. ํด๋์ค๋ฅผ ์ค๋ธ์ ํธ ํํ๋ก ์ง์ ํ๋ฉฐ, ๋ฐฑํฑ์ ์ฌ์ฉํด์ ์กฐ๊ฑด๋ถ ํด๋์ค ์ง์ ๋ ๊ฐ๋ฅํ๋ค.
import styles from './NavBar.module.css'
export default function sample() {
return (
<div className={styles.title}>
<div className={styles.hi}>
Hi
</div>
</div>
)
}
- ์ฅ์ : ์๋ก ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ ๊ฐ์ ์ด๋ฆ์ ํด๋์ค๋ฅผ ์ฌ์ฉํด๋ ์ค์ฒฉ๋์ง ์๋๋ค. module.css๋ฅผ importํ ํด๋น ์ปดํฌ๋ํธ์๋ง ์ ์ฉ๋๋ค. js์ css๋ฅผ ๋ณ๋๋ก ๊ด๋ฆฌ ํ ์ ์๋ค.
- ๋จ์ : ์ค์ ๋๋๋ ๋ ์ด๋ฆ์ด ๋ค๋ฅด๋ค ์ค์ ์ด๋ฆ์
Concept_title__2xS7g
์ด๋ฐ์์ผ๋ก ์๊ธด๋ค. ๊ทธ๋์ ์ฟผ๋ฆฌ์ ๋ ํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ(์์ฐ๋๊ฒ ์ข์) ์ด๋ ต๋ค.
์๋ง react์์ ๊ฐ์ฅ ๋ง์ด? ์ฌ์ฉํ๋ ๋ฏํ ๋ฐฉ๋ฒ์ด๋ค. css๋ฅผ js๋ก ํ ๋นํ๋ค. ๊ทธ๋์ css๋ ๋ชจ๋ js ํ์ผ์ ์์ฑ๋์ด ์์ด, ์ปดํฌ๋ํธ๋น ํ์ผ์ ๋จ ํ๊ฐ๋ง ๊ฐ์ง ์ ์๋ค. ์ฌ์ฉ๋ฒ์ ์๋์ ๊ฐ์ด ๋ณ์๋ฅผ ์์ฑํ๋ฏ์ด ์ฌ์ฉํ๋ค. styled.<ํ๊ทธ ์ด๋ฆ>์ผ๋ก ์ฌ์ฉํ ์ ์๊ณ , element๋ฅผ custom ํ๋ ๋๋์ด๋ค. ์์ ์์๋ ๊ธฐํ ์ ํ์๋ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ์๊ธฐ์์ ์ &
๋ก ๋๊ณ ์ฌ์ฉํ๋ค. ๋ฏธ๋์ด ์ฟผ๋ฆฌ๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
import styled from 'styled-components';
export default function NavBar() {
const [isShow, setIsShow] = useState(false)
return (
<nav>
<StyledDropdown/>
</nav>
)
}
const StyledDropdown = styled.div`
position: absolute;
top: 80px;
right: 10px;
z-index: 10;
height: 0%;
text-align: center;
background-color: white;
border-radius: 3px;
transition: all 1s ease;
border: 0px solid grey;
overflow: hidden;
& > svg {
width: 100%;
height: 42px;
color: red;
cursor: pointer
}
& > * {
padding: 10px;
border-bottom: 1px solid grey;
}
& > div:hover {
color: rgb(84, 105, 190);
}
& > div:last-child {
padding: 10px;
border-bottom: none;
}
&.showMenu {
height: 360px;
border: 1px solid grey;
}
`;
- ์ฅ์ : ํ๋์ jsํ์ผ์์ css๋ ๊ด๋ฆฌํ ์ ์๋ค. js๋ก css๋ฅผ ์ ์ดํ๋ค. props๋ฅผ ๋ด๋ฆด ์ ์์ด์ ํจ์์ฒ๋ผ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๊ณ ๋ฐ์ดํฐ์ ๋ฐ๋ผ ๋์ ์ผ๋ก ์์ง ์ผ ์ ์๋ค.
- ๋จ์ : style ๊ด๋ จ ์ค์ ์ด ๋ง์์ง๋ฉด, js๊ฐ ์ง์ ๋ถํด ๋ณด์ธ๋ค. ์ด๋๊น์ง๋ ์ด ํ์ผ์ js ํ์ผ์ด๋ผ์ css ์๋์์ฑ์ด ์๋๋ค.
-
๋ญ ์จ์ผ๋ง ํ๋ค๋ ์ ๋ต์ ์์ง๋ง, ํ๋๋ก ํต์ผํ๋ ๊ฒ์ด ๋ณด๊ธฐ ์ข์ ๊ฒ ๊ฐ๊ธดํ๋ค. ๋ 3๊ฐ ๋ค ์ฐ๊ณ ์์ง๋ง...
-
์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ์์ฃผ ์ฌ์ฉํ๋ element์ด๋ฉฐ(์๋ฅผ ๋ค๋ฉด button) ๋์ผํ ์คํ์ผ์ ์ ์ฉํ๊ณ ์ ํ๋ค๋ฉด, 1๋ฒ์ ์ฌ์ฉํ์ฌ ๊ฐ์ฅ ์์ ํ์ผ(App.js)์ ์ผ๊ด ์ ์ฉ์ด ํธํ๋ค.
- ๋ฌผ๋ก ์ด๊ฑด 3๋ฒ์ ์ฌ์ฉํด์ globalํ๊ฒ ์ ์ฉ๋ ์คํ์ผ๋ง ๋ชจ์๋๊ณ export & import ํ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ ์๋ ์๋ค.
-
๋ด๋ถ์ ๋ค์ด๊ฐ ์คํ์ผ์ ๋ค๋ฅด์ง๋ง, ํด๋์ค๋ช ์ ๋์ผํ๊ฒ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ(header, title, description ๋ฑ๋ฑ ํํ ๋ค์ด๋ฐ)์ 2๋ฒ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
-
์ปดํฌ๋ํธ๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ๋๋ํ๊ณ , ๊ฐ ๋ฐ์ดํฐ๋ง๋ค ํ๋กฏ์ ๊ฐ์ง๋ง props๋ก ์ผ๋ถ ๋ค๋ฅธ ์คํ์ผ์ ์ ์ฉํด์ผ ํ ๊ฒฝ์ฐ 3๋ฒ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
- data์ ์๊น์ด ์ง์ ๋์ด ์๊ณ , ์ด ์๊น์ ๊ทธ element์ ๋ฐฐ๊ฒฝ์์ผ๋ก ์ง์ ํ๊ณ ์ ํ๋ ๊ฒฝ์ฐ
- title์ ๊ธธ์ด์ ๋ฐ๋ผ ์๊น์ ๋ค๋ฅด๊ฒ ํด์ผํ๋ค๊ฑฐ๋, ์กฐ๊ฑด๋ถ ์คํ์ผ์ด ํ์ํ ๊ฒฝ์ฐ