[React 프로젝트] 숫자야구 프로젝트 - 프로젝트 준비

Hyuk·2023년 1월 14일
0

재작년에 React를 강의나 실습없이 프로젝트를 통해 배운 적이 있다. 심지어 JavaScript도 제대로 모른 채로. 그랬기 때문에 작은 프로젝트 하나도 몇 달을 걸려서 마무리 했고 기능 하나를 구현하는 데에도 수많은 에러를 마주쳤다. 아주 각종 에러란 에러는 다 마주쳤던 것 같다.

역시나 그럴 땐 검색을 통해 언어에 대한 문법, 기능 구현, UX, 숫자야구 알고리즘 등 많은 부분에서 도움을 받았기 때문에 나도 누군가의 도움이 될 수 있을까 하는 마음에 재작년에 완성했던 프로젝트를 올리고자 한다. 물론 그 사이에 React-Router v6가 나오면서 코드가 최신화도 아니고 React를 처음 배웠기 때문에 지금보면 엉성한 코드이지만.

처음 React 를 시작할 때 Root.js, App.js ... 등등 모든 것이 낯설어서 헤매었던 기억이 있어 상세한 CSS 코드를 제외한 모든 코드를 업로드할 예정이다.

개요 및 기본 구조

개요

프로젝트 구성하기


우선 React를 통해 프로젝트를 생성하자.
프로젝트를 구성할 폴더를 만들고 폴더에 들어간 후에 create-react-app으로 프로젝트를 생성해야한다.

create-react-app 프로젝트 명

그리고 게임 화면 페이지를 구성해야하기 때문에 React-router를 설치하자.

yarn add react-router-dom


기본 구조 설정

초안은 이렇다.


숫자야구 프로젝트의 기본 골조는 위와 같다.

또한 src폴더 안에는 이미지 등을 담는 assets 과 컴포넌트 폴더인 components, 폰트 폴더인 fonts, 각 페이지의 내용인 view 로 구성을 했다.

추가로 Node.js로 백엔드까지 구현했기 때문에 simple-server 폴더도 구성했지만 추후에 적겠다.


컴포넌트 준비하기

index.js 파일의 코드이다.

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Root from './view/Root';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
  <React.StrictMode>
    <Root />
  </React.StrictMode>,
  document.getElementById('root')
);

reportWebVitals();

Root.js 파일의 코드이다.

// src/view/Root.js
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

const Root = () => (
    <BrowserRouter>
        <App/>
    </BrowserRouter>
);

export default Root;

App.js 파일의 코드이다.

// src/view/App.js
import React from 'react'
import { Route } from 'react-router-dom'
import Home from './Home/index'
import PlayGround from './Game/index'
import End from './End/index'
import JoinMembership from './JoinMembership/index'


const App = () => {
    return (
        <div className={'fill-height'}>
            <Route exact path="/" component={Home} />
            <Route path="/play-ground" component={PlayGround} />
            <Route path="/End" component={End} />
            <Route path="/JoinMembership" component={JoinMembership} />
        </div>
    )
}

export default App

App.js 에선 이미 라우트를 설정해 놓은 상태이다. 라우트를 설정해놓을 땐, Route 컴포넌트를 설정하고 경로는 path 값으로 설정한다.
이때 첫 번째 라우트의 경우엔 exact가 붙어있는데 이게 붙어있으면 주어진 경로와 정확히 맞아 떨어져야만 설정한 컴포넌트를 보여준다.
만약 exact를 하지 않으면, path='/play-ground'path='/End'에도 /가 있기 때문에 매칭되어 Home 컴포넌트를 보여줄때 PlayGround 컴포넌트와 End 컴포넌트를 동시에 보여준다.

참고로 exactreact-router v6가 업데이트 되면서 사라진 옵션이다. 그러니 무시해도 좋다.

라우터 파라미터를 읽어 이동하기

라우터로 설정한 컴포넌트는 3가지의 props를 전달받는다. 각각 hitorylocation, match의 형식이 있다.
라우트를 이동하는 방법은 HTMLa 태그 방식인 <a ref...>data</a>의 방식으로 진행하면 안된다. 새로고침을 하기 때문이다. 그래서 라우트 이동은 Link 컴포넌트를 이용해 페이지를 새로 불러오는걸 막고, 원하는 라우트로 화면전환을 해준다.

해당 프로젝트에선 history 방식을 이용해서 파라미터를 읽고 이동시켰다. 코드는 다음과 같다.

// src/view/Home/index.js
import { useHistory } from 'react-router-dom'

const Home = () => {
    const history = useHistory()
    const onGameStartButtonClick = () => {
				// '/play-ground' 페이지로 이동
        history.push('/play-ground');
    }

    return(
        <div className="container">
            <button onClick={onGameStartButtonClick}>
                게임 시작
            </button>
        </div>
    )
}

export default Home

CSS

개요 및 기본 구조

개요

React 에서는 className 을 통해 선택자를 지정해준다. 하물며, 선택자의 이름은 카멜케이스를 적용하거나, 케밥케이스를 적용하기도 한다.
<div className='home-button' | 'home-btn'></div>


기본 구조

가장 상위 폴더에 css파일을 만들어서 하위 폴더에 모두 적용시킬 수 있도록 했다.
특히 fill-height의 이름으로 설정해 놓음으로써 글로벌하게 사용하게 했다.

/* after */
/* src/index.css */
.container{
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

.fill-height {
  height: 100vh !important
}

해당 프로젝트에서 GmarketSansMedium 라는 폰트를 사용했다. 따로 디렉토리를 만들어 폰트를 관리했고, 최상단에서 @font-face 를 관리했다. 또한 폰트를 적용하고 싶은 곳에 font-weight를 이용해서 적용해줬다.

눈누: https://noonnu.cc/

/* // src/view/index.css */
@font-face {
  font-family: 'GmarketSansMedium';
  src: url('./fonts/GmarketSansOTF/GmarketSansMedium.otf') format('woff');
  font-weight: normal;
  font-style: normal;
}

/* src/view/Home/index.css */
.game-start-button {
    ...
    font-family: 'GmarketSansMedium';
}

또한, 이번 프로젝트에서 부트스트랩이나 테일윈드같은 무료 템플릿 사이트를 이용해보고자 테일윈드 사이트를 참고했다. 먼저, 다음과 같이 최상단 index.csstailwind를 선언해주고 원하는 태그의 className에 원하는 디자인을 적용시켜주면 된다.

테일윈드: https://tailwindcss.com/

/* src/view/index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* src/view/Home/index.css */
<button
    className='logout-button text-gray-400 underline ...'
    onClick={onlogoutButtonClick}>
    로그아웃
</button>

반응형 웹 css 코드는 다음과 같다. 모바일, 태블릿, PC 화면 3가지로 나눠서 진행했고, 기준이 되는 max-width는 다음과 같다.

/* src/view/Home/index.css */
/* 핸드폰 */
@media screen and (max-width: 620px) {
	...
}

/* 태블릿 */
@media screen and (max-width: 900px) {
	...
}
profile
프론트엔드 개발자

0개의 댓글