관리 메뉴

Unwound Developer

Arcane - 클라이언트 구조 본문

Web/Node.js

Arcane - 클라이언트 구조

unwind 2022. 11. 13. 17:31
반응형

이번에는 클라이언트 쪽 코드 구조입니다.

client 구조

가장먼저 Root에 제일 가까운 App.jsx입니다.
jsx는 자바스크립트의 확장 문법을 지원하는 확장자로써, 자바스크립트안에서 HTML문법을 사용가능하도록 합니다.
기본적으로 Arcane 웹페이지 작동방식은 다음과 같아요.

page구조
component구조



Page폴더에있는 파일들 중 하나를 App.jsx에서 불러냅니다.
예를들어, Main.jsx 페이지를 불러냈다고 하면, 그 메인 페이지는 다시 필요한 컴포넌트들을 불러냅니다.
Main의 경우에는 Tobbar컴포넌트, 메인메뉴 컴포넌트 등을 부릅니다.


이렇게, 페이지는 상황에따라 여러 컴포넌트들을 갈아끼우는식으로 사용자에게 다른 모습을 보여줍니다.
마치 퍼즐조각을 끼웠다 뺐다 하는 느낌이에요.

// App.jsx
import  { Routes, Route, BrowserRouter }  from  "react-router-dom";
import Search from  "./page/search/Search.jsx";
import Login from  "./page/login/Login.jsx";
import Signup from  "./page/signup/Signup.jsx";
import Community from  "./page/community/Community.jsx";
...

react-router-dom 라이브러리를 Import해주고, 페이지들 또한 Import해줍니다. 컴포넌트들은 페이지에서 Import하고 실행하기 때문에, App.jsx에서 Import해줄 필요는 없습니다.

...
<BrowserRouter>
    <Routes>
        <Route  path="/summoners/:summoner"  element={<Summoners  />}  />
        <Route  path="/signup"  element={<Signup  />}  />
        <Route  path="/login"  element={<Login  />}  />
...

URL에 /summoners/{사용자닉네임} 이런식으로 입력이 들어오는것을 감지하면 Summoners 페이지를, /signup이 감지된다면 Signup페이지를 보여주는식으로 BrowserRouter가 작동합니다. 서버에서 Routing이 작동하는 것과 비슷한 느낌이기도해요.

페이지는 코드가 대체적으로 간단합니다. 단지 상황에따라 컴포넌트를 실행하는 역할만 수행하기 때문이에요.

// Login.jsx 페이지
import LoginMain from  "./../../components/login/Login_main";
import Topbar from  "./../../components/main_topbar/Topbar.jsx";
import style from  "./login.module.css";

function  Login()  {
    return (
        <>
            <Topbar  />
            <LoginMain  />
        </>
    );
}
export  default Login;

이렇게 리액트환경에서 HTML 문법을 쓰려고 .jsx확장자를 사용했던것입니다. 만약 App.jsx에서 Login페이지를 실행했다면, Login페이지는 다시 로그인 Tobar 컴포넌트와 LoginMain 컴포넌트를 순서대로 App.jsx에 Return 해줄것입니다. App.jsx는 Login페이지를 불렀을 뿐인데, 로그인 TopBar와 메인 컴포넌트를 모두 부른것이 되는거죠.

컴포넌트는 본격적으로 해당 페이지에서 필요로하는 기능을 실행하는 곳입니다.

// Login.jsx 컴포넌트
...
return (
    <div  className={style.login}>
        <div  className={style.loginWrapper}  ref={loginWrapper}>
            <div  className={style.loginTop}>
                <h3  className={style.loginLogo}>Arcane에 로그인하세요</h3>
            </div>
            <div  className={style.loginBottom}>
                <form  className={style.loginBoxID}  onSubmit={onSubmitID}>
                    <input
                    placeholder="아이디"
                    className={style.loginInputID}
                    onChange={changeUsername}
                    id="username"
                    />
                </form>
                ...

컴포넌트는 서버와 통신 등의 기능을 가진 다양한 함수, 전반적인 UI를 css와 함께 담당하고 있고, 위 처럼 페이지에 직접적으로 사용자에게 보여줄 HTML 코드를 Return합니다. 컴포넌트와 서버에서 사용한 다양한 라이브러리, 핵심 함수 등은 따로 다루겠습니다.


이처럼 리액트로 웹페이지의 Client부분을 다룰땐, App.jsx Page Components들의 상호작용으로 작성하곤 합니다. 이런점이 리액트의 가장 큰 장점이라고 할 수 있을텐데요. 여러 페이지에서 공통적으로 사용되는 부분, 예를 들면 내비게이션 바 같은것들이죠. 리액트를 사용하지 않는다면 페이지 별로 전부 내비게이션 바를 작성해줘야 할겁니다. 하지만, 리액트는 공통적으로 사용되는 부분을 컴포넌트로 작성 후, 페이지들에 붙이기만 하면 끝납니다. 재사용이 쉬우면서, 컴포넌트 형식으로 조각조각 관리하기 때문에, 유지 보수에도 장점을 가지고있습니다.


다음으론 db폴더에 있는 db.js 파일입니다. Arcane 프로젝트는 로그인과 회원가입, 커뮤니티, 'League of Legends' 사용자 전적 검색 등의 기능을 다양하게 사용하는지라, 클라이언트 에서 데이터베이스로 통신을 요청할 일이 잦습니다. 그래서 클라이언트에서 DB로 무언가를 요청하는 함수를 db.js에 넣고, 다른 컴포넌트에서는 db.js에 있는 함수를 호출하는 식으로 작성했습니다. 예를들면, 이전에 작성한 글에서 로그인과 회원가입 방식을 설명했었는데, 로그인을하면 서버에서 클라이언트에게 검증된 토큰을 반환하는 형식이었습니다(Json Web Token). 그럼 클라이언트가 서버에 무언가 요청할 때, 클라이언트의 토큰이 정말 서버에서 검증한 토큰인지 확인하는 부분이 필요한데, 모든 페이지에서 어떤 동작이든 항상 토큰을 검증합니다. 모든 페이지에 전부 작성하는것은 비 효율적이니 db.js에 작성했습니다.

// db.js
...
async  isValidToken(token)  {
    let username =  await axios
        .get("/auth",  {
            headers:  {
            token: token,
            },
        })
        .then((res)  =>  {
            return res.data.username;
        })
        .catch((err)  => console.log(err));return  await username;
}
...

함수들의 자세한 작동은 추후에 설명하고, db.js에는 이런식으로 데이터베이스와 통신할 수 있는 함수들을 모아놓았습니다.


riotAPI.js 파일은 저번에 올린 글 설명 그대로입니다. Riot사의 API에 직접접근하는 함수들을 모아놓은 파일입니다.

클라이언트의 구조는 여기까지입니다. 다음엔 클라이언트와 서버 코드작성 시에 사용되었던 중요 기술들을 설명하겠습니다.

반응형