일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 패스트캠퍼스
- 추상화
- Props
- Fetch
- 리액트
- 투두앱만들기
- 부트캠프
- 자바스트립트
- 타입스크립트
- 객체지향프로그래밍
- CSS
- 노마드코더
- typeScript
- 클래스
- 불변성
- 프론트엔드
- 자바스크립트
- 상속
- 캡슐화
- OOP
- frontend
- JavaScript
- REACT
- js
- 논리연산자
- 웹개발
- github
- Zustand
- webdevelopment
- Hooks
- Today
- Total
connecting dots
Toy project source code template understanding 본문
SPA 방식
Single Page Application(SPA)는 단일 HTML 페이지로 구성된 웹 애플리케이션 방식입니다. SPA에서는 페이지 전환이나 데이터 로드 시 전체 페이지를 새로 고치지 않고, 필요한 부분만 동적으로 업데이트합니다. JavaScript를 사용하여 클라이언트 측에서 이러한 작업을 처리합니다.
왜 SPA를 사용할까?
• 빠른 사용자 경험: 페이지 전환 시 전체 페이지를 다시 로드하지 않아서 더 빠르고 부드러운 사용자 경험을 제공합니다.
• 부드러운 내비게이션: 전체 페이지를 새로 고치지 않으므로 사용자 인터페이스가 더 부드럽고 자연스럽습니다.
• 효율적인 서버 통신: 필요한 데이터만 서버에서 가져오므로 네트워크 사용량이 적습니다.
SPA의 작동 원리
1. 초기 로드: 애플리케이션이 처음 로드될 때 필요한 HTML, CSS, JavaScript 파일을 한 번에 로드합니다.
2. 클라이언트 사이드 라우팅: JavaScript를 사용하여 URL 변경을 감지하고, 필요한 콘텐츠만 동적으로 업데이트합니다.
3. AJAX 사용: 비동기식 JavaScript와 XML(AJAX) 기술을 사용하여 서버와 통신하고 데이터를 주고받습니다.
예제
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple SPA</title>
<style>
.view {
display: none;
}
.view.active {
display: block;
}
</style>
</head>
<body>
<nav>
<a href="#home">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
</nav>
<div id="app">
<div id="home" class="view active">Welcome to the Home page!</div>
<div id="about" class="view">Learn more About us.</div>
<div id="contact" class="view">Contact us here.</div>
</div>
<script src="app.js"></script>
</body>
</html>
<head>
• <meta charset="UTF-8">는 문서의 인코딩을 UTF-8로 설정합니다.
• <meta name="viewport" content="width=device-width, initial-scale=1.0">는 반응형 디자인을 지원하도록 뷰포트 설정을 지정합니다.
• <title>Simple SPA</title>는 브라우저 탭에 표시될 페이지 제목을 설정합니다.
• <style> 태그는 간단한 CSS를 포함하며, .view 클래스는 기본적으로 보이지 않게 하고, .view.active 클래스는 보이게 설정합니다.
<body>
• <nav> 태그는 네비게이션 링크를 포함합니다. 각 링크는 href 속성에 해시(#home, #about, #contact)를 지정하여 URL의 해시 부분을 변경합니다.
• <div id="app">는 각 뷰를 포함하는 컨테이너입니다.
• <div id="home" class="view active">는 홈 페이지 콘텐츠를 포함하며, 초기 로드 시 활성화된 상태로 보입니다.
• <div id="about" class="view">와 <div id="contact" class="view">는 각각 About 및 Contact 페이지 콘텐츠를 포함하며, 초기 로드 시 보이지 않습니다.
• <script src="app.js"></script>는 app.js 파일을 로드하여 JavaScript 코드를 실행합니다.
Javascript
function showView(viewId) {
const views = document.querySelectorAll('.view');
views.forEach(view => {
view.classList.remove('active');
if (view.id === viewId) {
view.classList.add('active');
}
});
}
window.addEventListener('hashchange', () => {
const hash = window.location.hash.substring(1);
showView(hash);
});
// 초기 로딩 시 현재 해시 값에 따라 뷰를 설정합니다.
if (window.location.hash) {
showView(window.location.hash.substring(1));
} else {
window.location.hash = '#home';
}
showView 함수
• showView 함수는 viewId 매개변수를 받아서 해당 ID를 가진 뷰를 활성화합니다.
• document.querySelectorAll('.view')를 사용하여 모든 뷰를 선택하고, 각각의 뷰에서 active 클래스를 제거합니다.
• view.id === viewId인 경우, 즉 전달된 viewId와 일치하는 뷰에 active 클래스를 추가하여 해당 뷰를 보이게 합니다.
해시 변경 이벤트 리스너
• window.addEventListener('hashchange', ...)는 URL의 해시 부분이 변경될 때마다 호출되는 이벤트 리스너를 추가합니다.
• window.location.hash는 URL의 해시 부분을 반환합니다. substring(1)을 사용하여 # 문자를 제거하고 실제 해시 값을 얻습니다.
• showView(hash)를 호출하여 변경된 해시 값에 해당하는 뷰를 활성화합니다.
초기 로딩 시 뷰 설정
• 페이지가 처음 로드될 때, 현재 URL에 해시가 있는지 확인합니다.
• 해시가 있다면 showView 함수를 호출하여 해당 뷰를 활성화합니다.
• 해시가 없다면 기본적으로 #home 해시를 설정하여 홈 뷰를 활성화합니다.
라우터
라우터(router)는 웹 애플리케이션에서 URL 경로와 애플리케이션 내의 특정 코드나 컴포넌트를 연결하는 역할을 합니다. 쉽게 말해, 사용자가 어떤 URL을 방문했을 때 어떤 화면이나 기능을 보여줄지를 결정하는 시스템입니다. 라우터는 특히 Single Page Application(SPA)에서 중요한 역할을 합니다.
왜 라우터가 중요한가요?
1. 페이지 내비게이션: 사용자가 다른 URL로 이동할 때마다 전체 페이지를 새로 고치지 않고도 다른 콘텐츠를 보여줄 수 있습니다.
2. 코드 관리: 다양한 URL 경로에 대해 어떤 컴포넌트를 로드할지 명확하게 정의할 수 있어 코드 관리가 용이합니다.
3. 사용자 경험: 페이지 전환 시 빠르고 부드러운 사용자 경험을 제공합니다.
라우터의 기본 개념
1. 경로(Route): URL 경로와 그 경로에서 보여줄 컴포넌트를 정의합니다.
2. 라우팅(Routing): 사용자가 특정 URL을 요청할 때 어떤 컴포넌트를 보여줄지 결정하는 과정입니다.
라우터의 작동 방식
1. 사용자가 특정 URL을 입력하거나 링크를 클릭하면, 라우터는 해당 URL 경로를 감지합니다.
2. 라우터는 해당 경로에 맞는 컴포넌트나 페이지를 로드하여 사용자에게 보여줍니다.
3. 이 모든 과정은 브라우저의 기본 페이지 새로 고침 없이 JavaScript로 처리됩니다.
예제
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Router</title>
</head>
<body>
<nav>
<a href="#home">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
</nav>
<div id="app">
<!-- 콘텐츠가 여기에 로드됩니다 -->
</div>
<script src="router.js"></script>
</body>
</html>
Javascript
const routes = {
'#home': '<h1>Home Page</h1><p>Welcome to the Home page!</p>',
'#about': '<h1>About Page</h1><p>Learn more About us.</p>',
'#contact': '<h1>Contact Page</h1><p>Contact us here.</p>'
};
function router() {
const hash = window.location.hash;
const app = document.getElementById('app');
app.innerHTML = routes[hash] || '<h1>404 Not Found</h1><p>Page not found!</p>';
}
window.addEventListener('hashchange', router);
// 초기 로딩 시 라우팅 설정
window.addEventListener('load', router);
라우트 정의
• routes 객체는 URL 해시와 해당하는 HTML 콘텐츠를 매핑합니다. 예를 들어, #home 해시가 있을 때 표시할 HTML 콘텐츠를 정의합니다.
라우터 함수
• router 함수는 현재 URL 해시 값을 가져와(window.location.hash), routes 객체에서 해당하는 콘텐츠를 찾아 app 요소의 innerHTML에 설정합니다.
• 만약 현재 해시 값이 routes 객체에 없으면, “404 Not Found” 페이지를 표시합니다.
해시 변경 이벤트 리스너
• hashchange 이벤트는 URL의 해시 값이 변경될 때 발생합니다. 이 이벤트가 발생하면 router 함수를 호출하여 적절한 콘텐츠를 로드합니다.
초기 로딩 시 라우팅 설정
• load 이벤트는 페이지가 처음 로드될 때 발생합니다. 이 이벤트가 발생하면 router 함수를 호출하여 현재 URL 해시 값에 따라 적절한 콘텐츠를 로드합니다.
동작 과정 요약
1. 페이지 로드 시:
• window.addEventListener('load', router);가 호출되어 현재 해시 값에 따라 콘텐츠를 로드합니다.
• 만약 해시 값이 없으면 기본으로 #home 콘텐츠가 로드됩니다.
2. 링크 클릭 시:
• 사용자가 네비게이션 링크를 클릭하면 URL의 해시 값이 변경됩니다.
• window.addEventListener('hashchange', router);가 호출되어 변경된 해시 값에 따라 새로운 콘텐츠를 로드합니다.
동기와 비동기
동기 (Synchronous)
동기 방식에서는 하나의 작업이 완료된 후에야 다음 작업이 시작됩니다. 모든 작업이 순차적으로 실행되며, 이전 작업이 완료될 때까지 다음 작업은 기다립니다. 동기 방식은 직관적이지만, 긴 작업이 있을 경우 전체 프로그램이 대기 상태가 될 수 있습니다.
function syncFunction() {
console.log("작업 1 시작");
// 작업 1 (예: 복잡한 계산)
console.log("작업 1 완료");
console.log("작업 2 시작");
// 작업 2 (예: 파일 읽기)
console.log("작업 2 완료");
}
syncFunction();
// 출력
작업 1 시작
작업 1 완료
작업 2 시작
작업 2 완료
비동기 (Asynchronous)
비동기 방식에서는 작업이 시작되면 그 작업의 완료 여부와 상관없이 다음 작업이 즉시 시작될 수 있습니다. 비동기 작업은 대기 상태에서 블로킹되지 않으며, 완료되었을 때 콜백 함수나 프로미스(약속)를 통해 결과를 처리합니다. 이는 특히 네트워크 요청이나 파일 읽기 같은 시간이 오래 걸리는 작업에 유용합니다.
function asyncFunction() {
console.log("작업 1 시작");
setTimeout(() => {
// 작업 1 (예: 네트워크 요청) - 2초 후 완료
console.log("작업 1 완료");
}, 2000);
console.log("작업 2 시작");
// 작업 2 (즉시 완료)
console.log("작업 2 완료");
}
asyncFunction();
// 출력
작업 1 시작
작업 2 시작
작업 2 완료
작업 1 완료 (2초 후 출력)
주요 차이점
1. 처리 순서:
• 동기: 작업이 순차적으로 실행되며, 앞선 작업이 완료될 때까지 기다립니다.
• 비동기: 작업이 동시에 실행될 수 있으며, 완료 여부와 상관없이 다음 작업이 실행됩니다.
2. 성능:
• 동기: 긴 작업이 있으면 전체 프로그램이 블로킹됩니다.
• 비동기: 긴 작업이 있어도 다른 작업이 동시에 실행될 수 있어 더 효율적입니다.
3. 복잡성:
• 동기: 코드가 직관적이며 읽기 쉽습니다.
• 비동기: 콜백, 프로미스, async/await 등을 사용하여 비동기 작업을 처리해야 하므로 코드가 복잡해질 수 있습니다.
async/await
async/await는 JavaScript에서 비동기 코드를 동기 코드처럼 작성할 수 있게 해주는 문법입니다. 이 문법을 사용하면 비동기 작업을 더 읽기 쉽고 관리하기 쉽게 만들 수 있습니다. async/await는 Promise와 함께 사용됩니다.
기본 개념
• async 함수: async 키워드를 함수 앞에 붙여서 해당 함수가 비동기 함수를 나타내도록 합니다. 비동기 함수는 항상 Promise를 반환합니다.
• await 키워드: await 키워드는 비동기 함수 내부에서만 사용할 수 있으며, Promise가 처리될 때까지 함수 실행을 일시 중단하고 결과를 반환합니다. await는 Promise가 완료될 때까지 기다린 다음, 그 결과 값을 반환합니다.
기본 사용법
async 함수
myAsyncFunction은 Promise를 반환하는 비동기 함수입니다. 이 함수는 자동으로 Promise로 래핑됩니다.
async function myAsyncFunction() {
return "Hello, World!";
}
await 키워드
코드에서 await fetch('https://api.example.com/data')는 fetch 함수가 반환하는 Promise가 처리될 때까지 기다립니다. fetch가 완료되면 응답 객체(response)를 반환합니다. 이후 await response.json()은 응답 객체를 JSON으로 파싱하는 비동기 작업을 기다립니다.
async function fetchData() {
let response = await fetch('https://api.example.com/data');
let data = await response.json();
console.log(data);
}
fetch
Fetch API는 JavaScript에서 네트워크 요청을 쉽게 할 수 있게 해주는 도구입니다. Fetch를 사용하면 데이터를 서버로부터 가져오거나 서버에 데이터를 보낼 수 있습니다. 주로 API와 통신할 때 사용됩니다.
기본 예제
// 데이터를 가져오는 함수
function fetchData() {
// Fetch API를 사용하여 데이터 가져오기
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => response.json()) // 응답을 JSON으로 변환
.then(data => {
console.log(data); // 가져온 데이터를 콘솔에 출력
})
.catch(error => {
console.error('Error fetching data:', error); // 에러 처리
});
}
// 함수 호출
fetchData();
위 예제에서는 https://jsonplaceholder.typicode.com/posts에서 데이터를 가져와 JSON 형식으로 변환한 후 콘솔에 출력합니다.
async/await 사용
async/await 문법을 사용하면 Fetch API를 더 직관적으로 사용할 수 있습니다.
async/await 예제
// 비동기 함수를 선언하여 데이터를 가져옴
async function fetchData() {
try {
// Fetch API를 사용하여 데이터 가져오기
let response = await fetch('https://jsonplaceholder.typicode.com/posts');
let data = await response.json(); // 응답을 JSON으로 변환
console.log(data); // 가져온 데이터를 콘솔에 출력
} catch (error) {
console.error('Error fetching data:', error); // 에러 처리
}
}
// 함수 호출
fetchData();
위 예제에서는 await 키워드를 사용하여 fetch 요청이 완료될 때까지 기다리고, 응답을 JSON으로 변환합니다. try...catch 블록을 사용하여 에러를 처리합니다.
POST 요청 보내기
Fetch API를 사용하여 데이터를 서버에 보낼 수도 있습니다. POST 요청을 사용하여 데이터를 서버에 보내는 방법을 보겠습니다.
POST 요청 예제
// 비동기 함수를 선언하여 데이터를 서버로 보냄
async function postData() {
try {
let response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST', // HTTP 메서드를 POST로 설정
headers: {
'Content-Type': 'application/json' // 요청 헤더 설정
},
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
}) // 전송할 데이터를 JSON 문자열로 변환
});
let data = await response.json(); // 응답을 JSON으로 변환
console.log(data); // 서버로부터의 응답 데이터를 콘솔에 출력
} catch (error) {
console.error('Error posting data:', error); // 에러 처리
}
}
// 함수 호출
postData();
위 예제에서는 POST 메서드를 사용하여 서버에 데이터를 전송합니다. headers 속성을 통해 요청 헤더를 설정하고, body 속성에 전송할 데이터를 JSON 문자열로 변환하여 포함시킵니다.
요약
• fetch() 함수: 네트워크 요청을 시작합니다.
• Promise 반환: fetch 함수는 Promise를 반환합니다.
• .then() 메서드: Promise가 완료되면 .then() 메서드를 사용하여 응답을 처리합니다.
• .catch() 메서드: 네트워크 요청 중 에러가 발생하면 .catch() 메서드를 사용하여 에러를 처리합니다.
• async/await: 비동기 코드를 더 직관적으로 작성할 수 있도록 도와줍니다.
• GET 요청: 서버로부터 데이터를 가져올 때 사용합니다.
• POST 요청: 서버에 데이터를 보낼 때 사용합니다.
'Project > Toy Project 1' 카테고리의 다른 글
토이 프로젝트 1 회고 (2) | 2024.07.15 |
---|---|
BEM 네이밍 (0) | 2024.06.16 |