React : SPA & SCSS

camilleยท2022๋…„ 5์›” 12์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
2/9
post-thumbnail

๐Ÿ“• SPA

Single Page Application (์‹ฑ๊ธ€ ํŽ˜์ด์ง€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜)์˜ ์•ฝ์ž์ด๋‹ค.
์ฆ‰, ํŽ˜์ด์ง€๊ฐ€ 1๊ฐœ์ธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋ž€ ๋œป์œผ๋กœ ์œ ์ €๊ฐ€ ์š”์ฒญ ํ•  ๋•Œ ๋งˆ๋‹ค ํŽ˜์ด์ง€๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ ์ œ๊ณต๋˜๋Š” ์ •๋ณด๊ฐ€ ์ •๋ง ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์†๋„์ ์ธ ์ธก๋ฉด์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , ๋ถˆํ•„์š”ํ•œ ํŠธ๋ž˜ํ”ฝ์œผ๋กœ ์ธํ•œ ๋‚ญ๋น„๊ฐ€ ์‹ฌํ•ด์ง€๊ธฐ๋•Œ๋ฌธ์— ๋ฆฌ์•กํŠธ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜น์€ ํ”„๋ ˆ์ž„ ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ทฐ๋ Œ๋”๋ง์„ ์œ ์ €์˜ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋‹ด๋‹นํ•˜๋„๋ก, ํ•˜๊ณ  ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ธŒ๋ผ์šฐ์ €์— ๋กœ๋“œํ•œ ๋‹ค์Œ ํ•„์š”ํ•œ ์ •๋ณด๋งŒ ๋ณด์—ฌ์ค€๋‹ค.

๐Ÿ“Œ ์‹ฑ๊ธ€ํŽ˜์ด์ง€๋ผ๊ณ  ํ•ด์„œ, ํ•œ ์ข…๋ฅ˜์˜ ํ™”๋ฉด๋งŒ ์žˆ๋Š”๊ฐ€?

๊ทธ๊ฑด No. ์˜ˆ๋ฅผ๋“ค์–ด ๋ธ”๋กœ๊ทธ๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด, ํ™ˆ, ํฌ์ŠคํŠธ ๋ชฉ๋ก, ํฌ์ŠคํŠธ, ๊ธ€์“ฐ๊ธฐ ๋“ฑ์˜ ํ™”๋ฉด์ด ์žˆ๋‹ค.

๋‹ค๋ฅธ ์ฃผ์†Œ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋ทฐ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š”๊ฒƒ์„ ๋ผ์šฐํŒ…์ด๋ผ ํ•˜๋ฉฐ, ๋ฆฌ์•กํŠธ ์ž์ฒด์—๋Š” ์ด ๊ธฐ๋Šฅ์ด ๋‚ด์žฅ๋˜์–ด์žˆ์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ๋ธŒ๋ผ์šฐ์ €์˜ API ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ƒํƒœ๋ฅผ ์„ค์ •ํ•˜์—ฌ ๋‹ค๋ฅธ ๋ทฐ๋ฅผ ๋ณด์—ฌ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

react-router ๋Š”, ์จ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ์„œ, ๋น„๋ก ๊ณต์‹์€ ์•„๋‹ˆ์ง€๋งŒ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ๋ฐ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ์—์„œ ์ด๋ค„์ง€๋Š” ๋ผ์šฐํŒ…์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.

๐Ÿ“Œ SPA์˜ ๋‹จ์ ์€ ๋ฌด์—‡์ธ๊ฐ€?

SPA ์˜ ๋‹จ์ ์€, ์•ฑ์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ ์‚ฌ์ด์ฆˆ๊ฐ€ ๋„ˆ๋ฌด ์ปค์ง„๋‹ค๋Š” ์ ์•„๋‹ค.


๐Ÿ“• React : Router

  • ๋ผ์šฐํŒ…(Routing)์ด๋ผ๋Š” ๊ฒƒ์€ ๋‹ค๋ฅธ ๊ฒฝ๋กœ(url ์ฃผ์†Œ)์— ๋”ฐ๋ผ ๋‹ค๋ฅธ View(ํ™”๋ฉด)๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

  • ๋ฆฌ์•กํŠธ ์ž์ฒด์—๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์ด ๋‚ด์žฅ๋˜์–ด์žˆ์ง€ ์•Š๋Š”๋‹ค.

