[#CovidKoreaStatus] 토이 프로젝트 안내

RookieAND·2022년 7월 6일
2

Project

목록 보기
1/3
post-thumbnail

📖 Introduce

React.js를 학습한 후 처음으로 제작해본 토이 프로젝트를 소개합니다.

지난 6월 말부터 조금씩 학습해온 React 프레임워크를 본격적으로 활용해보았다.
아직 미숙한 점이 많지만 (lazy loading 등) 그래도 처음이 가지는 의미는 꽤 크다!

디자인과 설계 및 세부 기능 구현을 혼자서 하다보니 여러가지 문제도 많았지만..
그래도 혼자서 깨부하는 건 내 전문이라고 자신하기 때문에, 끝내 완성을 해냈다.

✒️ Design Project

이번 토이 프로젝트의 설계 배경개발 과정을 간단하게 소개하고자 한다.

React.js 를 처음으로 배우면서 이를 활용할 수 있는 방법이 뭐가 있을지를 고민했다.
그러던 중, 공공데이터 사이트를 뒤져보다 코로나 관련 Open API를 제공한다는 것을
알게 되었고, 이를 활용하여 간단한 정보 제공 사이트를 만드는 게 좋다고 생각했다.

아래는 내가 제공하고자 하는 정보를 정리한 목록이다. 생각보다 별 거 없다.

  1. 일주일 간격으로 전국의 코로나 확진자 수를 나열하고, 이를 시각화한다.
  2. 전국 선별 진료소를 시/도 별로 나누어 3 X 3 그리드 형식으로 나열한다.
  3. 해당 사이트의 기능에 대한 정보를 간단하게 안내하는 섹션을 추가한다.

💡 Learning Skills

✅ Axios Usage

const getCovidStatus = async (request) => {
    let response;
    try {
        response = await axios({
            method: 'GET',
            url: `${BASE_URL}/${process.env.COVID_STATUS_URL}`,
            params: {
                serviceKey: decodeURIComponent(process.env.COVID_STATUS_SERVICE_KEY),
            },
        });
    } catch (err) {
        console.log(err);
    }
    return response.data.response.result[0];
};

Python Flask 에서는 request 라이브러리를 사용하여 HTTP 통신을 진행했으나.
JS Express 환경에서는 axios 모듈을 사용하여 GET, POST 통신을 구현하였다.

또한 dotenv 모듈을 활용하여 .env 환경 변수 파일을 핸들링하는 방식도 익혔다.
이 또한 Flask 프레임워크에서 사용한 전적이 있었기에, 비교적 수월하게 사용하였다.

✅ styled-component

const fonts = {
    family: {
        base: `'Nanumsquare', sans-serif`,
        title: `'Noto Sans KR', serif`,
    },
    size: {
        xsm: '1rem',
        sm: '1.4rem',
        base: '1.6rem',
        lg: '2rem',
        xl: '2.5rem',
        xxl: '4rem',
        title: '6rem',
    },
    weight: {
        light: 100,
        normal: 400,
        bold: 700,
    },
};

... (이하 중략) ...

// 미디어 쿼리의 중복 코드를 줄이기 위해 선언된 변수
const device = {
    mobile: `@media only screen and (max-width: ${size.mobile})`,
    tablet: `@media only screen and (max-width: ${size.tablet})`,
    desktop: `@media only screen and (max-width: ${size.desktop})`,
};

export const defalutTheme = {
    margins,
    paddings,
    fonts,
    device,
    colors,
};

그동안은 React를 쓰면서 CSS Module로 각 컴포넌트의 요소들을 디자인했다.
하지만 이번에 styled-component 를 배우면서 JS 환경 내에서 CSS를 활용했다.

상단의 코드는 내가 자주 사용하는 CSS 옵션을 규격화시킨 Theme 모듈이다.
이렇게 모듈을 하나 만들어 놓으니, 스타일이 규격화되어 더욱 사용이 편해졌다.

✅ Chart.js

const CovidGraph = () => {
    const [loading, setLoading] = useState(true);
    const [corona, setCorona] = useState([]);
    useEffect(() => {
        const coronaStatus = async () => {
            let res = await axios.get('http://localhost:5000/api/status');
            setCorona(res.data);
            setLoading(false);
        };
        coronaStatus();
    }, []);

    const date = Array.from([...Array(7).keys()], (num) => corona[`mmdd${num + 1}`]);
    const confirmedCases = Array.from([...Array(7).keys()], (num) => corona[`cnt${num + 1}`]);
    const data = {
        labels: date,
        datasets: [
            {
                type: 'bar',
                label: '확진자',
                backgroundColor: 'rgba(0, 102, 176, 0.5)',
                data: confirmedCases,
            },
        ],
    };
    const option = {
        maintainAspectRatio: false,
        layout: {
            padding: {
                top: 5,
                left: 15,
                right: 15,
                bottom: 15,
            },
        },
        plugins: {
            legend: {
                display: true,
            },
        },
        interaction: {
            mode: 'index',
            intersect: false,
        },
        scales: {
            x: {
                grid: {
                    display: false,
                },
            },
            y: {
                grid: {
                    color: '#E3E3E3',
                },
            },
        },
    };

    return (
        <CovidGraphSection>
            {loading ? null : <ReactChart type='line' data={data} options={option} />}
        </CovidGraphSection>
    );

JS 모듈 중에서, 그래프 관련 기능을 지원하는 Chart.js 라이브러리를 알게 되었다.
따라서 이를 간단하게 사용하여 주간 코로나 확진자 수를 시각화 하고자 하였다.

아직은 코드 자체가 상당히 불필요한 구간이 많고 난잡하다고 생각한다. 사실이니까...
이 또한 리팩터링 과정을 거치면서 상당 부분을 유연하게 변경할 예정이다.

✅ Using Express Server

import express from 'express';
import cors from 'cors';
import dotenv from 'dotenv';

import covidStatusRouter from './api/covidStatus.js';
import traigeRouter from './api/traigeRoom.js';

dotenv.config({ encoding: 'utf8' });

const app = express();
const port = process.env.PORT || 5000;

// CORS Header를 추가하여 CORS 통신을 가능하게 한다.
// Web Application 간의 송신을 가능하게끔 열어주는 목적.
app.use(cors());
// Post의 Payload 데이터를 json 으로 파싱해주기 위한 작업.
app.use(express.json());

// Router를 통해 API 를 분리시켜 관리함.
app.get('/api/status', covidStatusRouter);
app.post('/api/traige', traigeRouter);

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(port, () => {
    console.log(`Example Express server with ${port}`);
});

Node.js 기반의 Express 를 통해 백엔드 서버를 처음으로 구축해보았다.
문법은 기존의 CommonJS 형식이 아닌 ES6 를 기준으로 작성해보았다.

그간 Python 기반의 Flask, Django에 익숙한 나로서는 참 신기하고 생소했지만..
사용을 해보고 나니 역시 Spring 을 빨리 익혀야겠다는 생각밖에 들지 않았다.

📱 Project UI/UX

이번 토이 프로젝트의 사이트 레이아웃 을 파트 별로 소개하고자 한다.

먼저 프로젝트의 메인 페이지 이다. 최상단에 네비게이션 바를 삽입하였다.
배경의 이미지와 제목을 최대한 잘 보이게 하려고 나름대로 고민을 하였다.

다음은 홈페이지의 기본적인 사용 방식을 안내하는 소개 페이지 이다.
제공하는 기능이 간단한 만큼, 아이콘과 심플한 메세지로만 구성하였다.

다음은 주간 전국 코로나 확진자 추이를 그래프로 나타낸 통계 페이지다.
아직 Chart.js 라이브러리를 다루는 것이 어려워 아쉬움이 큰 섹션이다.
추후 리팩터링 과정에서 차트 디자인을 대대적으로 개편해야겠다는 생각이 크다.

마지막으로 전국 시/도를 기준으로 분포된 선별 진료소들을 목록으로 나타낸 섹션이다.
이 섹션에 가장 많은 공을 들였고, 아직 풀어야 할 숙제도 제일 많이 직면한 곳이다.
그래도 최종적으로는 기능 구현에 성공했으니, 개인적으로는 아주 만족한다!


모바일 사용자를 위해 태블릿 기반의 레이아웃 또한 구현을 완료하였다.
미리 Theme 모듈에 저장해둔 query 변수를 잘 사용하여 빠르게 마무리 할 수 있었다.

https://github.com/RookieAND/CovidKoreaStatus

📚 Conclusion

이렇게 나의 첫 React.js 를 활용한 프로젝트가 어느덧 끝이 났다.
하지만 아직 해결해야 할 문제가 많기에 완전한 끝이라고 말할 수는 없다.

공식적으로 Heroku 플랫폼에 배포하기 위해 관련 자료를 열심히 찾는 중이다.
추후 업로드가 완료된다면 해당 URL 또한 이곳에 기입하도록 하겠다!


프로젝트를 진행하면서 아쉬운 점들은 아래와 같다.

  1. styled-component 의 목적인 재사용성을 제대로 활용하지 못했다.
  2. Component를 렌더링하는 과정에서 일부 최적화가 진행되지 않았다.
  3. 모바일 버전의 Layout을 아직 설계하지 못해 일부 섹션이 깨져 보인다. [✅ 2022/7/7]
  4. 실 서비스를 위한 호스팅을 진행하지 않았다. [✅ 2022/7/8]

상단의 문제점들은 추후 리팩터링 과정을 통해 단계적으로 해결할 예정이다.

profile
항상 왜 이걸 써야하는지가 궁금한 사람

0개의 댓글