오늘 목표 : react, webpack 으로 components로 구성된 페이지 만들기
<준비 사항>
어제 만든 header 소스코드 까지 준비!
반응형 main - 오른쪽의 햄버거를 X 로 만들기
1. NavToggle Component 생성 및 button 대체
Narbar.jsx
react-icon에서 가져온 button 쪽, FaBars를 삭제하고 직접 만든 햄버거를 넣을 예정
코드가 길어질 것 같아서 component 로 만들어서 넣기
아래처럼 import 해오고 그 다음에 NavToggle 파일 만들기 !
import React, { Component } from 'react'
import '../css/navbar.css'
import { FaFacebook, FaInstagram, FaBars, FaTwitter } from 'react-icons/fa'
import NavToggle from './NavToggle' // 가져오기
render() {
return (
<nav>
<div className="nav-center">
{/*logo*/}
<div className="nav-header">
<h1 className="logo">Logo</h1>
<NavToggle />
{/* <button className="nav-toggle">
<FaBars />
</button> */}
</div>
{/* navigation */}
<div className="links-container">
<ul className="links">
{
component > NavToggle
import React, {Component} from 'react'
class NavToggle extends Component{
render(){
return;
}
}
export default NavToggle
React가져오는 이유 : jsx 들은 React.createElement() 을 사용하기 때문 ! (안보이지만..)
* label tag 클릭 <- 화면 보이고 안보이고를 구현할 때 사용할 예정
lable tag 안에 span ㅡ x 3 개를 넣을 예정 (햄버거 구현)
import React, {Component} from 'react'
class NavToggle extends Component{
render(){
return(
<>
<input type="checkbox" id="nav-toggle" className="nav-toggle"/>
<label htmlFor = "nav-toggle">
{/* 클릭하면 nav-toggle id를 가진 아이를 바라봄 for 예약어
그냥 쓸 수가 없어서 htmlFor로 써야함 jsx안에서 알아서 babel이 for로 바꿔서 랜더 */}
<span></span>
<span></span>
<span></span>
</label>
</>
)
}
}
export default NavToggle
=> npm ren dev 한번 코드 잘 작동되는지 쳌
2. css 추가
import React, {Component} from 'react'
import '../css/NavToggle.css'
NavToggle css
/* 체크박스 가리기 */
.nav-toggle{
display:none;
}
/* 인접 접근자
처음 선택한 바로 아래의 element ex) 아래 .nav-toggle + label
label : inline이라 넓이 조절이 안되 -> block
어차피 얘를 flex로 관리할 거라 inline이 될것
relative : 선을 하나하나
*/
.nav-toggle + label{
display:block;
width:2.5rem;
height:2rem;
position:relative;
cursor:pointer;
}
/* span 영역 설정 */
.nav-toggle + label > span{
display: block;
width:100%;
height:5px;
border-radius: 30px;
background-color: black;
transition: all .35s;
position:absolute;
}
.nav-toggle + label > span:nth-child(1){
top:0;
}
.nav-toggle + label > span:nth-child(2){}
.nav-toggle + label > span:nth-child(3){
bottom:0;
}
mobile 바라보면서 pc를 바라보기 -- mobile을 만들면서 pc를 만드는게 더 편하다 !
3. 가운데의 선 내려보기
nav-toggle.css
.nav-toggle + label > span:nth-child(2){
top:50%;
transform: translateY(-50%);
}
-> 그냥 top:50%하면 가운데가 50%부터 ~ 들어가서 살짝 내려감
transform: Y -50%을 해주면 완벽한 햄버거쓰
< 지금까지의 파일트리 >
4. nav-toggle - display: none을 해제하고 체크박스 쳌
-> 다시 display none 해주기
5. input box 체크가 눌리면 모션을 다르게 주기 -> X 모양 만들기
1) 먼저 막대기들을 가운데로 다 옮길 거야
.nav-toggle:checked + label > span:nth-child(1){
top:50%;
transform: translateY(-50%);
}
.nav-toggle:checked + label > span:nth-child(2){
}
.nav-toggle:checked + label > span:nth-child(3){
bottom:50%;
transform: translateY(50%);
}
-> 세개 막대기가 하나로 합쳐짐
2) 각도만 바꿔주면됨 + 가운데를 없애기 !
.nav-toggle:checked + label > span:nth-child(1){
top:50%;
transform: translateY(-50%) rotate(45deg);
}
.nav-toggle:checked + label > span:nth-child(2){
opacity:0;
}
.nav-toggle:checked + label > span:nth-child(3){
bottom:50%;
transform: translateY(50%) rotate(-45deg);
}
여기까지 모바일 버전 !
6. PC 버전 어떻게 할지 정하기
/* pc 버전 */
@media screen and (min-width:800px){
.nav-toggle + label{
display: none;
}
}
pc 버전일 경우 없애기 !
NavToggle.css 전체 코드
/* 체크박스 가리기 */
.nav-toggle{
display:none;
}
/* 인접 접근자
처음 선택한 바로 아래의 element ex) 아래 .nav-toggle + label
label : inline이라 넓이 조절이 안되 -> block
어차피 얘를 flex로 관리할 거라 inline이 될것
relative : 선을 하나하나
*/
.nav-toggle + label{
display:block;
width:2.5rem;
height:2rem;
position:relative;
cursor:pointer;
}
/* span 영역 설정 */
.nav-toggle + label > span{
display: block;
width:100%;
height:5px;
border-radius: 30px;
background-color: black;
transition: all .35s;
position:absolute;
}
.nav-toggle + label > span:nth-child(1){
top:0;
}
.nav-toggle + label > span:nth-child(2){
top:50%;
transform: translateY(-50%);
}
.nav-toggle + label > span:nth-child(3){
bottom:0;
}
/* checked 임을 나타내는 css 선택자 :
.nav_toggle:checked~
*/
.nav-toggle:checked + label > span:nth-child(1){
top:50%;
transform: translateY(-50%) rotate(45deg);
}
.nav-toggle:checked + label > span:nth-child(2){
opacity:0;
}
.nav-toggle:checked + label > span:nth-child(3){
bottom:50%;
transform: translateY(50%) rotate(-45deg);
}
/* pc 버전 */
@media screen and (min-width:800px){
.nav-toggle + label{
display: none;
}
}
NavBar CSS 하기
Navbar.css
Navbar component 안에서 상태값 관리하기
Navbar.jsx
url:'/',
text:'coconut'
},
{
id:2,
url:'/',
text:'banana'
},
{
id:3,
url:'/',
text:'mango'
}
],
showLinks:false,
}
false : 안보이게 : links-contatiner
true : 100% (보이게) : links-container on
{/* navigation */}
<div className="links-container">
<ul className="links">
{
위의 className에 on이라는 class 붙여서 on and off 구현
Narvar.css
/* rem 확대 축소 비율로 늘어남 */
/* .links-container의 높이값이 생기면 내용 출력할 수 있다. */
.links-container{
height:0;
overflow:hidden;
}
.links-container.on{
height:100%;
}
Navbar.jsx
아래처럼 할 수 있지만 더 함수로 밖으로 빼주기
{/* navigation */}
<div className={this.state.showLinks ? 'links-container' : 'links-container on'}>
<ul className="links">
{
↓↓↓↓↓↓↓↓↓↓↓
showContainer = ()=>{ // 요로코롬
let className = this.state.showLinks ? 'links-container on' : 'links-container'
return className
}
render() {
return (
<nav>
<div className="nav-center">
{/*logo*/}
<div className="nav-header">
<h1 className="logo">Logo</h1>
<NavToggle />
{/* <button className="nav-toggle">
<FaBars />
</button> */}
</div>
{/* navigation */}
<div className={this.showContainer()}> //return 값 받아야하니 () 추가
<ul className="links">
{
이제 클릭했을 때 상태값을 반대로 만들기
함수 하나 더 만들기 -> NavToggle Component에 해당 함수 보내기 named toggle
handleToggle=()=>{
this.setState({showLinks:!this.state.showLinks})
}
render() {
return (
<nav>
<div className="nav-center">
{/*logo*/}
<div className="nav-header">
<h1 className="logo">Logo</h1>
<NavToggle
toggle={this.handleToggle}
/>
</div>
NavToggle에 있는 아이을 클릭했을 때
NavToggle.jsx
import React, {Component} from 'react'
import '../css/NavToggle.css'
class NavToggle extends Component{
render(){
return(
<>
<input
type="checkbox"
id="nav-toggle"
className="nav-toggle"
onClick={()=>this.props.toggle()} // 함수형
/>
onClick 이 발생될 떄 (== ()=> arrow 함수가 실행이 될 때 )this.props.toggle() 함수가 실행되도록 하기 위해
근데 this.props.toggle() 도 가능 ~
this.props.toggle OK
this.props.toggle() NOPE
()=>{this.props.toggle()} OK
Navbar.css추가 아래 PC, mobile 버전
/* MOBILE */
.links{
display: flex;
flex-direction: column;
align-items:center;
box-sizing: border-box;
}
.links>li{
width:100%;
text-align: center;
border-bottom: 1px solid #eee
;
}
.links>li>a{
display:inline-block;
/* margin:0 0.5rem; */
color:#000;
font-size: 1.25rem;
padding:0.75rem;
}
/* PC */
.links{
display: flex;
flex-direction: row;
}
.links>li{
width:100%;
text-align: center;
border-bottom: none;
}
.links>li>a{
margin:0 0.5rem;
color:#000;
font-size: 1.25rem;
}
css 전체
/* mobile */
.nav-header{
display:flex;
align-items: center;
justify-content: space-between; /* 양쪽 끝 */
padding:1rem;
}
.logo{
font-size: 3rem;
}
/* rem 확대 축소 비율로 늘어남 */
/* .links-container의 높이값이 생기면 내용 출력할 수 있다. */
.links-container{
height:0;
overflow:hidden;
}
.links-container.on{
height:100%;
}
.social-icons{
height:0;
overflow:hidden;
}
.nav-toggle{
font-size:3rem;
/*투명하게 만들기 */
background:transparent;
border-color:transparent;
color:blue;
}
/* MOBILE */
.links{
display: flex;
flex-direction: column;
align-items:center;
box-sizing: border-box;
}
.links>li{
width:100%;
text-align: center;
border-bottom: 1px solid #eee;
}
.links>li>a{
display:inline-block;
color:#000;
font-size: 1.25rem;
padding:0.75rem;
}
/* PC css style */
@media screen and (min-width:800px){
.logo{
font-size: 4rem;
}
.nav-toggle{
/*pc 경우에 토글 안보이게*/
font-size: 0px;
color:blue;
}
.nav-center{
max-width:1170px;
margin:0 auto;
display: flex;
align-items:center;
justify-content: space-between;
padding:1rem;
}
.links-container{
height:auto;
}
/* PC */
.links{
display: flex;
flex-direction: row;
}
.links>li{
width:100%;
text-align: center;
border-bottom: none;
}
.links>li>a{
margin:0 0.5rem;
color:#000;
font-size: 1.25rem;
}
.social-icons{
display:flex;
height:auto;
}
.social-icons>li>a{
margin: 0 .5rem;
color: red;
}
}
React
Single Page Application
링크 이동해도 페이지는 바뀌지 않음
그래서 왠만해서는 a tag 를 넣지않음 ! 넣더라도 link 개념을 빼고 씀
JS 에서는 url 관리해주는 매서드가 존재하는데 url 값을 js 가 바꾸기는 하지만 link 이동 (요청 to server) 은 하지 않음.
==> a hreg="j~: void(0)" -> url은 바뀜 / 요청은 안함
요걸 이용해서 ----> url 을 바뀐걸로 component를 설정해주는 것 ---> react 라우터
JS 로 했을 때는 header 메뉴를 클릭했을 때 server 로 url 요청 -- 브라우저에 다시 그림
react - home 이라는 것을 쓰면 url 에 home 이 있으면 아래에 home Component를 보여줌 !
이제 react router 배우기 !
Next == React
CRA 는 왠만하면 안쓴다 Next라는 좋은게 있어서 ! - server side rendering
NEXT도 배울 예정
Express 기준으로 url 이 바뀌었을 때는 page 전체를 reload (html 처음부터 닫는 끝-까지를 ) 다시 그려줌.
React는.. 못들었다. 아마 부분부분 바꿔주는... ?
라우터 설치하기
1. 아래 명령어 실행 / 설치
$ npm i react-router-dom
2. App.jsx (최상위 Component)
항상 라우터는 최상위 노드에서 작업을 해야함 ! ★
import React, {Component} from 'react'
import Navbar from './component/Navbar'
import {BrowserRouter, Route, Switch} from 'react-router-dom'
class App extends Component{
render(){
return(
<>
<BrowserRouter>
<Navbar />
{/* 여기서부터 내용 보이는 영역(header 아래) */}
<Switch>
<Route path="" component="" />
</Switch>
</BrowserRouter>
</>
)
}
}
export default App
Navebar 아래 영역은 가변적 -> Switch
path="" url 값이 어떤 거일 때 component ="실행할 Component" <-요걸 불러오겠다.
exact = > 정확한 저 path 값이 들어올 때 compont 를 실행하겠다.
webpack - pages - 각각의 jsx Component 만들기
Coconut.jsx
import React, {Component} from 'react'
class Coconut extends Component{
render(){
return(
<>
hi I am Coconut
</>
)
}
}
export default Coconut
Banana.jsx / Mango.jsx 도 위와 같이 !
App.jsx 에 위의 Components 가져오기 & 사용하기
import React, {Component} from 'react'
import Navbar from './component/Navbar'
import {BrowserRouter, Route, Switch} from 'react-router-dom'
import Coconut from './pages/Coconut'
import Banana from './pages/Banana'
import Mango from './pages/Mango'
class App extends Component{
render(){
return(
<>
<BrowserRouter>
<Navbar />
{/* 여기서부터 내용 보이는 영역(header 아래) */}
<Switch>
<Route exact path="/" component={Coconut} />
<Route exact path="/banana" component={Banana} />
<Route exact path="/mango" component={Mango} />
</Switch>
</BrowserRouter>
</>
)
}
}
export default App
Navbar .jsx
menu: [
{
id:1,
url:'/',
text:'coconut'
},
{
id:2,
url:'/banana',
text:'banana'
},
{
id:3,
url:'/mango',
text:'mango'
}
],
showLinks:false,
}
link 를 이동하지 않도록 위의 오류 안나게 만들기
Navbar.jsx
import React, { Component } from 'react'
import '../css/navbar.css'
import { FaFacebook, FaInstagram, FaBars, FaTwitter } from 'react-icons/fa'
import NavToggle from './NavToggle'
import {Link} from 'react-router-dom'
class Navbar extends Component {
state = {
social: [
{
id: 1,
Link Component를 a tag 대체로 쓸것
또 a 는 Link Component로 쓰고 href -> a로 바꾸기
{/* navigation */}
<div className={this.showContainer()}>
<ul className="links">
{
this.state.menu.map(item=>{
let {id, url, text} = item
return(
<li key={id}>
<Link to={url}>{text}</Link>
</li>
)
})
요렇게 클릭하는대로 나온다 !
Coconut.jsx
import React, { Component } from 'react'
import '../css/Coconut.css'
class Coconut extends Component {
render() {
return (
<>
<div>
<span className="coconut">
hi I am Coconut
</span>
</div>
</>
)
}
}
export default Coconut
Coconut.css
.coconut{
/* display: block; */
background-color: blueviolet;
color:#fff
}
.coconut{
display: block;
height:100px;
background-color: blueviolet;
color:#fff
}
* url 오류 계속 났을 때 아래 true로 바꿔주면 괜찮다 !
과제 : 경일게임아카데미 아래 페이지 react로 만들기 !
banana menu page에서 내가 사용할 component는 총 3개로 정했다. top, sidebar, content
기본틀 만들기
내용 넣기
배경 색 지우기
지우니깐 예뿌다
끗
'블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기' 카테고리의 다른 글
[83일차]20210708 React 기본 개념 복습 (0) | 2021.07.08 |
---|---|
[81일차 복습] css 반응형 햄버거 (삼선) 메뉴 만들기 / 리액트 라우터 react-router-dom (1) | 2021.07.07 |
[80일차 복습] React 리액트, 웹팩, CSS 연결, 반응형 / Header 만들기 (0) | 2021.07.06 |
[80일차] 20210706 React, Webpack, CSS 웹팩으로 Header 만들기 (0) | 2021.07.06 |
[79일차 복습] 웹팩 CRA 없이 React 개발 환경 구축 및 핫리로드 & CRA 사용버전 (0) | 2021.07.05 |