๐Ÿ‘ฉโ€๐Ÿซ Router : ์‹คํ–‰ํ•˜๊ธฐ


๐Ÿ‘‰ ๋จผ์ € Router.js ํŒŒ์ผ์„ srcํด๋”์— ๋งŒ๋“ค์–ด ์ค€๋‹ค.

์œ„์น˜ : App.js


import { useNavigate } from 'react-router-dom';
import './App.scss';

function App() {
  const navigate = useNavigate();
  const goToLogin = () => {
  navigate('/login');
}
  return (
    <div className='app'>
      <div onClick ={goToLogin}>go to Login</div>
    </div>
  );
  }


export default App;

------------------------------------------------------------

์œ„์น˜ : Login.js

import React from 'react';
import { Link } from 'react-router-dom';


const Login = () =>{
    return(
            <div>
            <Link to ="/">go to App</Link>
            </div>
        );
};

export default Login;

-------------------------------------------------------------
  
์œ„์น˜ : Nav.js
  
import React from 'react';

const Nav = () => {
    return(
        <div>
            <h1>Nav</h1>
        </div>
    );
};

export default Nav;

๐Ÿ‘‰ App.js์™€ Login.js, Nav.js ํด๋”์— ๋“ค์–ด๊ฐ€์„œ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๊ธธ ์›ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ์ค€๋‹ค.

๐Ÿ‘‰ Nav.js์˜ ๊ฒฝ์šฐ๋Š” ์ปดํฌ๋„ŒํŠธ๋กœ ์ œ์ž‘ํ•ด์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉํ•  ๋•Œ ์šฉ์ดํ•˜๊ฒŒ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜์žˆ๋„๋ก ํ•œ๋‹ค.

import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import App from "./App";
import Login from './Login';
import Nav from './Nav';

const Router = () => {
    return (
        <BrowserRouter>
        <Nav />
            <Routes>
                <Route  path="/" element={<App />} />
                <Route  path="/login" element={<Login />} />
            </Routes>
        </BrowserRouter>
    );
};

export default Router;

๐Ÿ‘‰ Router.js๋กœ ์ด๋™ํ•ด์„œ BrowserRouter์•ˆ์— Routes๋ฅผ ๋„ฃ๊ณ  Route์— ๋„ฃ๊ณ  ์‹ถ์€ ํŒจ์Šค์™€, ์—ฐ๊ฒฐํ•˜๊ณ ์žํ•˜๋Š” ๋ถ€๋ถ„์„ ์œ„์˜ ์ฝ”๋“œ ์ฒ˜๋Ÿผ ์ž‘์„ฑํ•œ๋‹ค.

๐Ÿ’ก ์ฃผ์˜ : import App from "./App"์™€ ๊ฐ™์€ import๋ฅผ ๋ฐ›์•„์˜ค๋Š” ๋ถ€๋ถ„์— ์ž‘์„ฑํ•˜๊ณ , export default Login์™€ ๊ฐ™์€ export๋ฅผ ๋‚ด๋ณด๋‚ด๋Š” App.js์— ์ž‘์„ฑํ•ด ์ค€๋‹ค.

๐Ÿ‘‰ terminal์—์„œ npm start๋ฅผ ํ•ด์ค€ ๋’ค ํ™”๋ฉด์„ ๋ณด๋ฉด ์ง€์ •ํ•ด์ค€ ํŒจ์Šค์ธ "/ " -> localhost:3001์—), "/login" -> localhost:3001/login์ด ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.



Nav๋Š” ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“ค์–ด์„œ ๊ณ ์ •ํ•ด ์คฌ๊ธฐ ๋•Œ๋ฌธ์— path ๊ฒฝ๋กœ๋ฅผ ์ด๋™ํ•˜์—ฌ๋„ ๊ณ ์ •๋˜์–ด ๋‚˜ํƒ€๋‚œ๋‹ค.


import React from 'react';
import { BrowserRouter, Route, Routes} from 'react-router-dom';
import App from './App';
import Login from './Login';

const Router = () => {
  return (
  <BrowserRouter>
    <Routes>
      <Route path = "/" element = {<App .>} />
    </Routes>
 </BrowserRouter>
  );
};

export default Router;

๋ณดํ†ต ๋Œ€๋ฌธ์ž๋Š” ์ปดํฌ๋„ŒํŠธ๋กœ ์ธ์‹ํ•˜๊ณ , ํŒจ์Šค๋Š” ์†์„ฑ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

