나만의 포트폴리오를 만들어 보는 시간이다. 서버와 클라이언트 전부!
클라이언트 사이드 셋업
서버 사이드 셋업
npm init -y
)public
이라고 짓습니다.)https://localhost:8080/static
과 같은 URL로 접근할 때 클라이언트 파일들이 접근 가능하도록 만듭니다. (다시한번 말씀드리지만, create-react-app의 yarn start
를 이용하는 것이 아닙니다)페이지 설계
yarn build
)을 이용합니다.일단은 클라이언트부터 먼저 잡고가려고 한다. 그 이유는 요구사항을 보았을 때 클라이언트에서 해야 할 일들이 더욱 많기 때문이다. 클라이언트는 SPA 나 Stateful Component 의 구현, 클라이언트 단에서의 페이지 라우팅(React Router
를 사용해서) 등등 해야 할 부분들이 많다.
그에 비해 서버는 클라이언트에 맞추어서 "일단은" 간략하게만 구현해도 내 포트폴리오를 보여주는 데에는 큰 손색이 없기 때문이다. (물론, 서버가 중요하지 않다는 이야기는 절대로 아니다)
React Router
란 무엇인가Client Routing
and Server Routing
Routing, 즉 URL 조건에 따른 분기이다. 그리고, 이 라우팅을 서버사이드에서 처리해주느냐, 혹은 클라이언트 사이드에서 처리해주느냐에 대한 방법론들도 존재한다. 전자는 server side routing
, 후자는 client side routing
이라고 한다.
웹페이지를 그려낼 때 업데이트가 필요한 부분이 생기면, 업데이트가 필요한 "부분만" 업데이트를 한다. 서버와는 달리 DOM을 필요한 부분만 그려주는 방식으로 업데이트한다. 그렇지만 DOM 만 바뀌는 것이 아니다. 실제로 URL 도 바뀌고, back/front 버튼을 누르면 작동한다.
위에 적은 Client Side Routing 이 되는 SPA 앱은 HTML5
의 History API
를 사용해서, 그 중에서도 pushState()
라는 메서드를 이용해서 만들어졌다. pushState()
메서드는 내가 입력한대로 브라우저에 기록을 저장한다. 그렇게 만든다면 브라우저 상에서 back/front 버튼을 통해 왔다갔다 할 수 있다.
코드로 이해해보자, 내가 만약 "google.com" 에 접속해 있는 상태에서, 개발자 도구를 통해
const state = { 'page_id': 1, 'user_id': 5 }
const title = ''
const url = '/inseob'
history.pushState(state, title, url)
다음과 같은 pushState
코드를 실행해 주었다면, 현재 내 URL 은 "google.com/inseob" 으로 바뀌고, 저 endpoint 에는 내 state 가 추가된다. 위에 적은 대로, back/front 버튼이 전부 잘 작동한다.
그러나 이 상태는 실제로 서버에 기록되진 않는다. 그저 브라우저 상에만 저장되고 있다. 새로고침을 해서 "google.com/inseob" 이라는 페이지에 접속을 요청하면 404 에러가 뜬다. 즉 브라우저 안에서 왔다갔다 할 때만 의미가 있는 주소라는 것이다.
서버에서 클라이언트에 맞추어 라우팅처리를 할 필요가 없이 클라이언트를 개발하면서 렌더링을 해 주면 되니 작업과정이 줄어들어 오류가 생길 확률이 적어진다.
물론 client side routing "만" 으로 routing 을 걸어준 endpoint 를 server 에서 routing 해주지 않으면, 브라우저 내부에서 접근하는 과정에선 문제가 없지만 그 endpoint 로 직접 접근하는 방식 자체는 안 된다. 왜냐면, 서버에서 해당 url 에 대한 요청의 routing 이 되어있지 않기 때문이다. cannot /GET request
같은 메시지가 뜰 것이다.
이렇게 클라이언트 단에서도, 서버 단에서도 렌더링을 해 주는 경우에서 이득을 볼 수 있는 경우는 두 가지이다.
이제는 client side rendering + routing 을 넘어서서, 그냥 서버에서 해당 과정들을 모두 처리해버리자는 server side rendering 이라는 방법론도 고개를 드는 중이다. server side rendering 에서 가장 유명한 라이브러리는 Next.js
이다.
먼저, npm install react-router-dom
을 통해 react-router-dom 을 사용한다. 그 중에서도 BrowserRouter
, Switch
, Route
, Link
를 활용해 Routing 을 해주면 된다. 이렇게 하면 client side routing 이 가능해진다. 다시 한 번 말하지만, 물론 서버에는 구현되어있지 않다.
참고 문서 :
React Router: Declarative Routing for React
import React from 'react'
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from 'react-router-dom'
export default function App() {
return (
// router section
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
)
}
function Home() {
return <h2>Home</h2>
}
function About() {
return <h2>About</h2>
}
function Users() {
return <h2>Users</h2>
}
"어떤 배치가 이쁠까?" 를 잘 모르겠어서, Redux 페이지를 참고하였다. 일단 초안은 이런 식인데, 계속 만들면서 바꿔나가야겠다.
다크모드를 Toggle 로 구현해보고자 생각보다 간단해 보이는 기능이었는데, 뜯어보니 상당히 복잡해서 놀랐다. CSS 가 정말 많이 들어갔었다.
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
사실 W3S 의 toggle 예제를 그대로 복붙했다. 다행히 작동은 잘 된다.
오늘은 사실상 CSS 만 한 듯 하다. CSS 를 하나도 안 했더니, 꽤나 고생을 많이 했다. padding
이나 flex
등등의 작업들, React Routing
을 통한 client side routing 정도를 했다. 오늘은 뭔가 남해개발자한달살기 모임들의 사람들이 오고, 오리엔테이션도 하는 등등 이런저런 일들이 많아서 제대로 공부를 하지 못 했다. 내일부터는 공부하는 것들을 다시 제대로 적어보려고 한다.