일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- app router
- ESlint
- Promise
- async/await
- CI/CD
- recoil
- Cypress
- 호이스팅
- map
- CORS
- 태그된 유니온
- Jest
- 반공변성
- React
- autosize
- 타입 좁히기
- webpack
- 결정 알고리즘
- TS
- 공변성
- 리터럴 타입
- dfs
- 인터섹션
- SSR
- 투포인터
- tailwind
- RTK Query
- useAppDispatch
- 무한 스크롤
- 이분 검색
- Today
- Total
짧은코딩
프로젝트 기초 공사 1 본문
1. 폰트 세팅
이 사이트에 가면 여러 가지 폰트가 있다.
이 중에서 나눔펜, 연성 글꼴을 사용할 것이다.
-App.css
@import url("https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&family=Yeon+Sung&display=swap");
.App {
padding: 20px;
font-family: "Nanum Pen Script", cursive;
font-family: "Yeon Sung", cursive;
}
폰트 사이트에서 저 주소를 가져와서 App.css에 넣어주고 폰트도 넣어줬다. 이 코드에서는 연성이 적용된다. 만약 나눔팬을 아래로 보내면 나눔팬이 아래로 온다. 그리고 같은 라인에서는 왼쪽이 적용된다.
2. 레이아웃 세팅
리액트 앱은 index.js에서 App 컴포넌트가 랜더링되는 JSX 요소들을 id가 root를 갖는 자식의 요소에 추가함으로서 화면에 출력된다.
그렇기에 id가 root인 div 밑에 App 컴포넌트가 있다.
-App.css
body {
background-color: #f6f6f6;
display: flex;
justify-content: center;
align-items: center;
font-family: "Nanum Pen Script";
min-height: 100vh;
margin: 0px;
}
max-height Css 속성은 요소의 최소 높이를 설정한다. min-height는 height속성의 사용값이 자신의 값보다 작아지는걸 방지한다.
body에는 기본적으로 margin이 있어서 0으로 만들어준다.
@media (min-width: 650px) {
.App {
width: 640px;
}
}
@media (max-width: 650px) {
.App {
width: 90vw;
}
}
#root {
background-color: white;
box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
}
미디어쿼리를 이용해서 반응형으로 만들어준다. 그리고 div인 root의 배경을 white로 한다.
-box-shadow
https://developer.mozilla.org/ko/docs/Web/CSS/box-shadow
box-shadow을 이용해서 그림자를 만들어준다.
.App {
min-height: 100vh;
padding-left: 20px;
padding-right: 20px;
}
min-height로 저렇게 설정하면 기본적으로 100%의 높이를 갖게해준다.
-최종 코드
@import url("https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&family=Yeon+Sung&display=swap");
body {
background-color: #f6f6f6;
display: flex;
justify-content: center;
align-items: center;
font-family: "Nanum Pen Script";
min-height: 100vh;
margin: 0px;
}
@media (min-width: 650px) {
.App {
width: 640px;
}
}
@media (max-width: 650px) {
.App {
width: 90vw;
}
}
#root {
background-color: white;
box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
}
.App {
min-height: 100vh;
padding-left: 20px;
padding-right: 20px;
}
최종적으로 이렇게 만들면 레이아웃 세팅이 완성된다.
3. 이미지 에셋 세팅
public에 assets 파일을 만들고 이미지 모형으로 사용할 사진들을 넣어준다.
-App.js
<img src={process.env.PUBLIC_URL + `/assets/emotion1.png`} />
App.js에 이 코드를 추가한다. 여기서 process.env.PUBLIC_URL은 지금 어떤 위치에 있는public 디렉토리를 가리키게 된다.'
-최종 코드
import "./App.css";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "./pages/Home";
import New from "./pages/New";
import Edit from "./pages/Edit";
import Diary from "./pages/Diary";
function App() {
const env = process.env;
// env.PUBLIC_URL이 존재하면 담고 아니면 비워라
env.PUBLIC_URL = env.PUBLIC_URL || "";
return (
<BrowserRouter>
<div className="App">
<h2>App.js</h2>
<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`} />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/new" element={<New />} />
<Route path="/edit" element={<Edit />} />
<Route path="/diary" element={<Diary />} />
</Routes>
</div>
</BrowserRouter>
);
}
export default App;
-출력 화면
4. 공통 컴포넌트 세팅
모든 페이지에 공통으로 사용되는 버튼, 헤더 컴포넌트 세팅
Button
버튼 같은 UI 요소 하나를 컴포넌트화 하기 위해서는 UI 요소가 어떤 기준으로 얼마만큼 변화는지 찾아내서 패턴화해야 한다.
작성완료: 긍정적인 부분이라 type: POSITIVE
수정하기: 긍정도 부정도 아닌 부분이라 type: DEFAULT
삭제하기: 부정적인 부분이라 type: NEGATIVE
=> 버튼에 표시되는 텍스트는 text prop로 받고, 눌렀을 때 어떤 엑션을 취할 것인지는 onClick로 만든다.
Compponents에 MyButton.js를 만든다.
-MyButton.js
const MyButton = ({ text, type, onClick }) => {
return (
<button className={"MyButton"} onClick={onClick}>
{text}
</button>
);
};
className은 컴포넌트 이름이랑 똑같이 사용할거라 똑같이 사용하고 onClick와 text는 바로 넣어준다.
-App.js
import MyButton from "./Components/MyButton";
function App() {
return (
<BrowserRouter>
<div className="App">
<h2>App.js</h2>
<MyButton
text={"버튼"}
onClick={() => alert("버튼 클릭")}
type={"positive"}
/>
이렇게 MyButton 컴포넌트를 활용하여 버튼을 만들어 줄 수 있다.
이런 결과가 나온다.
-App.css
/* MyButton */
.MyButton {
cursor: pointer;
border: none;
border-radius: 5px;
padding: 10px 20px 10px 20px;
font-size: 18px;
/* 버튼 안에 글자가 짤려서 2줄이 되지 않도록 해주는 속성 */
white-space: nowrap;
font-family: "Nanum Pen Script";
}
버튼을 꾸민 코드이다.
white-space: nowrap는 버튼 안에 글자가 짤려서 2줄이 되지 않도록 해준다.
이런 버튼이 완성된다.
-type prop에 따라서 다르게 만들기
const MyButton = ({ text, type, onClick }) => {
return (
<button
className={["MyButton", `MyButton_${type}`].join(" ")}
onClick={onClick}
>
{text}
</button>
);
};
MyButton.defaultProprs = {
type: "default",
};
export default MyButton;
classNam을 요소마다 다르게 해줄 수 있다. 0번째 요소는 그냥 MyButton이고 그 다음 요소는 type에 따라서 MyButton_positive, MyButton_default, MyButton_negative로 구분되어 나온다. className은 문자열로 전달해야 하기 때문에 배열로 전달해주면 안되고 join 메서드를 통해 " "로 띄어쓰기를 세퍼레이트로 해서 합쳐준다.
버튼을 누르고 확인해보면 이런 결과가 나온다.
-App.css
.MyButton_default {
background-color: #ececec;
color: balck;
}
.MyButton_positive {
background-color: #64c964;
color: white;
}
.MyButton_negative {
background-color: #fd565f;
color: white;
}
버튼을 positive, default, negative로 나눠서 색을 각각 다르게 해줬다.
-MyButton.js
const MyButton = ({ text, type, onClick }) => {
const btnType = ["positive", "negative"].includes(type) ? type : "default";
return (
<button
className={["MyButton", `MyButton_${btnType}`].join(" ")}
onClick={onClick}
>
{text}
</button>
);
};
MyButton.defaultProprs = {
type: "default",
};
export default MyButton;
btnType를 추가해서 만약 클래스네임이 이상한 버튼이 생성되어도 default로 바꿔주도록 만들었다.
Header
헤더는 가운데에 headText가 있다. 그리고 leftchild, rightchild가 있는데 이런 자식 헤더들은 존재하지 않을 수도 있다.
-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;
마찬가지로 Components에 MyHeader.js를 만들어주고 headText, leftchild, rightchild로 나눠서 만들어준다.
-App.css
header {
padding-top: 20px;
padding-bottom: 20px;
display: flex;
align-items: center;
border-bottom: 1px solid #e2e2e2;
}
header > div {
display: flex;
}
header .head_text {
width: 50%;
font-size: 25px;
justify-content: center;
}
header .head_btn_left {
width: 25%;
justify-content: start;
}
header .head_btn_right {
width: 25%;
justify-content: end;
}
header button {
font-family: "Nanum Pen Script";
}
그리고 왼쪽 25%, 중앙 50%, 오른쪽 25%로 해서 만들면 된다.
-App.js
<MyHeader
headText={"App"}
leftchild={
<MyButton
text={"왼쪽 버튼"}
onClick={() => alert("왼쪽 버튼 클릭")}
/>
}
rightchild={
<MyButton
text={"오른쪽 버튼"}
onClick={() => alert("오른쪽 버튼 클릭")}
/>
}
/>
App.js에서 headText, leftchild, rightchild를 만들어주면
이런 화면이 나온다.
'인프런, 유데미 > 한입 크기로 잘라 먹는 리액트' 카테고리의 다른 글
HOME 구현하기 (0) | 2022.06.21 |
---|---|
프로젝트 기초 공사 2 (0) | 2022.06.20 |
페이지 라우팅 (0) | 2022.06.16 |
일기장 만들기 되짚어보기 (0) | 2022.06.14 |
컴포넌트 트리에 데이터 공급하기 (0) | 2022.06.01 |