import React from 'react';
import {Link} form 'reat-router-dom';

const Login = () => {
  return (
    <div>
      <Link to ="/">go to App</Link>
    </div>
  );
};

export default Login;

aํƒœ๊ทธ ๊ฐ™์€ ๊ฒฝ์šฐ ์›น์œผ๋กœ ๋ณด๋‚ผ๋•Œ ex) ์ธ์Šคํƒ€ ํ•˜๋‚˜? ํ•˜๊ณ  ์ฐพ์•„๋ณด๋Š” ๊ฒฝ์šฐ,
Link๋Š” ๊ทธ ์•ˆ์—์„œ ๋‚ด์šฉ์„ ๋ณด์—ฌ์ค„ ๋•Œ ์‚ฌ์šฉ ํ•œ๋‹ค.


์œ„์น˜ : App.js 

improt { useNavigaate } from 'react-router-dom';

function App() {
  const navigate = userNavigate();
  const goToLogin = () => {
    navigate('/login');
  };
  
  return (
    <div>
      <div onClick = {goToLogin}>go to Login</div>
    </div>
  );
}

export default App;

์™œ ๋„ค๋น„๊ฒŒ์ดํŠธ๋ฅผ ์‚ฌ์šฉํ• ๊นŒ??
a ํƒœ๊ทธ๋Š” ๋‹ค๋ฅธ CSSํŒŒ์ผ์„ ์ž‘์„ฑํ•˜๊ฒŒ ๋” ์š”๊ตฌ๋ฅผ ํ•œ๋‹ค.
Link๋Š” ํด๋ฆญํ–ˆ์„ ๊ฒฝ์šฐ ๋ฐ”๋กœ ์ด๋™์„ ํ•˜๋Š”๋ฐ, Navigate๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ์กฐ๊ฑด์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๋‹ค.

์œ„์น˜ : router.js

import React from "react";
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import App from "./App";
import Login from "./Login";
import Nav from "./Nav";

const Router = () => {
  return (
   <BrowserRouter>
    <Nav />
      <Routes>
         <Route path="/" element= {<App />} />
         <Route path="/login" element = {<Login />} />
      </Routes>
   </BrowserRouter>
  );
};

export default Router;

๐Ÿ“• CSS -> SCSS

Sass์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ธฐ๋Šฅ์œผ๋กœ Nesting ์ด๋ผ๋Š” ๊ฒƒ์ด ์žˆ๋Š”๋ฐ, JSX ์ตœ์ƒ์œ„ ์š”์†Œ์˜ 'className'์„ ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„๊ณผ ๋™์ผํ•˜๊ฒŒ ์„ค์ •ํ•ด์ฃผ๊ณ , '.scss' ํŒŒ์ผ์—์„œ๋„ ์ตœ์ƒ์œ„ ์š”์†Œ ์•ˆ ์ชฝ์—์„œ ํ•˜์œ„ ์š”์†Œ์˜ ์Šคํƒ€์ผ ์†์„ฑ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿ“— CSS

nav ul{
  margin :0;
  padding: 0;
  list-style: none;
}

nav li {
  display : inline-block;
}

nav a {
  display: block;
  padding: 6px 12px;
  text-decoration : none;
}

๐Ÿ“— SCSS


nav{
  ul{
    margin : 0;
    padding: 0;
    list-style: none;
    
      li{
        display: inline-block;
      }
  }
  a{
   display: block;
   padding: 6px 12px;
   text-decoration: none;
  }
 }

๐Ÿ““ CSS

.login-container{
  display: flex;
  justify-content: center;
  align-items: center;
}

button{
  width: 200px;
  height: 100px;
  background-color: blue;
}
button:hover{
  background-color: red;
  cursor: pointer;
}
input{
  background-color: blue;
}
input:focus{
 background-color: red;
}

๐Ÿ““ SCSS

$theme-color: blue;
$border-style: 1px black solid;

@mixin flex-center{
  display: flex;
  justify-content: center;
  align-items: center;
}

.login-container{
  @include flex-center;
  
  button{
    width: 200px;
    height: 100px;
    background-color: $theme-color;
    
    &:hover{
      backgound-color: red;
      cursor: pointer;
    }
  }
  
  input{
   background-color: $theme-color;
  }
}

0๊ฐœ์˜ ๋Œ“๊ธ€