<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>yu.log</title>
        <link>https://velog.io/</link>
        <description>도라에몽 암기빵</description>
        <lastBuildDate>Mon, 30 Oct 2023 15:51:13 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>yu.log</title>
            <url>https://velog.velcdn.com/images/yuj_125/profile/35d6b2a0-2e84-4e01-ba53-c3efc0b7dbed/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. yu.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/yuj_125" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[React] 상태 관리]]></title>
            <link>https://velog.io/@yuj_125/React-%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@yuj_125/React-%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Mon, 30 Oct 2023 15:51:13 GMT</pubDate>
            <description><![CDATA[<h1 id="📝-상태-관리란">📝 상태 관리란?</h1>
<blockquote>
<p>상태 관리 기술이란 앱 상에서의 데이터를 메모리 등에 저장하고 하나 이상의 컴포넌트에서 데이터를 공유하는 것 이다.</p>
</blockquote>
<p><br><br></p>
<h3 id="mpa와-spa의-상태관리-차이점">MPA와 SPA의 상태관리 차이점</h3>
<p><strong>MPA</strong> : 서버의 데이터를 이용해 페이지를 렌더링하므로 클라이언트의 데이터와 서버의 데이터가 큰 차이를 가지지 않는다.
<strong>SPA</strong> : 자체적으로 데이터를 갖고 서버와의 동기화가 필요한 데이터만을 처리한다. 그외의 데이터는 Client만의 데이터로 유지한다.</p>
<p><br><br></p>
<h1 id="상태-관리-기술의-도입">상태 관리 기술의 도입</h1>
<p>• 상태가 많지 않거나, 유저와의 인터렉션이 많지 않다면 매 작업 시 서버와 동기화하는 것으로 충분하지만 앱이 사용하는 데이터가 점점 많아지고, 유저와의 인터렉션 시 임시로 저장하는 데이터가 많아지는 경우 상태 관리를 고려해야 한다.
• 프론트엔드 뿐만 아니라, 백엔드와의 데이터 통신도 충분히 고려해야 한다. ex) GraphQL</p>
<p><br><br></p>
<h1 id="📈-상태-관리-기술의-장점">📈 상태 관리 기술의 장점</h1>
<p>• 높은 품질의 코드를 작성하는 데 유리하다.
• 성능 최적화, 네트워크 최적화 등에 유리하다.
• 데이터 관리의 고도화할 수 있다. ex) localStorage 활용한 persist state</p>
<p><br><br></p>
<h1 id="📉-상태-관리-기술의-단점">📉 상태 관리 기술의 단점</h1>
<p>• Boilerplate 문제가 있다.
• 파악해야 할 로직과 레이어가 많아진다.
• 잘못 사용할 경우, 앱의 복잡도만을 높이거나, 성능을 악화시킬 수 있다. ex) global state의 잘못된 활용 시 앱 전체 리렌더링 발생</p>
<p><br><br></p>
<h1 id="flux-pattern">Flux Pattern</h1>
<h3 id="1-flux-pattern의-정의">1) Flux Pattern의 정의</h3>
<p>2014년에 Facebook에서 제안한 웹 애플리케이션 아키텍처 패턴으로 Unidirectional data flow를 활용하여 데이터의 업데이트와 UI 반영을 단순화한다. React의 UI 패턴인 합성 컴포넌트와 어울리도록 설계되었다.
• redux, react-redux 라이브러리의 Prior art</p>
<h3 id="2-mvc-pattern과-비교">2) MVC Pattern과 비교</h3>
<p>• <strong>MVC 패턴</strong>은 애플리케이션을 Model, View, Controller로 분리하여 개발하는 소프트웨어 디자인 패턴 중 하나이다. View에서 특정 데이터를 업데이트하면 연쇄적인 업데이트가 일어난다. 특정 유저의 인터렉션이 여러 UI 컴포넌트가 사용하는 데이터에 영향을 줄 때, MVC만으로는 앱의 복잡도를 낮추거나 업데이트의 흐름을 따라가기 어렵다. 앱이 커질수록 업데이트의 흐름을 따라가기 힘들다는 단점이 있다.
• <strong>Flux</strong>는 하나의 Action이 하나의 Update만을 만들 수 있다. data와 업데이트가 한 방향으로 흐르기 때문에 UI의 업데이트를 예측하기 쉽다.</p>
<h3 id="3-flux-pattern의-구조">3) Flux Pattern의 구조</h3>
<p><strong>Action -&gt; Dispatcher -&gt; Store -&gt; View 순으로 데이터가 흐른다.</strong>
• store : 미리 dispatcher에 callback을 등록해, 자신이 처리할 action을 정의한다.
• action creator : action을 생성하여 dispatcher로 보낸다.
• dispatcher : action을 store로 넘긴다.
• store : action에 따라 데이터를 업데이트 후, 관련 view로 변경 이벤트 발생한다.
• view : 데이터를 다시 받아와 새로운 UI를 만든다. 유저 인터렉션이 발생하면 View는 action을 발생한다.</p>
<p><br><br></p>
<h1 id="상태-관리에-사용되는-훅">상태 관리에 사용되는 훅</h1>
<p>• 외부 라이브러리 없이 React가 제공하는 훅 만으로 상태 관리를 구현하기 위해 사용한다.
• 함수형 컴포넌트에 상태를 두고, 여러 컴포넌트 간 데이터와 데이터 변경 함수를 공유하는 방식으로 상태를 관리하게 된다.
<strong>useState, useRef, useContext, useReducer</strong></p>
<h3 id="1-usestate">1) useState</h3>
<p>• 단순한 하나의 상태를 관리하기에 적합하여 상태와 상태에 대한 변화가 단순하거나, 상대적으로 소규모 앱에서 사용한다.
• 상위 컴포넌트에서 state와 state 변경 함수를 정의하고, 그 state나 변경 함수를 사용하는 컴포넌트까지 prop으로 내려주는 패턴이다.
• state가 변경되면, 중간에 state를 넘기기만 하는 컴포넌트들도 모두 리렌더링된다.
• useEffect와 함께, state에 반응하는 훅을 구축한다.</p>
<pre><code class="language-javascript">const [ state, setState ] = useState(initState | initFn)</code></pre>
<h3 id="2-useref">2) useRef</h3>
<p>• 상태가 바뀌어도 리렌더링하지 않는 상태를 정의한다. 상태가 UI의 변경과 관계없을 때 사용한다. ex) setTimeout의 timerId 저장
• uncontrolled component의 상태를 조작하는 등, 리렌더링을 최소화하는 상태 관리에 사용된다. ex) Dynamic Form 예시</p>
<h3 id="3-usecontext">3) useContext</h3>
<p>• Provider 단에서 상태를 정의하고, 직접 상태와 변경 함수를 사용하는 컴포넌트에서 useContext를 이용해 바로 상태를 가져와 사용하는 패턴이다.
• 컴포넌트와 컴포넌트 간 상태를 공유할 때 사용한다.
• 부분적인 컴포넌트들의 상태 관리, 전체 앱의 상태 관리를 모두 구현한다.
• state는 필요한 곳에서만 사용하므로, 불필요한 컴포넌트 리렌더링을 방지한다.
• Context Provider 안에서 렌더링되는 컴포넌트는, useContext를 이용해 깊이 nested 된 컴포넌트라도 바로 context value를 가져온다.
• context value가 바뀌면 내부 컴포넌트는 모두 리렌더링된다.
• useReducer와 함께 복잡한 상태와 상태에 대한 변경 로직을 두 개 이상의 컴포넌트에서 활용하도록 구현 가능하다.
• Prop Drilling(Plumbing)을 방지하여 컴포넌트 간 결합도를 낮춘다.</p>
<h3 id="4-usereducer">4) useReducer</h3>
<p>• useState보다 복잡한 상태를 다룰 때 사용한다.
• 별도의 라이브러리 없이 flux pattern에 기반한 상태 관리를 구현한다.
• nested state 등 복잡한 여러 개의 상태를 한꺼번에 관리하거나, 어떤 상태에 여러 가지 처리를 적용할 때 유용하다.
• 상태 복잡하다면, useState에 관한 callback을 내려주는 것보다 dispatch를 prop으로 내려 리렌더링을 최적화하는 것을 권장한다.</p>
<pre><code class="language-javascript">const [state, dispatch] = useReducer(reducer, initState)</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 비동기 통신]]></title>
            <link>https://velog.io/@yuj_125/React-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%86%B5%EC%8B%A0</link>
            <guid>https://velog.io/@yuj_125/React-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%86%B5%EC%8B%A0</guid>
            <pubDate>Sun, 29 Oct 2023 19:34:49 GMT</pubDate>
            <description><![CDATA[<h1 id="🧬-자바스크립트-비동기의-등장">🧬 자바스크립트 비동기의 등장</h1>
<blockquote>
<p>초기 웹 환경에서는 서버에서 모든 데이터를 로드하여 페이지를 빌드했으므로 자바스크립트에는 별도의 비동기 처리가 필요하지 않았지만 <strong>Ajax(Asynchronous JavaScript and XML)</strong> 기술의 등장으로 페이지 로드 없이 client-side에서 XMLHttpRequest라는 객체를 통해 서버로 요청을 보내면서 데이터를 처리할 수 있게 되었다.</p>
</blockquote>
<p><br><br></p>
<h1 id="🎯-비동기-통신의-특징">🎯 비동기 통신의 특징</h1>
<ul>
<li>비동기 통신은 페이지의 새로고침 없이 부분적으로 데이터를 가져올 수 있게 한다.</li>
<li>통신 처리가 끝나지 않아도 다른 작업을 할 수 있다.</li>
<li>사용자 경험이 극대화된다는 장점이 있다. </li>
<li>비동기 통신 방법에는 Ajax(Asynchronous JavaScript and XML), fetch, axios가 있다.</li>
</ul>
<p><br><br></p>
<h1 id="비동기-통신-방법">비동기 통신 방법</h1>
<h3 id="1-ajax">1) Ajax</h3>
<ul>
<li>Ajax에서 XMLHttpRequest 객체를 통해 웹 브라우저와 서버가 데이터를 교환한다.</li>
<li>콜백지옥이 생길 수 있고 복잡하다는 단점이 있다.</li>
</ul>
<h3 id="2-fetch">2) fetch</h3>
<ul>
<li>웹 API에서 지원을 하는 내장 라이브러리로 import없이 사용 가능하다.</li>
<li>XMLHttpRequest의 대체자로 나온것이 fetch이다. 비동기 요청을 더 편하게 해준다.</li>
<li>promise 기반으로 동작하여 콜백지옥이 생기지 않는다.</li>
<li>응답으로 오는 데이터는 Response 객체로 Json이나 text로 변경해주는 과정이 필요하다.</li>
<li>API 요청을 취소할 수 없다.</li>
</ul>
<h3 id="3-axios">3) axios</h3>
<ul>
<li>promise API를 활용한 비동기 통신 라이브러리이다.</li>
<li>크로스 브라우징 기반으로 브라우저 호환성이 뛰어나다.</li>
<li>자동으로 Json 데이터 형식으로 변환이 된다.</li>
<li>다양한 메소드를 지원하며 추가적인 옵션도 제공한다.</li>
<li>요청 취소 및 타임아웃 설정이 가능하다.</li>
<li>React에서 주로 사용된다.</li>
<li>라이브러리 설치가 필요하다.</li>
</ul>
<hr>
<h1 id="참고자료">참고자료</h1>
<ul>
<li><a href="https://velog.io/@yonghk423/%EB%B9%84%EB%8F%99%EA%B8%B0-HTTP-%ED%86%B5%EC%8B%A0-%EC%A2%85%EB%A5%98ajax-fetchaxios">비동기 HTTP 통신 종류(ajax, fetch,axios)</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] SPA와 라우팅]]></title>
            <link>https://velog.io/@yuj_125/React-SPA%EC%99%80-%EB%9D%BC%EC%9A%B0%ED%8C%85</link>
            <guid>https://velog.io/@yuj_125/React-SPA%EC%99%80-%EB%9D%BC%EC%9A%B0%ED%8C%85</guid>
            <pubDate>Sun, 29 Oct 2023 16:35:18 GMT</pubDate>
            <description><![CDATA[<h1 id="📝-spa란">📝 SPA란?</h1>
<blockquote>
<p><strong>SPA(Single Page Application)</strong>은 하나의 페이지 요청으로 전체 웹앱을 사용하는 방식이다.</p>
</blockquote>
<br>

<h3 id="❓-그렇다면-mpa는-무엇일까">❓ 그렇다면 MPA는 무엇일까</h3>
<blockquote>
<p><strong>MPA(Multi Page Application)</strong>은 서버에 미리 여러 페이지를 두고, 유저가 네비게이션 시 요청에 적합한 페이지를 전달하는 방식이다. 서버에 라우팅을 처리하는 기능이 있고, 서버에서 여러 페이지를 관리한다. 이러한 방식은 페이지 요청마다 모든 리소스를 다시 받아오므로, <strong>페이지 간 데이터를 재활용하기 힘들다</strong>는 단점이 있다.</p>
</blockquote>
<p><br><br></p>
<h1 id="🎯-spa의-특징">🎯 SPA의 특징</h1>
<p>• 유저는 웹페이지를 사용하며 모바일 앱 같은 경험을 느낄 수 있다. ex) Instargram, Twitter
• Client-side routing 기술을 활용하여 페이지 진입 시 리로드없이 라우팅한다.
• AJAX 기술을 활용, 페이지 이동 시 서버에 데이터만 요청하여 자바스크립트로 페이지를 만든다.
• MPA와 다르게, 여러 페이지를 하나의 앱의 구성요소로 보고 여러 페이지 간의 스타일, 컴포넌트를 재활용하는 방향으로 구현한다.
• 자바스크립트만을 활용해 전체 페이지를 만들기에, 첫 요청 시 빈 페이지를 받게 된다.</p>
<p><br><br></p>
<h1 id="📈-spa의-장점">📈 SPA의 장점</h1>
<p>• 서버에서 페이지를 만들 필요가 없으므로 <code>CDN</code>에 캐싱이 가능하다.</p>
<blockquote>
<p>✔ <strong>콘텐츠 전송 네트워크(CDN)</strong></p>
</blockquote>
<ul>
<li>콘텐츠 전송 네트워크(CDN)는 데이터 사용량이 많은 애플리케이션의 웹 페이지 로드 속도를 높이는 상호 연결된 서버 네트워크이다.</li>
<li>CDN의 주 목적은 대기 시간을 줄이거나 네트워크 설계로 인해 발생하는 통신 지연을 줄이는 것이다.</li>
<li>CDN을 작동하는 방식으로 캐싱, 동적 가속 및 엣지 로직 계산의 원리 등이 있다.</li>
<li>캐싱이란 더 빠른 데이터 액세스를 위해 동일한 데이터의 여러 복사본을 저장하는 프로세스이다.</li>
</ul>
<p>• 매번 페이지 요청을 할 필요가 없어 네트워크 요청이 줄어든다. 또한 데이터 요청 등을 캐싱하여 재사용하는 등 제약 조건이 줄어든다.
• 웹사이트를 개별 페이지보다는 하나의 앱으로 보는 설계로 고도의 소프트웨어 설계와 패턴을 적용할 수 있다.
• 사용자가 페이지를 이동할 때 빈 화면 없이 바로바로 이동하는 것처럼 보이기 때문에 페이지의 잔존율이 높고 사용자 경험이 좋다.
• 모바일에서도 반응형으로 제작 시 하나의 앱처럼 사용이 가능하기 때문에 모바일 친화적이다.</p>
<p><br><br></p>
<h1 id="📉-spa의-단점">📉 SPA의 단점</h1>
<p>• MPA방식 보다는 <strong>Search Engine Optimization</strong>(검색 엔진 최적화)에 불리하다. 자바스크립트가 전부 실행되어야 요소가 가득 차고 검색엔진이 페이지를 검색하게 되면 비어있는 페이지로 인식 하기 때문에 SEO 최적화에 어려움이 생기게 된다.
• 하나의 자바스크립트 앱이 지속하므로, 메모리 관리와 성능, 데이터 활용 등이 중요하다.
• 여러 페이지를 전송받는 것 보다, 하나의 거대한 자바스크립트 앱을 전송받아야 하므로 코드가 많아질수록 로드 속도가 느려진다. 즉, 사용자의 컴퓨터 성능에 따라 로딩 속도에 영향을 준다.</p>
<p><br><br> </p>
<hr>
<p><br><br></p>
<h1 id="🧏♂️-react-router-소개">🧏‍♂️ react-router 소개</h1>
<p>• React의 JSX를 이용하거나, History API를 사용하여 라우팅을 구현 할 수 있다.
• 웹에서는 <code>react-router-dom</code>을 사용한다.
• 적용 시, 서버의 모든 path에서 같은 앱을 서빙하도록 해야 한다.</p>
<blockquote>
<p><strong>react-router-dom이란?</strong>
• React로 생성된 SPA 내부에서 페이지 이동이 가능하도록 만들어주는 라이브러리이다.
• 사용자의 url 경로에 따라서 해당 컴포넌트를 바꿔가면서 렌더링할 수 있게 해준다.</p>
</blockquote>
<p><br><br></p>
<h1 id="react-router의-기능">react-router의 기능</h1>
<p>• React 컴포넌트를 특정 path와 연결하면, 해당하는 path로 진입 시 컴포넌트를 렌더링하게 한다.
• query, path variable 등 URL parameter를 얻어 활용한다.
• 조건에 맞지 않을 경우 redirect 한다.
• 페이지 이동 시, 이벤트 핸들러를 등록한다.
• /posts/my-post-1 등의 nested route를 구현한다.</p>
<p><br><br></p>
<h1 id="react-router-사용법">react-router 사용법</h1>
<blockquote>
<p>** 2021년 말부터 v5에서 v6로 버전 업데이트가 이루어지면서 새로운 기능 추가 및 변경된 점이 있다. </p>
</blockquote>
<h2 id="v5"><code>&lt;V5&gt;</code></h2>
<p>• <code>&lt;BrowserRouter&gt;</code> 로 감싸 Router Context를 제공해야 함.
• Route로 path를 정의하고, 그 안에 렌더링하고자 하는 컴포넌트를 넣음.
• Link로 특정 페이지로 이동 시, 리로드 없이 페이지가 이동함.
• Switch로, 매칭되는 라우트 하나를 렌더링하게 함.</p>
<pre><code class="language-javascript">import { BrowserRouter, Route, Switch } from &#39;react-router-dom&#39;
export function App() {
  return (
    &lt;BrowserRouter&gt;
      &lt;Switch&gt;
        &lt;Route path=&quot;/about&quot;&gt;&lt;AboutPage /&gt;&lt;/Route&gt;
        &lt;Route path=&quot;/contact&quot;&gt;&lt;ContactPage /&gt;&lt;/Route&gt;
        &lt;Route path=&quot;/&quot;&gt;&lt;HomePage /&gt;&lt;/Route&gt;
      &lt;/Switch&gt;
    &lt;/BrowserRouter&gt;
  )
}</code></pre>
<h4 id="1-browserrouter">1) BrowserRouter</h4>
<p>• HTML5의 History API를 사용하여, UI와 URL의 싱크를 맞추는 역할이다.
• 최상위 컴포넌트에 사용되며, 라우팅을 위한 컨텍스트를 제공한다.
• 모든 URL에 대해 동작하게 하기 위해서는 서버 설정 필요하다.
• 모든 path 앞의 basename을 지정할 수 있다. ex) basename=&quot;/ko&quot;
• forceRefresh로, 페이지 이동 시 리프레시할 것인지 지정할 수 있다.</p>
<h4 id="2-switch">2) Switch</h4>
<p>• 여러 Route 중 매치되는 Route 위에서부터 하나 선택하여 렌더링한다.
• 매칭되는 Route가 없으면 아무것도 보여주지 않는다. fallback용으로 404 Not Found Page를 추가한다.
• path=&quot;/&quot;의 경우 모든 path에 매칭되므로 exact 키워드를 추가하거나 가장 아래로 내린다.</p>
<h4 id="3-route">3) Route</h4>
<p>• path와 컴포넌트를 매칭한다.
• 매칭되는 컴포넌트는 <code>children</code>으로 넣어주거나
component prop으로 넘긴다.</p>
<blockquote>
<p>React 컴포넌트에서 <strong>children</strong>이란, <code>&lt;Component&gt;{children}&lt;/Component&gt;</code>과 같이
태그 안에 넣을 수 있는 값을 가리키는 것이다.</p>
</blockquote>
<p>• exact 키워드로 정확하게 매칭하는 path를 설정한다.
• Route로 렌더링 되는 최상위 컴포넌트는 match, location, history를 prop으로 받는다.
• render prop으로, 매칭되었을 때 실제 어떤 컴포넌트를 렌더링할지 통제한다.</p>
<h4 id="4-redirect">4) Redirect</h4>
<p>• Link와 비슷하나, 렌더링되면 to prop으로 지정한 path로 이동한다.
• Switch 안에서 쓰일 경우, from, to를 받아 이동하게 만든다. ex) from=&quot;/&quot; to=&quot;/login&quot;</p>
<h4 id="5-link-navlink">5) Link, NavLink</h4>
<p>• to prop을 특정 URL로 받아, 클릭 시 네비게이션이 된다.
• anchor tag를 래핑한다.
• NavLink의 경우, 매칭 시 어떤 스타일을 가질지 등의
추가 기능이 있다.
• to에 location object나 함수를 받을 수 있다.</p>
<h2 id="v6"><code>&lt;V6&gt;</code></h2>
<h4 id="1-switch-대신-routes-사용">1) Switch 대신 Routes 사용</h4>
<ul>
<li>Router &gt; Routes &gt; Route 구조</li>
<li>컴포넌트 샌드위치 구조, component props 대신 element props 사용<pre><code class="language-javascript">import { BrowserRouter as Router, Routes, Route } from &quot;react-router-dom&quot;;
</code></pre>
</li>
</ul>
<p>function App() {
  return (
    <Router>
      <Routes>
        &lt;Route path=&quot;/&quot; element={<Portfolio />} /&gt;
        &lt;Route path=&quot;/login&quot; element={<LoginForm />} /&gt;
        &lt;Route path=&quot;/register&quot; element={<RegisterForm />} /&gt;
      </Routes>
    </Router>
  );
}</p>
<pre><code>
#### 2) useHistory 대신 useNavigate 사용
```javascript
// v5
const history = useHistory()

history.push(&quot;/login&quot;)
history.replace(&quot;/login&quot;)

// v6
const navigate = useNavigate()     // useNavigate 훅 사용

navigate(&quot;/login&quot;)                 // 로그인 페이지로 이동
navigate(&quot;/login&quot;, {replace: true})</code></pre><h4 id="3-redirect-대신-path사용">3) Redirect 대신 path=&quot;*&quot;사용</h4>
<pre><code class="language-javascript">&lt;Router&gt;
    &lt;Routes&gt;
        &lt;Route path=&quot;/&quot; element={&lt;Portfolio /&gt;} /&gt;
        &lt;Route path=&quot;/login&quot; element={&lt;LoginForm /&gt;} /&gt;
        &lt;Route path=&quot;/register&quot; element={&lt;RegisterForm /&gt;} /&gt;
        &lt;Route path=&quot;*&quot; element={&lt;NotFound /&gt;} /&gt;
    &lt;/Routes&gt;
&lt;/Router&gt;</code></pre>
<br>

<hr>
<br>

<h1 id="참고자료">참고자료</h1>
<ul>
<li><a href="https://aws.amazon.com/ko/what-is/cdn/">CDN이란 무엇입니까?</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] Hooks]]></title>
            <link>https://velog.io/@yuj_125/React-Hooks</link>
            <guid>https://velog.io/@yuj_125/React-Hooks</guid>
            <pubDate>Sat, 28 Oct 2023 17:44:42 GMT</pubDate>
            <description><![CDATA[<h1 id="📝-hook이란">📝 Hook이란?</h1>
<blockquote>
<p>컴포넌트에서 데이터를 관리(State)하고 데이터가 변경될 때 상호작용(Effect)을 하기 위해 사용한다.</p>
</blockquote>
<p><br><br></p>
<h2 id="hook의-배경">Hook의 배경</h2>
<p>기존에는 컴포넌트 내에서 State와 생명주기를 관리하기 위해서 반드시 <strong>클래스 컴포넌트(Class Component)</strong>를 사용하여야 했다.
그러나 개발자가 느끼기에 다소 복잡한 클래스 컴포넌트(Class Component)를 보완하고 <strong>함수 컴포넌트에서 클래스 컴포넌트의 기능을 구현하기 위해</strong> React 16.8 버전에 추가된 것이 바로 Hook이다.</p>
<p><br><br></p>
<h1 id="🎯-hook의-특징">🎯 Hook의 특징</h1>
<ul>
<li>Hook은 React 함수(컴포넌트, Hook) 내에서만
사용이 가능하다.</li>
<li>Hook의 이름은 반드시 ‘use’로 시작해야 한다.</li>
<li>최상위 Level에서만 Hook을 호출할 수 있다.
(if문, for문 안 쪽 또는 콜백함수 내에서 호출하면 안된다.)</li>
</ul>
<p><br><br></p>
<h1 id="📈-hook의-장점">📈 Hook의 장점</h1>
<ul>
<li><strong>컴포넌트의 함수가 많아질 때 클래스 구성 요소로 리팩토링할 필요가 없다.</strong><ul>
<li>React hooks를 사용하면 함수 구성 요소로만 상태 관리를 할 수 있기 때문에 리팩토링 노력이 최소화.</li>
</ul>
</li>
<li><strong>UI에서 로직을 더 쉽게 분리하여 두 가지 모두 재사용 가능하다.</strong><ul>
<li>코드를 재사용하기 위한 로직을 쉽게 만들 수 있다. </li>
<li>Hook은 더 적은 상용구와 더 직관적인 UI 및 논리 구성으로 더 세련되게 구현할 수 있다. </li>
<li>코드의 재사용은 작성해야 할 코드의 양을 줄어들게 함으로써 코드의 가독성 또한 좋아진다.</li>
</ul>
</li>
<li><strong>기존의 코드를 다시 작성할 필요 없이 일부의 컴포넌트들 안에서 Hook을 사용할 수 있다.</strong><ul>
<li>기존의 코드와 잘 호환이 되기 때문에 필요한 곳에서 Hook을 사용할 수 있다.</li>
</ul>
</li>
<li><strong>Hook을 사용하면 컴포넌트로부터 상태 관련 로직을 추상화가 가능하다.</strong><ul>
<li>Hook을 이용하면 컴포넌트별로 독립적인 테스트와 재사용이 가능해진다. </li>
<li>Hook은 컴포넌트 간 계층 변화 없이 상태 관련 로직을 재사용할 수 있도록 도와준다.</li>
</ul>
</li>
</ul>
<p><br><br></p>
<h1 id="state-hook">State Hook</h1>
<pre><code class="language-javascript">const App = () =&gt; {
  // 일반적인 useState 사용법
  const [state이름, setState이름] = useState(초기값)
}</code></pre>
<ul>
<li>상태를 저장하거나 재지정하는 역할을 한다.</li>
<li>useState는 컴포넌트 내 동적인 데이터를 관리할 수 있는 hook이다. </li>
<li>최초에 useState가 호출될 때 초기값으로 설정되며 이후 재 렌더링이 될 경우 무시된다.</li>
<li>state는 읽기 전용이므로 직접 수정하면 안된다.</li>
<li>state를 변경하기 위해서는 setState를 이용해야 한다.</li>
<li>state가 변경되면 자동으로 컴포넌트가 재 렌더링된다.</li>
</ul>
<h1 id="effect-hook">Effect Hook</h1>
<pre><code class="language-javascript">const App = () =&gt; {
    useEffect(EffectCallback, Deps?)
}</code></pre>
<ul>
<li>Effect Hook을 사용하면 함수 컴포넌트에서 <code>side effect</code>를 수행할 수 있다.<blockquote>
<p> side effect란 함수(React의 함수형 컴포넌트) 외부에서 로컬의 상태 값을 변경하는 것</p>
</blockquote>
</li>
<li>함수형 컴포넌트에서 실행 가능하다.</li>
<li>컴포넌트가 최초로 렌더링될 때, 지정한 State나 Prop가 변경될 때마다 EffectCallback 함수가 호출된다.</li>
<li>값이 없거나 빈 배열인 경우 해당 컴포넌트가 마운트되면, 즉 가상 DOM에 그려질 때 딱 한 번 실행이 된다.</li>
<li>Deps: 변경을 감지할 변수들의 집합(배열)</li>
<li>EffectCallback: Deps에 지정된 변수가 변경될 때 실행할 함수</li>
</ul>
<h1 id="내장-hook">내장 Hook</h1>
<h3 id="1-usememo">1) useMemo</h3>
<pre><code class="language-javascript">const App = () =&gt; {
  const [firstName, setFirstName] = useState(&#39;철수&#39;)
  const [lastName, setLastName] = useState(&#39;김&#39;)

  // 이름과 성이 바뀔 때마다 풀네임을 메모이제이션
  const fullName = useMemo(() =&gt; {
      return ′${firstName} ${lastName}′
    }, [firstName, lastName])
}</code></pre>
<ul>
<li>지정한 State나 Props가 변경될 경우 해당값을 활용해 계산된 값을 메모이제이션하여 재렌더링 시 불필요한 연산을 줄인다.</li>
<li>useMemo의 연산은 렌더링 단계에서 이루어지기 때문에 시간이 오래 걸리는 로직은 작성하지 않는 것을 권장한다.</li>
</ul>
<h3 id="2-usecallback">2) useCallback</h3>
<pre><code class="language-javascript">const App = () =&gt; {
  const [firstName, setFirstName] = useState(&#39;철수&#39;)
  const [lastName, setLastName] = useState(&#39;김&#39;)

// 이름과 성이 바뀔 때마다
// 풀네임을 return하는 함수를 메모이제이션
  const getfullName = useCallback(() =&gt; {
    return ′${firstName} ${lastName}′
  }, [firstName, lastName])

  return &lt;&gt;{fullname}&lt;/&gt;
}</code></pre>
<ul>
<li>함수를 메모이제이션하기 위해 사용하는 Hook이다. 컴포넌트가 재렌더링될 때 불필요하게 함수가 다시 생성되는 것을 방지한다.</li>
<li><strong>useMemo(() =&gt; fn, deps)</strong> 와 *<em>useCallback(fn, deps) *</em>는 같다.</li>
</ul>
<h3 id="3-useref">3) useRef</h3>
<pre><code class="language-javascript">const App = () =&gt; {
  const inputRef = useRef(null)
  const onButtonClick = () =&gt; {
      inputRef.current.focus()
  }

  return (
    &lt;div&gt;
      &lt;input ref={inputRef} type=&quot;text&quot; /&gt;
      &lt;button onClick={onButtonClick}&gt;
          input으로 포커스
      &lt;/button&gt;
    &lt;/div&gt;
  )
}</code></pre>
<ul>
<li>컴포넌트 생애 주기 내에서 유지할 ref 객체를 반환한다.</li>
<li>직접 HTML의 요소에 접근이 가능하도록 도와주는 훅이다.</li>
<li>ref 객체는 .current라는 프로퍼티를 가지며 이 값을 자유롭게 변경할 수 있다.</li>
<li>일반적으로 React에서 DOM Element에 접근할 때 사용한다(DOM Element의 ref 속성을 이용한다.)</li>
<li>useRef에 의해 반환된 ref 객체가 변경되어도 컴포넌트가 재렌더링되지 않는다.</li>
<li>언제든지 수정이 가능한 객체를 보관할 수 있게 도와주는 훅으로 사용할 수 있다. 즉, 어떠한 값을 기억하고 있다가 나중에 사용하거나 값을 변경할 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] Event]]></title>
            <link>https://velog.io/@yuj_125/React-Event</link>
            <guid>https://velog.io/@yuj_125/React-Event</guid>
            <pubDate>Sat, 28 Oct 2023 16:48:52 GMT</pubDate>
            <description><![CDATA[<h1 id="📝-event란">📝 Event란?</h1>
<blockquote>
<p>이벤트(event)란 웹 브라우저가 알려주는 HTML 요소에 대한 사건의 발생을 의미한다.
유저의 행동에 의해 발생할 수도 있으며 개발자가 의도한 로직에 의해 발생할 수도 있다.</p>
</blockquote>
<p><br><br></p>
<h1 id="🎯-event-특징">🎯 Event 특징</h1>
<ul>
<li>이벤트의 이름은 카멜(Camel) 표기법으로 사용한다.</li>
<li>이벤트에 실행할 코드를 그대로 전달하는 것이 아니라 함수 형태의 객체를 전달해야 한다.</li>
<li>DOM요소에만 이벤트 설정 가능이 가능하다.</li>
<li>직접 만든 리액트 컴포넌트에는 이벤트를 자체적으로 설정할 수 없다.</li>
</ul>
<p><br><br></p>
<h1 id="이벤트-처리-방법">이벤트 처리 방법</h1>
<h3 id="1-핸들링-함수-선언">1) 핸들링 함수 선언</h3>
<pre><code>const App = () =&gt; {
  const handleClick = () =&gt; {
      alert(&quot;클릭했습니다.&quot;);
  }
  return (
    &lt;div&gt;
      &lt;button onClick={handleClick}&gt;클릭하세요&lt;/button&gt;
    &lt;/div&gt;
  );
};</code></pre><ul>
<li>별도의 핸들링 함수를 선언하고 Element에 넘겨준다.</li>
<li>DOM Element의 경우 핸들링 함수에 이벤트
object를 매개변수로 전달한다.</li>
<li>이벤트 object를 이용하여 이벤트 발생 원인, 이벤트가
일어난 Element에 대한 정보를 얻을 수 있다.</li>
<li>DOM 이벤트를 활용하는 것뿐만 아니라 커스텀 이벤트를 만들 수도 있다. (“on” + 동사 또는 “on” + 명사 + 동사 형태로 작성한다.)</li>
<li>이벤트 형태(클릭, 키 입력 등)와 DOM 종류(button, 
form, input 등)에 따라 전달되는 이벤트 object의
내용이 다르다.<blockquote>
<p>✔ 주요 DOM 이벤트</p>
</blockquote>
</li>
<li><em>onClick*</em>: Element를 클릭했을 때</li>
<li><em>onChange*</em>: Element의 내용이 변경되었을 때 (input의 텍스트를 변경, 파일 선택 등)</li>
<li><em>onKeyDown, onKeyUp, onKeyPress*</em>: 키보드 입력이 일어났을 때</li>
<li><em>onDoubleClick*</em>: Element를 더블 클릭했을 때</li>
<li><em>onFocus*</em>: Element에 Focus되었을 때</li>
<li><em>onBlur*</em>: Element가 Focus를 잃었을 때</li>
<li><em>onSubmit*</em>: Form Element에서 Submit 했을 때</li>
</ul>
<h3 id="2-익명-함수로-처리">2) 익명 함수로 처리</h3>
<pre><code>const App = () =&gt; {
  return (
    &lt;div&gt;
      &lt;button onClick={() =&gt; { alert(&#39;클릭했습니다.&#39;) }
      }&gt;클릭하세요&lt;/button&gt;
    &lt;/div&gt;
  )
}</code></pre><ul>
<li>이벤트를 할당하는 부분에서 익명 함수를 작성한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] Props와 state]]></title>
            <link>https://velog.io/@yuj_125/React-Props%EC%99%80-state</link>
            <guid>https://velog.io/@yuj_125/React-Props%EC%99%80-state</guid>
            <pubDate>Sat, 28 Oct 2023 16:21:29 GMT</pubDate>
            <description><![CDATA[<h1 id="📝-props란">📝 Props란?</h1>
<blockquote>
<p>Component에 데이터를 전달하는 방식으로 넘겨줄 수 있는 값은 변수, 함수, 객체, 배열 등 JavaScript의 요소라면 제한이 없다. (컴포넌트로 전달되는 매개변수)
주로 Component의 ‘재사용’을 위하여 사용한다</p>
</blockquote>
<p><br><br></p>
<h1 id="🎯-props의-특징">🎯 Props의 특징?</h1>
<ul>
<li>컴포넌트에 전달되어 사용된다. (함수의 매개변수처럼 사용)</li>
<li>Props는 읽기 전용이다. Props의 값을 변경해서 사용하고 싶다면 새로운 변수를 생성해야한다.</li>
<li>React Attribute는 현재 값을 의미한다. 초기값의 의미로 사용하려면 defaultValue, defaultChecked로 설정해야한다.</li>
<li>key는 React에서 사용하는 새로운 Attribute이다.<blockquote>
<p><strong>Key</strong></p>
</blockquote>
1) React가 어떤 항목을 변경, 추가 또는 삭제할지
식별하는 것을 돕는다. 
2) 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 Element에 지정해야 한다. 
3) Key는 배열 안에서 형제 사이에서 고유해야 하고 전체범위에서 고유할 필요는 없다.
4) key 속성이 없으면 출력은 정상적으로 되지만 콘솔에 경고가 발생한다.  React가 배열을 순회하며 생성된 각 컴포넌트를 구별할 수 없기 때문이다.</li>
<li>반드시 부모 컴포넌트에서 상속 받아야 한다. 자식에서 부모로 전달할 수 없다.</li>
</ul>
<p><br><br></p>
<hr>
<p><br><br></p>
<h1 id="📝-state">📝 state?</h1>
<blockquote>
<p>State는 Component 내에서 유동적으로 변할 수 있는 값을 저장한다.</p>
</blockquote>
<p><br><br></p>
<h1 id="🎯-state-특징">🎯 state 특징</h1>
<ul>
<li>State는 컴포넌트 안에서 관리된다. (함수 내에 선언된 변수처럼 사용)</li>
<li>개발자가 의도한 동작에 의해 변할 수도 있고
사용자의 입력에 따라 새로운 값으로 변경될
수도 있다.</li>
<li>State 값이 변경되고 재렌더링이 필요한 경우
에 React가 자동으로 계산하여 변경된 부분을 렌더링한다.</li>
<li>State 값을 직접 변경하게 되면 React가
Component를 다시 렌더링할 타이밍을
알아차리지 못한다. 반드시 setState 함수를 이용해 값을 변경해야한다.</li>
</ul>
<p><br><br></p>
<h1 id="state-변경-방법">state 변경 방법</h1>
<h3 id="1-setstate내에-변경할-값-넣기">1) setState내에 변경할 값 넣기</h3>
<pre><code class="language-javascript">const [count, setCount] = useState(0);
setCount(count + 1)</code></pre>
<h3 id="2-setstate에-함수-넣기">2) setState에 함수 넣기</h3>
<pre><code class="language-javascript">const [count, setCount] = useState(0);
setCount((current) =&gt; {
    return current + 1
})</code></pre>
<ul>
<li>함수를 넣는 경우 함수가 반환(return)하는 값으로 State가 변경된다.</li>
<li>현재 값을 기반으로 State를 변경하고자 하는 경우 함수를 넣는 방법을 권장한다.</li>
</ul>
<blockquote>
<p> ❗❗ <strong>Object를 갖는 State를 변경할 때 주의할 점</strong></p>
</blockquote>
<pre><code class="language-javascript">const [user, setUser] = useState({name: &quot;민수&quot;, grade: 1})
setUser((current) =&gt; {
    current.grade = 2; // ----&gt; X
    return current;
})</code></pre>
<p>user object 안의 grade를 바로 변경하게 되면 grade는 변경되었지만 user 자체는 변경되지 않았기 때문에 변경된 것을 감지하지 못한다.</p>
<pre><code class="language-javascript">const [user, setUser] = useState({name: &#39;민수&#39;, grade: 1 })
setUser((current) =&gt; {
    const newUser = { ...current }
    newUser.grade = 2 // ----&gt; O
    return newUser
})</code></pre>
<p>기존 user의 내용을 새로운 object에 담고 grade를
변경해야한다.</p>
<p><br><br></p>
<h1 id="props-vs-state">Props vs State</h1>
<p>Props와 State의 가장 큰 차이로 Props는 부모 컴포넌트에서 자식 컴포넌트로 전달하는 값으로 <strong>자식 컴포넌트에서는 Props를 직접 수정할 수 없지만 State는 컴포넌트 내부에서 선언하며 내부에서 관리되는 값으로 값을 변경할 수 있다</strong>는 점이 있다.</p>
<p>따라서 값이 변경되어야하는 상황, 예를 들면 매초 변하는 시간을 출력해야 하거나 버튼 클릭시 값이 변하는 것을 출력해야 한다면 State를 사용해야 한다. Props는 읽기 전용으로 수정이 불가능하고, State는 원하는 경우 수정이 가능하기 때문에 상황에 따라 알맞은 것을 사용하면 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] React의 JSX와 Component]]></title>
            <link>https://velog.io/@yuj_125/React-React%EC%9D%98-JSX%EC%99%80-Component</link>
            <guid>https://velog.io/@yuj_125/React-React%EC%9D%98-JSX%EC%99%80-Component</guid>
            <pubDate>Sat, 28 Oct 2023 15:04:32 GMT</pubDate>
            <description><![CDATA[<h1 id="📝-jsx란">📝 JSX란?</h1>
<blockquote>
<p>JSX는 JavaScript <code>XML</code>의 약자로 함수 호출과 객체 생성을 위한 문법적 편의를 제공하여 UI 개발의 편의성을 느끼게 해주는 JavaScript 문법의 확장본이다. 
✔  XML은 HTML의 한계를 극복하기 위해 만들어진 마크업 언어</p>
</blockquote>
<p><br><br></p>
<h1 id="🎯-jsx의-특징">🎯 JSX의 특징</h1>
<ul>
<li><p>HTML 태그 내에 JavaScript 연산</p>
</li>
<li><p>class → className</p>
</li>
<li><p>스타일은 object이며 camelCase로 작성</p>
</li>
<li><p>닫는 태그 필수 ex) <code>&lt;br /&gt;</code></p>
</li>
<li><p>최상단 element는 반드시 하나만 작성 가능, <code>&lt;div&gt;</code> 또는 <code>&lt;React.Fragment&gt;</code>를 사용하고 실제 렌더링 시에는 는 Fragment 안에 있는 내용만 출력. &lt;React.Fragment&gt;는 간단히 &lt;&gt; 로 표기 가능.</p>
</li>
<li><p>JSX 코드는 브라우저가 이해하지 못하기 때문에  Babel에 의해서 Transcompile됨</p>
</li>
</ul>
<pre><code class="language-javascript">const App = () =&gt; {
    return (
        &lt;div className=&quot;App&quot;&gt;
            &lt;header&gt;
                &lt;img src={logo} className=&quot;App-logo&quot; alt=&quot;logo&quot; /&gt;
                &lt;h1&gt;Welcome to React&lt;/h1&gt;
            &lt;/header&gt;
            &lt;p style={{ color: &#39;blue&#39;, bakcgroundColor: &#39;black&#39; }}&gt;
                Hello World
            &lt;/p&gt;
        &lt;/div&gt;
    )
}</code></pre>
<p><br><br></p>
<h1 id="📈-jsx의-장점">📈 JSX의 장점</h1>
<ol>
<li>개발자 편의성 향상</li>
<li>협업에 용이하고 생산성 향상</li>
<li>문법 오류와 코드량 감소</li>
</ol>
<p><br><br></p>
<hr>
<p><br><br></p>
<h1 id="📝-component란">📝 Component란?</h1>
<blockquote>
<p>React에서 페이지를 구성하는 최소단위로 사용자가 만들 수 있는 태그이자 재사용 할 수 있는 UI 함수이다.</p>
</blockquote>
<p><br><br></p>
<h1 id="🎯-component의-특징">🎯 Component의 특징</h1>
<ul>
<li><p>Component의 이름은 대문자로 시작</p>
</li>
<li><p>Class Component(클래스형 컴포넌트) / Function Component(함수형 컴포넌트) 로 나뉨</p>
<blockquote>
<p><strong>Class Component</strong> 특징</p>
</blockquote>
<ol>
<li>Class 개념이 많이 활용되는 Java 개발자에게 친숙한 형태이다.</li>
<li>React의 생명주기를 파악하기 쉽다.</li>
</ol>
</li>
<li><p>Controlled Component / Uncontrolled Component</p>
</li>
<li><p>컴포넌트에 Attribute에 해당하는 부분을 Props(Properties)라고 한다. 컴포넌트 안에 작성된 하위 Element는 children라고 하는데 children도 결국엔 props 중 하나이다.</p>
</li>
<li><p>엘리먼트란 React 앱의 가장 작은 단위로 컴포넌트의 구성요소이다. 엘리먼트는 화면에 표시할 것들을 기록하는 것으로 쉽게 말하자면 HTML 요소라고 할 수 있다.</p>
</li>
<li><p>컴포넌트 안에서 다른 컴포넌트를 참조하는 것이 가능하다.</p>
</li>
</ul>
<p><br><br></p>
<h2 id="class-component클래스형-컴포넌트와-function-component함수형-컴포넌트">Class Component(클래스형 컴포넌트)와 Function Component(함수형 컴포넌트)</h2>
<h3 id="함수형-컴포넌트">함수형 컴포넌트</h3>
<pre><code class="language-javascript">function Introduce() {
  return &lt;h2&gt;Hi, I am elice!&lt;/h2&gt;;
}

ReactDOM.render(&lt;Introduce /&gt;, document.getElementById(&#39;root&#39;));</code></pre>
<ul>
<li>함수형 컴포넌트는 단순히 HTML UI를 반환하는 간단한 자바스크림트 함수로 자주 사용된다. 단순히 데이터를 받고 렌더링을 하면 끝이기 때문에 비상태형 컴포넌트라고도 한다.</li>
<li>State를 사용하지 않고 함수에 대한 결과를 반환하는데, State는 컴포넌트의 렌더링 결과물에 영향을 주는 데이터를 갖고 있는 객체이다. 즉, 컴포넌트에 현재 저장된 값이 State이다.</li>
</ul>
<h3 id="클래스형-컴포넌트">클래스형 컴포넌트</h3>
<pre><code class="language-javascript">class Introduce extends React.Component {
  render() {
    return &lt;h2&gt;Hi, I am elice!&lt;/h2&gt;;
  }
}

ReactDOM.render(&lt;Introduce /&gt;, document.getElementById(&#39;root&#39;));</code></pre>
<ul>
<li>클래스형 컴포넌트는 상태를 구현할 때 사용되어 상태형 컴포넌트라고 한다. HTML을 반환하는 render() 메소드가 구현되어, 복잡한 UI 로직을 구현할 때 클래스형 컴포넌트가 사용된다. 특히 위에서 언급한 State를 사용할 때 반드시 클래스형 컴포넌트로 구현이 되어야 한다.</li>
</ul>
<p>❗❗ <strong>React 16.8 버전부터 Function Component에서 Hook을 통해 State를 사용할 수 있다.</strong></p>
<p><br><br></p>
<h1 id="📈-component-구조의-장점">📈 Component 구조의 장점</h1>
<ul>
<li>각각의 모듈로 분리되어 있기 때문에 개발자는 필요한 컴포넌트만 가져와서 사용할 수 있다.</li>
<li>유지보수하기 쉽다.</li>
<li>가독성이 좋아진다.</li>
<li>재사용이 가능하여 메모리와 연산 비용을 아낄 수 있다.</li>
</ul>
<p><br><br></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] React란 무엇인가]]></title>
            <link>https://velog.io/@yuj_125/React-React%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@yuj_125/React-React%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Sat, 28 Oct 2023 12:11:40 GMT</pubDate>
            <description><![CDATA[<h1 id="📝-react란">📝 React란?</h1>
<blockquote>
<p>React(리액트)란 사용자 인터페이스를 구축하기 위한 <strong>자바스크립트 라이브러리</strong>입니다. </p>
</blockquote>
<br>
<br>

<h1 id="🎯-react의-특징">🎯 React의 특징</h1>
<ul>
<li>React는 선언적이고 효율적이며, 유연합니다. </li>
<li>React의 컴포넌트(component)라고 하는 요소를 이용하면 복잡한 UI를 독립적인 단위로 쪼개어 구현할 수 있습니다.</li>
</ul>
<p><br><br></p>
<h1 id="🤷♀️-react를-왜-사용해야-할까">🤷‍♀️ React를 왜 사용해야 할까?</h1>
<p>React이외에도 HTML과 CSS, Javascript, Jquery 등 다양한 방법으로 얼마든지 제작이 가능하지만, 요즘 같은 복잡한 동적인 웹페이지를 만드는 시대에는 다릅니다.</p>
<p>웹 페이지는 각 페이지마다 페이지를 관리해줘야 하고, 사용자의 응답에 따라 인터페이스가 지속적으로 변해야 하기 때문에 기존 방식으로 관리하기는 어렵습니다. 그러나 React는 동적 UI를 구축하기 위해 만들어진 라이브러리로 이런 어려움을 해결해줍니다. 이미 페이스북에서 적용해 증명이 되었고 요즘은 React를 Airbnb와 Netflix에서도 사용하면서 점점 생태계가 커지고 있습니다.</p>
<p><strong>즉, React를 사용하는 이유들을 정리하면 “사용자와의 소통을 UI로 쉽게 구현하고 대규모의 웹페이지를 관리하기 위해 사용한다”라고 말할 수 있습니다.</strong></p>
<p><br><br></p>
<h1 id="📈-react의-장점">📈 React의 장점</h1>
<ul>
<li><p>React의 <strong><code>Virtual DOM</code></strong>은 사용자 경험을 향상하고 개발자의 작업 속도를 높입니다. </p>
<blockquote>
<p>Virtual DOM이란 가상적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 실제 DOM과 동기화하는 프로그래밍 개념입니다.</p>
</blockquote>
</li>
<li><p>React 컴포넌트의 재사용은 개발 시간을 크게 절약할 수 있습니다.</p>
</li>
<li><p>단방향 데이터 흐름을 통해 안정적인 코드를 제공합니다. 단방향 데이터 흐름은 데이터는 항상 일정한 장소에 있고, 그 장소에서만 변경이 가능한 것을 의미합니다.</p>
</li>
<li><p>오픈 소스이며 페이스북 라이브러리이기 때문에 지속해서 개발되고 커뮤니티에 공개됩니다.</p>
</li>
<li><p>Hooks를 이용해 컴포넌트의 상태를 쉽게 관리할 수 있습니다.</p>
</li>
<li><p>여러 개발 도구를 지원합니다. 예를 들어 크롬에서는 React Developer Tools라는 확장 프로그램을 제공합니다.</p>
</li>
</ul>
<p><br><br></p>
<h1 id="react와-자바스크립트의-차이점">React와 자바스크립트의 차이점</h1>
<p>React는 앱 작성 방식을 정의하는 라이브러리입니다. 이는 데이터가 앱에 사용되는 방식과 그 데이터가 변화하는 결과에 따른 UI 변경 방법에 대해 명확한 규칙을 설정하여 수행합니다. 반면 자바스크립트는 규칙을 설정하지 않는 스크립트 언어라고 할 수 있습니다. 따라서 이러한 라이브러리 없이 작성된 앱은 더 자유로울수는 있지만, 정해진 것이 없기 때문에 코드가 복잡해질 수 있습니다.</p>
<h3 id="1-사용자-인터페이스">1) 사용자 인터페이스</h3>
<p><strong>자바스크립트</strong></p>
<pre><code class="language-javascript">&lt;div&gt;
    &lt;h1&gt;회원 목록&lt;/h1&gt;
    &lt;ul&gt;
        &lt;li&gt;Lee&lt;/li&gt;
        &lt;li&gt;Kim&lt;/li&gt;
        &lt;li&gt;Park&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;</code></pre>
<p>자바스크립트에서 사용자 인터페이스는 보통 HTML을 통해 구현합니다. 이 때 자바스크립트는 따로 추가적인 코드가 필요하지 않습니다.</p>
<p><strong>React</strong></p>
<pre><code class="language-javascript">function MemberList(props) {
    return (
        &lt;div&gt;
            &lt;h1&gt;회원 목록&lt;/h1&gt;
            &lt;ul&gt;
                &lt;li&gt;Lee&lt;/li&gt;
                &lt;li&gt;Kim&lt;/li&gt;
                &lt;li&gt;Park&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;
    )
};</code></pre>
<p>React는 <strong>JSX</strong>로 반환되는 컴포넌트를 통해 UI를 정의합니다. JSX는 HTML처럼 보이지만 실제로는 자바스크립트입니다. 위에 생성된 MemberList 컴포넌트는 이후 ReactDOM 라이브러리에 의해 렌더링되어 화면에 출력될 수 있습니다.</p>
<h3 id="2-기능-분할">2) 기능 분할</h3>
<p><strong>자바스크립트</strong></p>
<pre><code class="language-javascript">&lt;div&gt;
    &lt;h1&gt;회원 목록&lt;/h1&gt;
    &lt;ul id=&quot;member-list&quot;&gt;
        &lt;li&gt;Lee&lt;/li&gt;
        &lt;li&gt;Kim&lt;/li&gt;
        &lt;li&gt;Park&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;

function addMember() {        //자바스크립트 파일에 목록을 업데이트하는 코드 작성
  ...
}</code></pre>
<p>자바스크립트 앱에서는 앱의 기능 또는 UI의 요소를 분할하는 방법에 대한 특별한 요구사항이 없습니다. 기본적인 출력은 HTML 파일에 정의합니다.</p>
<p>코드가 이렇게 작성되어야 하는 이유는 관심사 분리 원칙에 따라 화면에 출력을 하는 HTML과 기능을 구현하는 자바스크립트가 분리되도록 설계하였기 때문입니다. 하지만 이러한 방식은 앱이 복잡해짐에 따라 문제가 생길 수 있습니다. 왜냐하면 하나의 HTML을 구성하는 코드가 서로 다른 자바스크립트 파일에 있을 수 있기 때문에 HTML의 기능이 구현된 코드가 위치한 곳을 기억하기 어렵기 때문입니다.</p>
<p><strong>React</strong></p>
<pre><code class="language-javascript">function MemberList(props) {
    function addItem() {
        ...
    }

    return (
        &lt;div&gt;
            &lt;h1&gt;회원 목록&lt;/h1&gt;
            &lt;ul&gt;
                &lt;li&gt;Lee&lt;/li&gt;
                &lt;li&gt;Kim&lt;/li&gt;
                &lt;li&gt;Park&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;
    )
};</code></pre>
<p>React를 이용하면 기능을 구현하는데 필요한 코드를 하나의 파일로 유지할 수 있습니다.
이렇게 하면 앱이 복잡해 지더라도 쉽게 이해할 수 있고 만들어 놓은 컴포넌트를 앱 전체가 공유할 수 있으므로 코드의 재사용이 가능해집니다.</p>
<h3 id="3-브라우저에-데이터-저장">3) 브라우저에 데이터 저장</h3>
<p><strong>자바스크립트</strong></p>
<pre><code class="language-javascript">// HTML
&lt;input type=&quot;text&quot; id=&quot;input-member&quot; /&gt;

//JS
const input = document.getElementById(&quot;input-member&quot;);
console.log(input.value);</code></pre>
<p>자바스크립트에서 사용자 데이터는 일반적으로 DOM(문서 객체 모델)에 저장됩니다. DOM은 브라우저 자체에서 만들고 유지 관리하며 전체 HTML을 나타냅니다. 예를 들어 자바스크립트에서는 텍스트 박스를 정의하고 사용자가 입력하면 해당 내용이 브라우저에 저장됩니다.</p>
<p>그리고 사용자가 값을 입력할 때 개발자가 먼저 DOM에서 값을 찾은 다음 추출하여 해당 입력 상자에 값을 수동으로 입력합니다.</p>
<p>이는 보기에 편리해보이지만 만약 id가 바뀌게 되면 해당 id를 사용하는 모든 코드를 다시 수정해야 하기 때문에 관리하기가 번거롭습니다.</p>
<p><strong>React</strong></p>
<pre><code class="language-javascript">const [member, setMember] = useState(&quot;&quot;);

&lt;input type=&quot;text&quot; value={member} onChange={e =&gt; setMember(e.target.value)}

console.log(member);</code></pre>
<p>React는 사용자의 입력을 기반으로 자신의 상태를 관리하고 업데이트 하는 제어 컴포넌트를 이용해 사용자 입력 시 자바스크립트 객체의 텍스트 값을 설정합니다. 이를 위해 먼저 상태를 정의해야 합니다.</p>
<p>입력이 변경될 때마다 설정이 되어야 하므로 HTML 코드는 조금 복잡해질 수 있습니다.</p>
<p>하지만 위와 같이 설정 후에는 코드를 이용해 텍스트 박스의 현재 값을 훨씬 쉽게 알 수 있습니다.</p>
<p>id를 별도로 관리할 필요가 없어 코드를 관리하기가 편리합니다. 현재 앱의 상태를 저장하기 위해 DOM에 의존하지 않음으로써 React가 사용자 데이터를 관리할 수 있습니다. 자바스크립트 변수에 앱의 상태를 저장하는 것은 React가 자바스크립트에 비해 얻을 수 있는 가장 큰 이점 중 하나이며 앱이 복잡할수록 해당 이점이 커집니다.</p>
<h3 id="4-ui-업데이트">4) UI 업데이트</h3>
<p><strong>자바스크립트</strong></p>
<pre><code class="language-javascript">&lt;input type=&quot;text&quot; id=&quot;member&quot; /&gt; &lt;button id=&quot;add-button&quot;&gt;회원 추가&lt;/button&gt;

const addButton = document.getElementById(&quot;add-button&quot;);

addButton.addEventListener(&quot;click&quot;, function() {

  ...

})</code></pre>
<p>자바스크립트에서 텍스트 박스 옆에 버튼을 추가할 수 있습니다. 해당 버튼을 누른 것에 응답하기 위해 DOM에서 버튼을 찾습니다. 그리고 버튼에 click 리스너를 설정합니다.</p>
<p>리스너 내부에서 먼저 이전과 동일한 방법을 사용하여 입력 상자의 값을 가져올 수 있습니다. 그런 다음 목록에 새 항목을 추가하려면 DOM에서 목록을 찾고 추가 할 새 항목을 만든 다음 마지막으로 목록 끝에 추가해야합니다. 이것은 상당히 복잡합니다.</p>
<p><strong>React</strong></p>
<pre><code class="language-javascript">const [members, setMembers] = useState([&quot;Lee&quot;, &quot;Kim&quot;, &quot;Park&quot;]);

&lt;ul&gt;
    {members.map(member =&gt; (
        &lt;li key={member}&gt;{member}&lt;/li&gt;
    ))}
&lt;/ul&gt;

&lt;button onClick={addMember}&gt;회원 추가&lt;/button&gt;

function addMember() { setMembers([...members, &quot;새로운 회원&quot;]); }</code></pre>
<p>React 앱은 자바스크립트 변수의 전체 상태를 유지합니다.
그리고 변수의 각 항목을 매핑한 후 그에 대한 목록 요소를 반환하여 JSX에 표시합니다.
버튼을 누르는 기능을 정의하면 클릭 리스너는 필요하지 않고 onClick 버튼 자체에 속성을 추가 할 수 있습니다.</p>
<p>이 함수에 추가할 것은 setMember 함수를 사용하여 기존 항목에 새 항목을 추가하는 것입니다.</p>
<p>이처럼 React는 목록이 변경되었음을 자동으로 등록하고 UI를 자동으로 업데이트합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Node.js] Template Engine]]></title>
            <link>https://velog.io/@yuj_125/Node.js-Template-Engine</link>
            <guid>https://velog.io/@yuj_125/Node.js-Template-Engine</guid>
            <pubDate>Wed, 27 Sep 2023 13:14:28 GMT</pubDate>
            <description><![CDATA[<h2 id="template-engine">Template Engine</h2>
<ul>
<li>서버에서 클라이언트로 보낼 HTML 의 형태를 미리 템플릿 으로 저장</li>
<li>동작 시에 미리 작성된 템플릿에 데이터를 넣어서 완성된 HTML 생성</li>
<li>템플릿 엔진은 템플릿 작성 문법과 작성된 템플릿을 HTML로 변환하는 기능을 제공</li>
</ul>
<br>

<h2 id="expressjs의-템플릿-엔진">Express.js의 템플릿 엔진</h2>
<p><strong>EJS</strong> - html과 유사한 문법의 템플릿 엔진
<strong>Mustache</strong> - 간단한 데이터 치환 정도만 제공하는 경량화된 템플릿 엔진
<strong>Pug</strong> - 들여쓰기 표현식을 이용한 간략한 표기와 레이아웃 등 강력한 기능을 제공</p>
<br>

<h2 id="pug">pug</h2>
<ul>
<li>들여쓰기 표현식을 이용해 가독성이 좋고 개발 생산성이 높음</li>
<li>HTML을 잘 모르더라도 문법적 실수를 줄일 수 있음</li>
<li>layout, include, mixin 등 강력한 기능 제공</li>
</ul>
<br>

<h2 id="pug-문법">pug 문법</h2>
<pre><code class="language-javascript">// index
html
    head
        title= title
    body
        h1#greeting 안녕하세요
        a.link(href=&quot;/&quot;) 홈으로</code></pre>
<ul>
<li>HTML 닫기 태그 없이 들여쓰기로 블럭을 구분</li>
<li>= 을 이용해서 전달받은 변수 사용 가능</li>
<li>id나 class는 태그 뒤에 이어서 바로 사용</li>
<li>() 을 이용해서 attribute 사용</li>
</ul>
<pre><code class="language-javascript">// each, if
each item in arr
    if item.name == &#39;new&#39;
        h1 New Document
    else
        h1= `${item.name}`
</code></pre>
<ul>
<li>each ~ in 표현식으로 주어진 배열의 값을 순환하며 HTML 태그를 만들 수 있음</li>
<li>if, else if, else를 이용해 주어진 값의 조건을 확인하여 HTML 태그를 만들 수 있음</li>
</ul>
<pre><code class="language-javascript">// layout
--- layout.pug ---
html
    head
        title= title
    body
        block content

--- main.pug ---
extends layout
block content
    h1 Main Page</code></pre>
<ul>
<li>block을 포함한 템플릿을 선언하면 해당 템플릿을 layout으로 사용할 수 있음</li>
<li>layout을 extends 하면 block 부분에 작성한 HTML 태그가 포함됨</li>
<li>반복되는 웹사이트의 틀을 작성해 두고 extends 하며 개발하면 매우 편리한 기능</li>
</ul>
<pre><code class="language-javascript">// include
---title.pug---
h1= title

---main.pug
extend layout
block content
    include title
    div.content
        안녕하세요
    pre
        include article.txt</code></pre>
<ul>
<li>자주 반복되는 구문을 미리 작성해 두고 include 하여 사용할 수 있음</li>
<li>일반적인 텍스트 파일도 include 하여 템플릿에 포함 가능</li>
</ul>
<pre><code class="language-javascript">// mixin
--- listItem.pug ---
mixin listItem(title, name)
    tr
        td title
        td name

--- main.pug ---
include listItem
table
    tbody
    listItem(&#39;제목&#39;, &#39;이름&#39;)</code></pre>
<ul>
<li>mixin 을 사용하여 템플릿을 함수처럼 사용할 수 있게 선언할 수 있음</li>
<li>include는 값을 지정할 수 없지만 mixin 은 파라미터를 지정하여 값을 넘겨받아 템플릿에 사용할 수 있음</li>
</ul>
<br>
<br>

<h2 id="expressjs와-pug-연동">Express.js와 pug 연동</h2>
<pre><code class="language-javascript">--- app.js ---
app.set(&#39;views&#39;, path.join(__dirname, &#39;views&#39;));
app.set(&#39;view engine&#39;, &#39;pug&#39;);
app.locals.pretty = true;

--- request handler ---
res.render(&#39;main&#39;, { title: &#39;Hello Express&#39; });
</code></pre>
<ul>
<li>app.set을 이용해 템플릿이 저장되는 디렉터리를 지정하고, 어떤 템플릿 엔진을 사용할지 지정할 수 있음</li>
<li>app.locals.pretty = true는 pug로 출력되는 html값을 가독성있게 정리.</li>
<li>res.render 함수는 app.set에 지정된 값을 이용해 화면을 그리는 기능을 수행함</li>
<li>render 함수의 첫 번째 인자는 템플릿의 이름, 두 번째 인자는 템플릿에 전달되는 값
javascript
```</li>
<li>-- app.js ---
app.locals.appName = &quot;Express&quot;</li>
</ul>
<p>--- main.pug ---
h1= appName</p>
<p>// <h1>Express</h1></p>
<pre><code>
- Express.js의 app.locals를 사용하면 render 함수에 전달되지 않은 값이나 함수를 사용할 수 있음
- 템플릿에 전역으로 사용될 값을 지정하는 역할

&lt;br&gt;&lt;br&gt;

## express-generator 사용 시 템플릿 엔진 지정하기
`$ express --view=pug myapp`
- express-generator는 기본적으로 jade라는 템플릿 엔진을 사용
- jade는 pug의 이전 이름으로, 최신 지원을 받기 위해선 템플릿 엔진을 pug로 지정 해야 함
- --view 옵션을 사용하여 템플릿 엔진을 지정할 수 있음

&lt;br&gt;&lt;br&gt;












</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Node.js] MongoDB 기초를 배워보자]]></title>
            <link>https://velog.io/@yuj_125/Node.js-MongoDB-%EA%B8%B0%EC%B4%88%EB%A5%BC-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@yuj_125/Node.js-MongoDB-%EA%B8%B0%EC%B4%88%EB%A5%BC-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Wed, 27 Sep 2023 13:04:42 GMT</pubDate>
            <description><![CDATA[<h2 id="dbdatabase--dbmsdatabase-management-system">DB(Database) &amp; DBMS(Database Management System)</h2>
<h3 id="db">DB</h3>
<ul>
<li>전기적으로 저장된 데이터의 집합 </li>
<li>영속성을 갖는 데이터 저장소</li>
<li>데이터를 각자가 정의한 구조로 저장</li>
</ul>
<h3 id="dbms">DBMS</h3>
<ul>
<li>데이터베이스를 운영하고 관리하는 소프트웨어(시스템). 전용 언어(SQL등)를 사용해서 관리하는 시스템.</li>
<li>DB는 데이터를 체계적으로 보관하는 저장소의 개념이고, DBMS는 DB에 저장된 데이터에 체계적으로 접근하도록 하는 시스템.</li>
<li>크게 네 가지 기능<ul>
<li>데이터 정의 : 저장하는 데이터의 구조 정의를 생성, 수정, 삭제한다.</li>
<li>데이터 업데이트 : 데이터 삽입, 수정, 삭제한다.</li>
<li>데이터 검색 : 저장된 데이터를 사용자가 원하는 형태로 가져온다.</li>
<li>관리 : DBMS 유저 등록/유저 모니터링/데이터 접근 권한 관리/성능 모니터링/무결성 유지/동시성 제어/정보 복구(특정 이벤트, 의도치않은 시스템 다운)</li>
</ul>
</li>
</ul>
<p><br><br></p>
<h2 id="데이터-페이스-타입">데이터 페이스 타입</h2>
<h3 id="1-관계형-데이터베이스relational-dbms--rdb">1) 관계형 데이터베이스(Relational DBMS : RDB)</h3>
<ul>
<li>관계 대수를 기반으로 구현된 데이터베이스. 정형 데이터를 관리한다.</li>
<li>스프레드시트 형태의 데이터 구조를 가지고 있다고 생각하면 이해하기 쉽다.</li>
<li><code>SQL</code>로 데이터를 검색, 업데이트할 수 있다.</li>
</ul>
<blockquote>
<p><strong>SQL(Structured Query Language)</strong></p>
</blockquote>
<ul>
<li><p>DBMS에 데이터를 <strong>검색/업데이트</strong>(DML : Data Manipulation Language), 일련의 데이터 구조를 가진 구조체(테이블)를 <strong>생성/수정/삭제</strong>(DDL : Data Definition Language), <strong>유저 관리</strong>(DCL : Data Control Language), <strong>DB transaction 관리</strong>(TCL : Transaction Control Language)를 지원하는 프로그래밍언어이다.</p>
</li>
<li><p>사람이 읽었을 때 이해하기 쉽도록 문법이 구성 되어있다.</p>
</li>
<li><p>모든 RDBMS의 SQL는 기본적으로 유사한 문법을 가지고 있다. 다만 독자적으로 가지고 있는 문법들도 있다.</p>
</li>
<li><p>SQL을 작성해서 DB에게 명령을 보내는 행위는 사람이 스프레드시트를 만들어서 값을 채워 넣고 수정하고 지우는 과정이랑 매우 유사하다</p>
</li>
<li><p>일반적으로 DB라고 하면 RDBMS를 일컫지만 점점 달라지고 있다.</p>
</li>
<li><p>MySQL, Oracle DB, MariaDB, PostgreSQL, SQLite </p>
</li>
</ul>
<h3 id="2-nosql-데이터베이스nosql-dbms">2) NoSQL 데이터베이스(NoSQL DBMS)</h3>
<ul>
<li>관계형 데이터베이스 이외의 데이터베이스(관계 대수를 엄격하게 따르지 않는다는 것)</li>
<li>제품마다 정형/비정형 데이터를 다룬다. 저장하는 데이터 구조가 다양하다.<ul>
<li>구조 유형 : Document, key value, Object, Wide Column, Graph 
→ MongoDB(Document), Redis(key-value), Cassandra(Wide column), Elasticsearch(Document), Neo4j(Graph)</li>
</ul>
</li>
</ul>
<p><br><br></p>
<h2 id="mongodb">MongoDB</h2>
<p><strong>문서 기반 DB(Document oriented DB)</strong></p>
<ul>
<li>Mongo는 Humongous 에서 따온 말로, 엄청나게 큰 DB 라는 의미 → 대용량 데이터를 처리하기 좋게 만들어졌다.</li>
<li>JSON like 문서(BSON 타입)를 지원하며 이러한 이유로 JSON형태의 데이터를 다루는 웹 생태계에서 큰 인기를 얻게 되었다.</li>
<li>RDMS대비 비교적 단순한 설계(데이터 저장 방식)를 가지고 있기 때문에 진입 장벽이 낮은 장점이 있다.</li>
<li>간단한 CRUD기반의 서비스에 매우 적합하다.</li>
<li>Aggregation Pipeline 기능을 활용하여 DB단에서 데이터 연산을 수행시킬 수 있다. 어플리케이션 코드의 부담을 줄일 수 있다. DB단에 연산을 수행시키는 것은 RDMS도 procedure라는 것을 이용해서 가능하다. 하지만 MongoDB의 aggregation 기능이 상대적으로 단순하고 사용하기 용이하다.</li>
<li>다양한 데이터를 저장하고 다뤄야하는 도메인에서 많이 사용한다.</li>
<li>데이터 간의 관계가 중요한 서비스에는 적합하지 않다.</li>
</ul>
<p><strong>관계형 데이터베이스와의 유사 개념</strong></p>
<ul>
<li>여러 개의 데이터베이스를 관리하고 하나의 데이터베이스는 여러 개의 컬렉션을 가지고 있다. 
➡ SQL에서의 database와 유사</li>
<li>컬렉션은 다큐먼트의 집합이다. 
➡ RDBMS의 테이블과 유사</li>
<li>다큐먼트는 MongoDB의 데이터 저장 단위이다. 사용자가 저장하는 데이터는 모두 다큐먼트로 저장된다. 
➡ RDBMS의 레코드(테이블의 한 row)와 유사</li>
</ul>
<br>

<h3 id="다큐먼트">다큐먼트</h3>
<ul>
<li>BSON(Binary JSON) 형식의 데이터 구조 : JSON보다 더 많은 데이터 타입을 지원한다.</li>
<li>자바스크립트 객체랑 비슷한 형태로 필드명과 필드값을 가진다.</li>
<li>최신 버전 기준 16개의 데이터 타입을 지원한다.<ul>
<li>Text - String</li>
<li>Numeric - 32-bit integer, 64-bit integer, Double </li>
<li>Date - Date, Timestamp </li>
<li>Other -  Object, Array, Binary data, ObjectId, Boolean, Null, Regular Expression, JavaScript, Min key, Max key</li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>필드명 제한</strong></p>
</blockquote>
<ul>
<li>&quot;_id&quot;는 사용할 수 없다. Primary key(고유값)로 예약되어 있는 이름이다.</li>
<li>필드명은 null 캐릭터(UTF-8 인코딩의 \u0000)를 포함할 수 없다.</li>
<li>&quot;$&quot;, &quot;.&quot;을 제한적인 환경에서 포함할 수 있다. <blockquote>
</blockquote>
</li>
<li><em>문서 사이즈 제한*</em></li>
<li>최대 16MB <blockquote>
</blockquote>
</li>
<li><em>_id 필드*</em></li>
<li>모든 MongoDB에 저장된 document들은 _id 필드를 가지고 있다. 고유값으로 DB에서의 primary key 역할을 수행한다.</li>
<li>새로운 document를 MongoDB에 생성(삽입)할 때 _id필드를 빼고 하면 MongoDB 드라이버가 알아서 _id필드를 생성해준다.<blockquote>
</blockquote>
</li>
<li><em>문서 필드 순서*</em></li>
<li>JS의 객체와는 다르게 MongoDB의 document의 필드들은 순서가 보장된다.</li>
<li>순서가 보장되어 있는 만큼 문서에 대한 데이터 검색를 할 때는 주의해야한다.</li>
<li>MongoDB의 정의에 따라 {a: 1, b: 1}와 {a: 1, b: 1}는 같지만 {a: 1, b: 1}와 {b: 1, a: 1}는 다르다.</li>
<li>MongoDB에서 document를 찾을 때는 exact match와 같은 데이터 검색(query)은 지양하는게 좋다. 조건문 검색이 좋다.<ul>
<li>항상 _id 필드는 첫번째로 배정된다.</li>
</ul>
</li>
</ul>
<h2 id="다큐먼트-crud">다큐먼트 CRUD</h2>
<h3 id="1-crud---create">1) CRUD - Create</h3>
<pre><code class="language-javascript">db.users.insertOne (            &lt;- collection
    {                            &lt;- document
        name : &quot;Lee&quot;,            &lt;- field: value 
        age : 26,        
        status : &quot;pending&quot;
    }
)</code></pre>
<ul>
<li>하나의 document : db.collection.insertOne({ 필드 : 값, 필드 : 값, ... }) </li>
<li>여러 document : db.collection.insertMany([{...}, {...}, {...}])</li>
</ul>
<h3 id="2-crud---read">2) CRUD - Read</h3>
<pre><code class="language-javascript">db.users.find(                    &lt;- collection
    { age : {$gt: 18} },        &lt;- query criteria
    { name : 1, address : 1 }    &lt;- projection
).limit(5)                        &lt;- cursor modifier
</code></pre>
<ul>
<li>db.collection.find() : 하나/다수의 ducument 찾기</li>
<li>$in : [] 을 사용하여 다중 값으로 검색, Mongoose는 쿼리 값으로 배열이 주어지면 자동으로 $in 쿼리를 생성해 줌</li>
<li>$or : [] 를 사용하여 다중 조건 검색</li>
<li>$lt, $lte, $gt, $gte 를 사용하여 range query 작성 가능</li>
</ul>
<h3 id="3-crud---update">3) CRUD - Update</h3>
<pre><code class="language-javascript">db.users.updateMany(                    &lt;- collection
    { age : {$lt: 18} },                 &lt;- update filter
    { $set : { status : &quot;reject&quot; } }    &lt;- update action
)</code></pre>
<ul>
<li>db.collection.updateOne() : 하나의 document 수정(단, 조건에 해당되는 document가 많으면 가장 처음 발견되는 document를 업데이트한다)</li>
<li>db.collection.updateMany(): 다수의 document 수정</li>
</ul>
<h3 id="4-crud---delete">4) CRUD - Delete</h3>
<pre><code class="language-javascript">db.users.deleteMany(        &lt;- collection
    { status: &quot;reject&quot; }    &lt;- delete filter
)</code></pre>
<ul>
<li>db.collection.deleteOne() : 하나의 document 삭제 (단, 조건에 해당되는 document가 많으면 가장 처음 발견되는 document를 삭제한다)</li>
<li>db.collection.deleteMany(): 다수의 document 삭제</li>
<li>db.collection.deleteMany({}) : 전체 삭제</li>
</ul>
<br>
<br>

<h2 id="mongooseodm">Mongoose(ODM)</h2>
<h3 id="odmobject-data-mapping">ODM(Object Data Mapping)</h3>
<ul>
<li>Node.js 어플리케이션이 MongoDB에 데이터를 CRUD할 수 있도록 도와주는 외부 패키지(라이브러리)</li>
<li>MongoDB의 기본 Node.js 드라이버는 연결상태를 관리하기 어려운데 Mongoose를 사용하면 간단하게 데이터베이스와의 연결상태를 관리.</li>
<li>Mongoose의 장점은 데이터를 단순하게 CRUD하는 것이 아니라, 데이터 검증(validation) + document를 JS 객체 변환까지 해주는 것.</li>
<li>MongoDB에서 가져온 document 데이터를 JS 객체화한 것을 모델이라고 함.</li>
<li>개발자는 이 모델을 가지고 데이터를 객체지향 방식으로 수정</li>
<li>크게 검증 파트와 CRUD + document를 JS 객체 변환 파트.</li>
<li>검증 파트는 Schema 모듈이 담당하고, CRUD + document를 JS 객체 변환은 Model 모듈이 담당.</li>
<li>Populate : MongoDB는 기본적으로 Join을 제공하지 않음. Join과 유사한 기능을 사용하기 위해선 aggregate 라는 복잡한 쿼리를 해야 하지만, Mongoose는 populate를 사용하여 간단하게 구현할 수 있음</li>
</ul>
<h3 id="mongoose-odm-사용-순서">Mongoose ODM 사용 순서</h3>
<ol>
<li>스키마 정의</li>
<li>모델 만들기</li>
<li>데이터베이스 연결</li>
<li>모델 사용</li>
</ol>
<h3 id="스키마schema">스키마(Schema)</h3>
<ul>
<li>한 collection의 document의 구조를 명시화한 객체</li>
<li>Mongoose는 어플리케이션이 MongoDB에 데이터를 CRUD를 할 때 이 객체를 가지고 데이터 검증(각 필드 별 타입 검증)을 수행. </li>
<li>추가적인 검증도 커스텀 함수를 추가해서 가능. ex) 나이의 범위, 이름의 글자수 등</li>
<li>일종의 데이터 체크리스트</li>
<li>mongoose.Schema =&gt; 이 함수의 리턴값은 객체.</li>
<li>MongoDB와 데이터를 어떤 틀에 맞춰서 주고 받을지 정의하는 것 </li>
<li>MongoDB는 RDB와 달리 한 collection에 저장된 document가 모두 같은 데이터 구조를 가져야하는 강제성을 갖고있지 않다.</li>
</ul>
<h3 id="모델model">모델(Model)</h3>
<ul>
<li>스키마 객체를 사용해서 MongoDB에 있는 document 데이터를 JS의 객체 형태로 나타낼 수 있게 해줌.</li>
<li>MongoDB에 있는 모든 document들에 대한 CRUD도 책임.</li>
<li>JS 코드 상에서 실질적으로 자주 다루는 것이 모델.</li>
<li>mongoose.model =&gt; 이 함수의 리턴값은 class. 이 class로 새로운 document 객체를 생성해서 MongoDB에 저장할 수도 있고 class의 static 메소드를 사용해서 document CRUD를 할 수도 있음. CRUD의 리턴값은 이 클래스의 객체.</li>
<li>JS객체 형식으로 MongoDB와 데이터를 주고 받는 것 </li>
</ul>
<pre><code class="language-javascript">const mongoose = require(&quot;mongoose&quot;);
await mongoose.connect(&quot;mongodb://&lt;your mongodb url&gt;&quot;);

const coffeeSchema = mongoose.Schema({
 type: String,
 orderedBy: String,
});

// Coffee가 Coffee model 생성을 위한 class이다.
const Coffee = mongoose.model(&quot;Coffee&quot;, coffeeSchema);
                             // ↑  Collection의 이름


// ./models/schemas/board.js
const { Schema } = require(&#39;mongoose&#39;);

const PostSchema = new Schema({
    title: String,             // 다양한 형식을 미리 지정하여, 생성, 수정 작업 시 데이터 형식을 체크해주는 기능을 제공함
    content: String,
}, {
    timestamps: true,        // timestamps 옵션을 사용하면 생성, 수정 시간을 자동으로 기록해 줌
});

module.exports = PostSchema;


// ./models/index.js
const mongoose = require(&#39;mongoose&#39;);

const PostSchema = require(&#39;./schemas/board&#39;);

exports.Post = mongoose.model(&#39;Post&#39;, PostSchema);    
// 작성된 스키마를 mongoose에서 사용할 수 있는 모델로 만들어야 함
// 모델의 이름을 지정하여 Populate 등에서 해당 이름으로 모델을 호출할 수 있음


// index.js
const mongoose = require(&#39;mongoose&#39;);

const { Post } = require(&#39;./models&#39;);

mongoose.connect(&#39;mongodb://localhost:27017/myapp&#39;);    
// connect 함수를 이용하여 간단하게 데이터베이스에 연결할 수 있음
// Post 바로 사용 가능
</code></pre>
<br>

<h2 id="connection-pooling">connection pooling</h2>
<ul>
<li>재사용할 수 있는 active connection들을 관리하는 개념</li>
<li>connection : 클라이언트와 서버 간의 특정 프로토콜을 이용한 연결이다. 한쪽이 연결을 끊으면 바로 없어진다.</li>
<li>하나의 풀(pool)장에 여러 active connection(끊기지 않은)을 담아 놓아서 재사용하는 것을 목적으로 한다.
재사용 = 연결을 새로 맺 는 수고(시간 및 연산 비용)를 줄일 수 있음</li>
<li>유연한 connection 관리로 application 입장에서는 query들의 병목 현상을 줄이고(throughput ↑), DB 입장에서는 클라이언트가 connection을 남용하지 않기 때문에 connection 가용성을 확보할 수 있다.</li>
<li>설정한 pool 사이즈 안에서 클라이언트는 connection을 마음대로 생성하고 사용하고 삭제할 수 있다.</li>
<li>mongoose의 pool 사이즈는 mongoose.connect 메소드의 minPoolSize와 maxPoolSize옵션으로 조절할 수 있으며 maxPoolSize의 default값은 100이다.</li>
<li>현재 사용중인 connection의 갯수가 가용 가능한 connection의 갯수랑 같을 때 새로운 쿼리가 실행되면 새로운 connection을 생성한다 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Node.js] express 미들웨어의 종류]]></title>
            <link>https://velog.io/@yuj_125/Node.js-express-%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4%EC%9D%98-%EC%A2%85%EB%A5%98</link>
            <guid>https://velog.io/@yuj_125/Node.js-express-%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4%EC%9D%98-%EC%A2%85%EB%A5%98</guid>
            <pubDate>Wed, 27 Sep 2023 12:26:39 GMT</pubDate>
            <description><![CDATA[<h2 id="🎯미들웨어middleware-정의">🎯미들웨어(Middleware) 정의</h2>
<blockquote>
<p> Express.js 안에서 요청과 응답 사이에 단계별 동작을 수행해주는 함수이다.</p>
</blockquote>
<br>
<br>

<h2 id="미들웨어middleware-특징">미들웨어(Middleware) 특징</h2>
<ul>
<li>middleware는 request, response 사이클 안에서 routing handler 함수가 가지고 있는 request 객체, response 객체, next 함수에 대한 접근이 가능한 함수다. </li>
<li>미들웨어는 어떠한 코드도 실행 가능하다.</li>
<li>request, response 객체 수정이 가능하고 request response 사이클을 끝낼 수 있다.</li>
<li>다음 미들웨어를 호출할 수 있다.</li>
<li>Client의 요청으로 Express 앱 내부에서 request response 사이클이 진행될 때마다 반드시 실행되어야 하는 코드들을 정의하기에 적합하다</li>
<li>middleware는 global 단위(모든 PATH), PATH 단위로 유연하게 등록이 가능하다.</li>
<li>등록 순서에 따라 실행되기 때문에 주의해야한다.</li>
<li>미들웨어의 유연성 덕분에 Express는 서드파티 미들웨어들이 매우 많다.</li>
</ul>
<br>
<br>

<h2 id="route-handler">Route Handler</h2>
<ul>
<li>Route Handler도 미들웨어의 한 종류</li>
<li>Route Handler는 라우팅 함수(get, post, put, delete 등)에 적용된 미들웨어</li>
<li>일반적인 미들웨어와는 다르게 path parameter를 사용할 수 있음</li>
</ul>
<br>
<br>

<h2 id="미들웨어-작성법">미들웨어 작성법</h2>
<ul>
<li>req, res, next를 매개변수로 가지는 함수를 작성<ul>
<li>req는 HTTP 요청을 처리하는 객체</li>
<li>res는 HTTP 응답을 처리하는 객체</li>
<li>next는 다음 미들웨어를 실행하는 함수
✔ <strong>next() 함수가 호출되지 않으면 미들웨어 사이클이 멈추기 때문에 주의!</strong></li>
</ul>
</li>
<li>middleware 는 적용되는 위치에 따라서 어플리케이션 미들웨어, 라우터 미들웨어, 오류처리 미들웨어로 분류 가능</li>
<li>필요한 동작 방식에 따라 미들웨어를 적용할 위치를 결정</li>
</ul>
<br>
<br>

<h3 id="어플리케이션-미들웨어">어플리케이션 미들웨어</h3>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
    console.log(`Request ${req.path}`);
    next();    //1
});

app.use(auth);    //2

app.get(&#39;/&#39;, (req, res, next) =&gt; {
    res.send(&#39;Hello Express&#39;);    //3
});</code></pre>
<ul>
<li>use 나 http method 함수를 사용하여 미들웨어를 연결할 수 있음</li>
<li>미들웨어를 모든 요청에 공통적으로 적용하기 위한 방법</li>
<li>HTTP 요청이 들어온 순간부터 적용된 순서대로 동작 함</li>
</ul>
<h3 id="라우터-미들웨어">라우터 미들웨어</h3>
<pre><code class="language-javascript">router.use(auth);                    //3

router.get(&#39;/&#39;, (req, res, next) =&gt; {
    res.send(&#39;Hello Router&#39;);        //4
});

app.use((req, res, next) =&gt; {
    console.log(`Request ${req.path}`);
    next();                            //1
});

app.use(&#39;/admin&#39;, router);            //2</code></pre>
<ul>
<li>router 객체에 미들웨어가 적용되는 것 외에는 어플리케이션 미들웨어와 사용 방법은 동일</li>
<li>특정 경로의 라우팅에만 미들웨어를 적용하기 위한 방법</li>
<li>app 객체에 라우터가 적용된 이후로 순서대로 동작함</li>
</ul>
<h3 id="미들웨어-서브-스택">미들웨어 서브 스택</h3>
<pre><code class="language-javascript">app.use(middleware1, middlware2, ...);

app.use(&#39;/admin&#39;, auth, adminRouter);

app.get(&#39;/&#39;, logger, (req, res, next) =&gt; {
    res.send(&#39;Hello Express&#39;);
});</code></pre>
<ul>
<li>use 나 http method 함수에 여러 개의 미들웨어를 동시에 적용할 수 있음</li>
<li>주로 한 개의 경로에 특정해서 미들웨어를 적용하기 위해 사용</li>
<li>전달된 인자의 순서 순으로 동작</li>
</ul>
<h3 id="오류처리-미들웨어">오류처리 미들웨어</h3>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
    if (!isAdmin(req)) {
        next(new Error(&#39;Not Authorized&#39;));
        return;
    }
    next();
});

app.get(&#39;/&#39;, (req, res, next) =&gt; {
    res.send(&#39;Hello Express&#39;);
});

app.use((err, req, res, next) =&gt; {
    res.send(&#39;Error Occurred&#39;);
});</code></pre>
<ul>
<li>오류처리 미들웨어는 일반적으로 가장 마지막에 위치하는 미들웨어</li>
<li>다른 미들웨어들과는 달리 err, req, res, next 네 가지 인자를 가지며,  앞선 미들웨어에서 next 함수에 인자가 전달되면 실행됨</li>
<li>이전에 적용된 미들웨어 중 next에 인자를 넘기는 경우 중간 미들웨어들은 뛰어넘고 오류처리 미들웨어가 바로 실행됨</li>
</ul>
<h3 id="함수형-미들웨어">함수형 미들웨어</h3>
<pre><code class="language-javascript">const auth = (memberType) =&gt; {
    return (req, res, next) =&gt; {
        if (!checkMember(req, memberType)) {
            next(new Error(`member not ${memberType}`));
            return;
        }
        next();
    }
}


app.use(&#39;/admin&#39;, auth(&#39;admin&#39;), adminRouter);

app.use(&#39;/users&#39;, auth(&#39;member&#39;), userRouter);</code></pre>
<ul>
<li>auth 함수는 미들웨어 함수를 반환하는 함수</li>
<li>auth 함수 실행 시 미들웨어의 동작이 결정되는 방식으로 작성됨</li>
<li>일반적으로 동일한 로직에 설정값만 다르게 미들웨어를 사용하고 싶을 경우에 활용됨</li>
</ul>
<br>
<br>












]]></description>
        </item>
        <item>
            <title><![CDATA[[Node.js] express.js 기초 알아보기]]></title>
            <link>https://velog.io/@yuj_125/Node.js-express.js-%EA%B8%B0%EC%B4%88-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@yuj_125/Node.js-express.js-%EA%B8%B0%EC%B4%88-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Mon, 18 Sep 2023 16:36:20 GMT</pubDate>
            <description><![CDATA[<h2 id="expressjs">Express.js</h2>
<ul>
<li>Node.js의 웹 프레임워크 중 가장 유명한 웹 프레임워크</li>
<li>필요에 따라 유연하게 구조 설정 가능</li>
<li>다양한 미들웨어를 통해 필요한 기능을 간단하게 추가 가능</li>
<li>모든 동작이 명시적으로 구성되기 때문에, 웹 프레임워크의 동작 방식을 이해하기 가장 좋은 프레임워크</li>
</ul>
<p><br><br></p>
<h2 id="expressjs-시작하기">Express.js 시작하기</h2>
<h3 id="1-npm-init으로-시작하기">1. npm init으로 시작하기</h3>
<ul>
<li>Express.js를 처음부터 작성할 수 있는 방법</li>
<li>직접 모든 구조를 작성해야 하기 때문에, Express.js를 처음 접하는 사용자에겐 쉽지 않음</li>
</ul>
<pre><code class="language-javascript">$mkdir my-web
$cd my-web
$npm init
$npm i express

---

const express = require(&#39;express&#39;)
const app = express()
app.get(&#39;/&#39;, (req, res) =&gt; {
    res.send(&#39;Hello World!&#39;);
});
app.listen(3000);</code></pre>
<h3 id="2-express-generator-사용하기">2. express-generator 사용하기</h3>
<ul>
<li>Express.js는 express-generator 라고 하는 프로젝트 생성기를 제공함</li>
<li>express-generator를 사용하면 프로젝트의 기본구조를 자동으로 생성해줌</li>
<li>빠르게 프로젝트를 시작하기 좋은 방법</li>
<li>생성된 프로젝트는 npm start 로 실행 가능</li>
</ul>
<pre><code class="language-javascript">$npm i -g express-generator
$express my-web
$cd my-web
$npm i
$npm start</code></pre>
<h3 id="3-npx--express-generator-사용하기">3. npx + express-generator 사용하기</h3>
<ul>
<li>npx를 사용하여 express-generator 를 설치하지 않고, 바로 사용 가능.</li>
<li>express-generator는 프로젝트 생성 이후엔 사용되지 않기 때문에, npx를 사용하는 것도 좋은 방법</li>
</ul>
<pre><code>$npx express-generator my-web
$cd my-web
$npm i
$npm start</code></pre><p><br><br></p>
<h2 id="expressjs-의-기본-구조">Express.js 의 기본 구조</h2>
<table>
<thead>
<tr>
<th></th>
<th align="center">구조</th>
<th align="center">의미</th>
</tr>
</thead>
<tbody><tr>
<td></td>
<td align="center"><strong>app.js</strong></td>
<td align="center">Express.js 의 가장 기본이 되는 파일, 웹 어플리케이션의 기능을 정의</td>
</tr>
<tr>
<td></td>
<td align="center"><strong>bin/www</strong></td>
<td align="center">Express.js 실행 부분을 담당, 포트와 실행 오류 등을 정의</td>
</tr>
<tr>
<td><strong>my-web</strong></td>
<td align="center"><strong>package.json</strong></td>
<td align="center">프로젝트 의존성 및 스크립트 정의</td>
</tr>
<tr>
<td></td>
<td align="center"><strong>public</strong></td>
<td align="center">코드를 통하지 않고, 직접 제공되는 파일 디렉터리</td>
</tr>
<tr>
<td></td>
<td align="center"><strong>routes</strong></td>
<td align="center">라우팅 파일 디렉터리</td>
</tr>
<tr>
<td></td>
<td align="center"><strong>views</strong></td>
<td align="center">HTML Template 디렉터리</td>
</tr>
</tbody></table>
<br>

<hr>
<br>

<h2 id="expressjs-동작-방식">Express.js 동작 방식</h2>
<h3 id="app-객체">app 객체</h3>
<pre><code class="language-javascript">// app.js
var express = require(&#39;express&#39;);    
...
var app = express();</code></pre>
<ul>
<li>app.js에서는 express()로 생성되는 <code>app 객체</code>를 확인할 수 있음</li>
<li>app 객체는 Express.js 의 기능을 담은 객체</li>
<li>Express.js의 모든 동작은 app 객체에 정의됨</li>
</ul>
<blockquote>
<p><strong>app 객체   주요 기능</strong></p>
</blockquote>
<ul>
<li>*<em>app.use() *</em>: middleware 를 사용하기 위한 함수</li>
<li><strong>app.listen()</strong> : http 서버를 생성해주는 함수. express-generator 를 사용하면 http.createServer를 사용하는데 app.listen 함수로 대체할 수 있음</li>
<li><strong>app.locals</strong> : app에서 사용할 공통 상수. Express.js 에선 global 변수를 선언하지 않고 이 값을 사용할 수 있음</li>
</ul>
<br>

<h3 id="라우팅">라우팅</h3>
<p><strong>1) app 라우팅</strong></p>
<pre><code class="language-javascript">app.get(&#39;/&#39;, (req, res) =&gt; {
    res.send(&#39;GET /&#39;);
});

app.post(&#39;/&#39;, (req, res) =&gt; {
    res.send(&#39;POST /&#39;);
});

app.put(&#39;/&#39;, (req, res) =&gt; {
    res.send(&#39;PUT /&#39;);
});

app.delete(&#39;/&#39;, (req, res) =&gt; {
    res.send(&#39;DELETE /&#39;);
});

app.all(&#39;/all&#39;, (req, res) =&gt; {
    res.send(&#39;ANY /&#39;);
});</code></pre>
<ul>
<li>app 객체에 직접 get, post, put, delete 함수를 사용하여 HTTP method 로 라우팅 할 수 있음.</li>
<li>HTTP method 함수의 첫 번째 인자가 이 라우팅을 실행할 URL.</li>
<li>마지막 인자가 이 라우팅이 실행될 때 작동하는 함수 all 함수를 사용하면 HTTP method에 상관없이 라우팅 가능</li>
</ul>
<p><strong>2) Express.Router</strong>
✔ app 라우팅을 통해서는 라우팅의 핵심인 그룹화를 지원하지 않음. Express.Router 를 통해 라우팅을 <strong>모듈화</strong> 할 수 있음</p>
<pre><code class="language-javascript">// Express.Router 모듈
const express = require(&#39;express&#39;);
const router = express.Router();

router.get(&#39;/&#39;, (req, res, next) =&gt; {
    res.send(&#39;respond with a resource&#39;);
});

module.exports = router;</code></pre>
<ul>
<li>router 객체에도 app 객체처럼 get, put, post, delete 함수를 사용할 수 있음</li>
<li>app의 함수와 동일한 동작을 하는 함수로 첫 번째 인자가 라우팅 될 URL이고, 마지막 인자가 라우팅 시 실행될 함수</li>
<li>라우터는 일반적으로 모듈로 만들어서 사용함</li>
</ul>
<pre><code class="language-javascript">// Express.Router 사용
// ./app.js
const userRouter = require(&#39;./routes/users&#39;);
const app = express();

app.use(&#39;/users&#39;, userRouter);    // 작성된 라우터 모듈을 app 에 use함수로 연결하여 사용할 수 있음

// ./routes/users.js
const petRouter = require(&#39;./pets&#39;); 
const router = express.Router();

router.use(&#39;/pets&#39;, petRouter);    // router 객체에도 하위 라우터를 use 함수로 연결하여 사용할 수 있음

module.exports = router;</code></pre>
<br>

<p><strong>라우팅 - path parameter 사용</strong></p>
<ul>
<li>Express.js 라우팅은 path parameter를 제공</li>
<li>path parameter를 사용하면, 주소의 일부를 변수처럼 사용할 수 있음<ul>
<li>/users/:id -&gt; /users/123, /users/456 등으로 접속했을 때 라우팅 적용</li>
<li>/messages/:from-:to -&gt; /message/123-456 등으로 접속했을 때 라우팅 적용</li>
</ul>
</li>
</ul>
<p><br><br></p>
<h3 id="request-handler">Request Handler</h3>
<ul>
<li>라우팅에 적용되는 함수를 Request Handler라고 부름</li>
<li>HTTP 요청과 응답을 다룰 수 있는 함수로 설정된 라우팅 경로에 해당하는 요청이 들어오면 Request Handler 함수가 실행됨</li>
</ul>
<pre><code class="language-javascript">router.get(&#39;/:id&#39;, (req, res) =&gt; {    // router나 app의 HTTP method 함수의 가장 마지막 인자로 전달되는 함수
    const id = req.params.id        // 설정된 라우팅 경로에 해당하는 요청이 들어오면 Request Handler 함수가 실행됨
    res.send(`hello ${id}`);        // 요청을 확인하고, 응답을 보내는 역할을 함
});</code></pre>
<br>

<p><strong>Request 객체의 주요 값 및 함수</strong>
HTTP 요청 정보를 가진 객체</p>
<p><strong>1) req.params</strong> : URL 표현 중 /path/:id 에서 :id 를 req.params.id 로 사용할 수 있음
<strong>2) req.queries</strong> : URL 표현 중 /path?page=2 에서 page 부분을 req.queries.page 로 사용할 수 있음 
<strong>3) req.body</strong> : 일반적으로 POST 요청의 요청 데이터를 담고 있음. req.body 에 요청 데이터가 저장되어 들어옴
<strong>4) req.get(&#39;&#39;)</strong> : HTTP Request 의 헤더 값을 가져올 수 있음. req.get(&#39;Authorization&#39;) 등으로 값을 가져옴</p>
<br>

<p><strong>Response 객체의 주요 값 및 함수</strong>
HTTP 응답을 처리하는 객체</p>
<p><strong>1) res.send()</strong> : text 형식의 HTTP 응답을 전송함
<strong>2) res.json()</strong> : json 형식의 HTTP 응답을 전송함
<strong>3) res.render()</strong> : HTML Template 을 사용하여 화면을 전송함
<strong>4) res.set()</strong> : HTTP 응답의 헤더를 설정함
<strong>5) res.status()</strong> : HTTP 응답의 상태 값을 설정함</p>
<p><br><br></p>
<h2 id="핸들러handler">핸들러(Handler)</h2>
<ul>
<li>클라이언트로부터 요청이 들어왔을 때 실행해야 하는 직업들을 정의해 놓은 함수이다.</li>
<li>클라이언트의 요청 정보가 담긴 request와 그 요청에 응답할 수 있도록 도와주는 response를 매개변수로 갖는다. </li>
<li>next라는 매개변수도 가지고 있는데 이는 다음 handler 또는 middleware를 부를 때 사용한다.</li>
<li>핸들러는 하나이거나 여러개(배열, 매개변수 형태)가 될 수 있다. </li>
<li>종류는 Route Handler / Middleware / Error Handler가 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Node.js] 프레임워크를 알아보자]]></title>
            <link>https://velog.io/@yuj_125/Node.js-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@yuj_125/Node.js-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Mon, 18 Sep 2023 15:53:34 GMT</pubDate>
            <description><![CDATA[<h2 id="웹-프레임워크">웹 프레임워크</h2>
<blockquote>
<p>웹 서비스에 필요한 기능들을 제공해주는 다양한 도구들의 모음</p>
</blockquote>
<br>

<h2 id="웹-프레임워크의-기본-구성요소">웹 프레임워크의 기본 구성요소</h2>
<p>웹 서비스의 정형화 된 구성을 많은 웹 프레임워크가 기본적으로 제공함</p>
<ul>
<li>HTTP 요청 처리<ul>
<li>웹 프레임워크는 HTTP 요청을 처리할 수 있다.</li>
<li>어떤 데이터를 필요로 하는지, 어떤 사용자로부터 요청이 수신되었는지 등</li>
</ul>
</li>
<li>HTTP 응답 처리<ul>
<li>웹 프레임워크는 HTTP 응답을 처리할 수 있다.</li>
<li>응답 데이터가 어떤 형식인지, 응답 상태가 정상적인지 등</li>
</ul>
</li>
<li>라우팅<ul>
<li>웹 프레임워크는 HTTP 요청을 분기하는 방법을 제공한다.</li>
<li>HTTP 요청 URL에 해당하는 알맞은 응답의 경로를 미리 설정</li>
</ul>
</li>
<li>HTML Templating<ul>
<li>웹 프레임워크는 SSR을 구현하기 위한 방법을 제공한다.</li>
<li>SSR에서 응답으로 보낼 HTML을 서버에서 작성하기 위해, HTML Template를 통해 미리 페이지의 뼈대를 작성 가능</li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>CSR &amp; SSR</strong>
양뱡항 통신으로 사용자와 상호작용하는 현대적인 웹은 대부분 동적 웹이다. 동적 웹은 사용자가 다양한 기능을 수행하고 프론트엔드와 백엔드가 유기적으로 통신하며 동작한다. 동적 웹을 구현하는 방법으로 CSR과 SSR이 있다.</p>
</blockquote>
<p><strong>CSR (Client-Side Rendering)</strong>
: 프론트엔드에서 사용자가 페이지에서 보는 동적인 부분을 대부분 처리하는 방식</p>
<ul>
<li>사이트가 변하는 부분들을 프론트엔드에서 처리</li>
<li>프론트엔드 코드에 페이지 리소스들이 미리 정의되어 있음</li>
<li>서버와의 통신은 API 통신을 이용하고 데이터만 주고받음</li>
<li>빠른 반응이지만 페이지의 내용은 API 호출이 완료된 후에 보여짐</li>
<li>복잡한 프로젝트 구성, 큰 개발 사이즈<blockquote>
</blockquote>
</li>
<li><em>SSR (Server-Side Rendering)*</em>
: 백엔드에서 페이지 대부분의 영역을 처리해서 프론트엔드로 전달하는 방식</li>
<li>사이트가 변하는 부분들을 백엔드에서 처리</li>
<li>백엔드에서 HTML 파일을 작성해서 프론트엔드로 전달, 프론트엔드는 HTTP 응답을 받아 화면에 표시</li>
<li>CSR에 비해 쉬운 구성, 작은 개발사이즈</li>
<li>로딩이 완료되면 페이지와 데이터가 한 번에 표시됨</li>
<li>상대적으로 사용자가 보기엔 로딩이 느려 보임</li>
<li>페이지 이동할 때마다 다시 로딩하기 때문에 페이지 깜빡임</li>
</ul>
<br>

<h2 id="nodejs의-웹프레임워크">Node.js의 웹프레임워크</h2>
<p><strong>Express.js</strong> - Node.js 의 가장 유명한 웹 프레임워크
<strong>Koa.js</strong> - 현대적인 JavaScript를 적극적으로 사용하는 웹 프레임워크
*<em>Nest.js *</em>- TypeScript 를 사용하며, 고정된 구조를 제공하는 웹 프레임워크
기타 - Hapi, Sails.js, Meteor.js 등</p>
<br>



















]]></description>
        </item>
        <item>
            <title><![CDATA[[Node.js] Node.js 모듈]]></title>
            <link>https://velog.io/@yuj_125/Node.js-Node.js-%EB%AA%A8%EB%93%88</link>
            <guid>https://velog.io/@yuj_125/Node.js-Node.js-%EB%AA%A8%EB%93%88</guid>
            <pubDate>Mon, 18 Sep 2023 15:46:50 GMT</pubDate>
            <description><![CDATA[<h2 id="nodejs-모듈">Node.js 모듈</h2>
<blockquote>
<p><strong>모듈이란?</strong>
간단한 프로그램이라면 파일 하나로도 가능하지만 프로젝트가 커지면 기능에 맞게 코드를 분리하는 것이 중요하다. 모듈은 코드를 분리하기 위한 방법이다.
✔ 패키지는 모듈의 모음. npm 패키지들은 많은 모듈을 포함하고 있는 코드 모음</p>
</blockquote>
<br>
<br>

<h2 id="nodejs-기본-제공-모듈">Node.js 기본 제공 모듈</h2>
<h3 id="1-console">1) console</h3>
<ul>
<li>브라우저에서 제공되는 console과 유사한 디버깅 도구</li>
<li>log, warn, error 함수로 로그 레벨 표시</li>
<li>time, timeLog, timeEnd 함수로 시간 추적</li>
</ul>
<h3 id="2-process">2) process</h3>
<ul>
<li>현재 실행 프로세스 관련 기능 제공</li>
<li>arch, argv, env 등 실행 환경 및 변수 관련 값 제공</li>
<li>abort, kill, exit 등 프로세스 동작 관련 함수 제공</li>
</ul>
<h3 id="3-fs">3) fs</h3>
<ul>
<li>파일 입출력을 하기 위해 사용</li>
<li>readFile, writeFile 함수로 파일 읽기, 쓰기</li>
<li>Sync 함수 제공, 동기 동작</li>
<li>watch로 파일/디렉터리 변경 이벤트 감지</li>
</ul>
<h3 id="4-http">4) http</h3>
<ul>
<li>http 서버, 클라이언트를 위해 사용</li>
<li>createServer 함수로 서버 생성</li>
<li>Request 함수로 http 요청 생성</li>
</ul>
<br>
<br>

<h2 id="모듈-작성법">모듈 작성법</h2>
<ul>
<li>기본적인 모듈 작성법<pre><code class="language-javascript">module.exports = {     // 모듈이 load될 때 사용될 값을 module.exports로 내보냄.
  name, 
  age, 
  nationality,
};
</code></pre>
</li>
</ul>
<hr>
<p>const people = require(‘./people’);</p>
<pre><code>
- 변수명으로 export하는 모듈 작성법
```javascript
exports.name = name;    // 모듈을 object로 만들고, 각 key - value를 지정해서 내보냄
exports.age = age;
exports.nationality = nationality;

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

const people = require(‘./people’);</code></pre><ul>
<li>함수를 export하는 모듈 작성법<pre><code class="language-javascript">module.exports = (name, age, nationality) =&gt; {    // 모듈을 함수로 만들어서 모듈 사용 시에 값을 정할 수 있게 내보냄
  return { 
      name, 
      age, 
      nationality,
  };
}
</code></pre>
</li>
</ul>
<hr>
<p>const student = require(‘./people’)(‘Park’, 5, ‘korea’) </p>
<pre><code>
&lt;br&gt;
&lt;br&gt;

## 모듈 사용 방법
- require 함수를 통해 모듈을 load 할 수 있다.
- C에서 include, Java에서 import와 유사하다.
- 의존성 패키지, 직접 작성한 모듈 사용 가능하다.
- require 할 때 모듈 코드가 실행된다.
- Node.js의 모듈은 첫 require 시에 cache, 두 번 실행하지 않는다.
- 모듈 코드를 여러 번 실행하기 위해선 함수 모듈로 작성한다.

### 1) npm패키지
```javascript
const dayjs = require(&#39;dayjs&#39;);
console.log(dayjs())</code></pre><ul>
<li>의존성 패키지들은 require(‘package-name’)로 load 할 수 있다.</li>
<li>패키지를 사용하려면 node_modules에 내려받아져 있어야 한다.</li>
</ul>
<h3 id="2-작접-작성한-모듈">2) 작접 작성한 모듈</h3>
<pre><code class="language-javascript">const myModule = require(&#39;./my-module&#39;);
console.log(myModule);</code></pre>
<ul>
<li>직접 작성한 모듈은 현재 파일과의 상대 디렉터리로 load한다.<ul>
<li>my-module이 .js 파일인 경우 해당 파일 load.</li>
<li>my-module이 디렉터리인 경우 my-module/index.js 파일 load.</li>
</ul>
</li>
</ul>
<h3 id="3-함수형-모듈">3) 함수형 모듈</h3>
<pre><code class="language-javascript">const myFunctionModule = require(&#39;./my-function-module&#39;);
console.log(myFunctionModule(name, age, nationality));</code></pre>
<ul>
<li>함수형 모듈은 load한 경우 모듈이 바로 실행되지 않는다.</li>
<li>필요한 시점에 load된 함수를 실행하여 모듈을 사용할 수 있다.</li>
</ul>
<h3 id="4-json-파일">4) json 파일</h3>
<pre><code class="language-javascript">// my-data.json 을 가지고 있음
const myData = require(&#39;./my-data&#39;);
console.log(myData);</code></pre>
<ul>
<li>require로 json 파일도 load 가능. object로 자동파싱</li>
</ul>
<br>
<br>



]]></description>
        </item>
        <item>
            <title><![CDATA[[Node.js] NPM 기초 알아보기]]></title>
            <link>https://velog.io/@yuj_125/Node.js-NPM-%EA%B8%B0%EC%B4%88-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@yuj_125/Node.js-NPM-%EA%B8%B0%EC%B4%88-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Mon, 18 Sep 2023 14:52:49 GMT</pubDate>
            <description><![CDATA[<h2 id="npm이란">NPM이란</h2>
<blockquote>
<p><strong>Node Package Manager</strong> 
Node.js 프로젝트를 관리하는 필수적인 도구 ( 온라인 저장소 + 커맨드라인 도구)</p>
</blockquote>
<br>

<h3 id="npm-온라인-저장소">NPM 온라인 저장소</h3>
<ul>
<li>수많은 오픈소스 라이브러리와 도구들이 업로드되는 저장소</li>
<li>필요한 라이브러리나 도구를 손쉽게 검색 가능</li>
<li>Node.js의 인기로 거대한 생태계를 보유</li>
</ul>
<br>

<h3 id="커맨드라인-도구">커맨드라인 도구</h3>
<p>프로젝트 관리를 위한 다양한 명령어를 제공</p>
<ul>
<li>저장소에서 라이브러리, 도구 설치</li>
<li>프로젝트 설정 / 관리</li>
<li>프로젝트 의존성 관리</li>
</ul>
<br>
<br>

<h2 id="npm-사용법">NPM 사용법</h2>
<h3 id="1-프로젝트-생성">1) 프로젝트 생성</h3>
<p><strong>$npm init</strong></p>
<ul>
<li>프로젝트 디렉터리를 생성하고 해당 디렉터리 안에서 npm init 명령어를 사용하면 몇 번의 질문을 통해 <code>package.json</code>이라는 파일을 만들어 주고 이 디렉터리는 Node.js 프로젝트가 된다.<blockquote>
<p><strong>package.json</strong> : 프로젝트 관련 정보들이 저장되는 파일. 이 파일을 직접 수정하거나 npm 명령어를 사용하여 프로젝트 정보를 수정할 있다.</p>
</blockquote>
<ul>
<li>dependencies - 어플리케이션 코드에 직접적으로 사용되는 모듈이다.</li>
<li>devDependencies - 어플리케이션 코드에는 사용되지 않지만 테스트/프로세스 재시작/린팅 작업들을 수행할 때 사용되는 모듈이다. (서포트 툴)</li>
</ul>
</li>
</ul>
<br>

<h3 id="2-1-의존성-관리하기">2-1) 의존성 관리하기</h3>
<p><strong>$npm install [package-name]</strong></p>
<ul>
<li>프로젝트 내에서 사용하는 라이브러리를 관리하는 방법이다.</li>
<li>프로젝트가 실행되기 위해 라이브러리에 의존하기 때문에 이러한 라이브러리들을 dependency(의존성)라고 한다.</li>
<li>npm install 명령어를 통해 프로젝트 의존성을 관리 할 수 있다.</li>
<li>npm install 명령어는 사용 방법에 따라 여러 용도로 사용 가능하다. <ul>
<li>npm i 를 축약형으로 사용 가능</li>
<li>의존성 추가, 의존성 내려받기, 개발용 의존성 추가, 전역 패기키 추가</li>
</ul>
</li>
<li>추가된 패키지는 package.json의 dependencies 안에 추가되며, node_modules 디렉터리에 저장됨.<blockquote>
<p>라이브러리 : 특정 기능을 수행하는 코드의 묶음
복잡한 기능을 직접 작성하지 않고, 다른 사람이 구현한 것을 사용하는 방법으로 <strong>Node.js 에서는 패키지라고도 부름</strong>.</p>
</blockquote>
</li>
</ul>
<br>

<p><strong>$npm install [package-name] --save-dev</strong></p>
<ul>
<li>npm은 개발용 의존성을 분리하여 관리할 수 있다.</li>
<li>개발용 의존성이란 배포 전까지만 사용하는 의존성이다. (ex. 유닛 테스트 라이브러리)</li>
<li>--save-dev 옵션을 이용하면 개발용 의존성을 추가할 수 있다. 개발용 의존성은 package.json의 devDependencies에 추가된다.</li>
</ul>
<blockquote>
<p><strong>package-lock.json</strong>
프로젝트에 의존성을 추가하면 snapshot 형태로 package-lock.json이라는 파일이 생성된다.
사용하고 있는 외부 모듈들의 상세한 스펙들이 저장된다.
프로젝트에 의존성을 추가하면 자동으로 ‘^최신버전’으로 추가가 되는데, 의존성 버전이 갑자기 변경되지 않도록, 설치된 버전을 고정하는 역할을 한다.</p>
</blockquote>
<blockquote>
<p><strong>의존성 버전 표기법</strong>
npm install [package-name]@[version] 으로 패키지 버전을 지정할 수 있다.</p>
</blockquote>
<p>~1.13.0 - 1.13.x 버전 설치
^1.13.0 - 1.x.x 버전 설치, 가장 왼쪽의 0이 아닌 버전을 고정.
0.13.0 – 0.13.0 버전만 설치</p>
<br>

<h3 id="2-2-의존성-내려받기">2-2) 의존성 내려받기</h3>
<p><strong>$npm install</strong></p>
<ul>
<li>기본적으로 node_modules 디렉터리는 코드 관리나 배포 시에 업로드 하지 않다. 의존성이 많아지면 용량이 너무 커지는 것과, 운영체제별로 실행되는 코드가 다른 경우가 존재하기 때문이다.</li>
<li>npm install 명령어를 아무 옵션 없이 사용하면 package.json 에 정의된 dependencies와 devDependencies의 의존성을 node_modules 디렉터리에 내려받음.<br>


</li>
</ul>
<p><strong>$npm install --production</strong></p>
<ul>
<li>프로젝트를 배포할 때에는 개발용 의존성을 같이 포함할 필요가 없다.</li>
<li>package.json 의 dependencies만 node_modules에 내려받는다.<br>

</li>
</ul>
<p><strong>$npm install [package-name] --global</strong></p>
<ul>
<li>패키지를 전역 패키지 디렉터리에 내려받는다.</li>
<li>주로 프로젝트에 종속되지 않는 커맨드라인 도구들을 전역 패키지로 추가해서 사용한다.
Ex) express-generator, pm2<br>

</li>
</ul>
<blockquote>
<p><strong>로컬 패키지와 전역 패키지</strong>
<strong>로컬 패키지</strong> : package.json 에 선언되어 있고, node_modules에 저장된 패키지
<strong>전역 패키지</strong> : npm install -g 를 통해 내려받아, 전역 패키지 저장소에 저장된 패키지</p>
</blockquote>
<p>✔ 전역 패키지도 프로젝트에서 사용할 수 있으나, 프로젝트의 의존성이 package.json 내에 명시적으로 선언되어 있는 것이 프로젝트 관리의 좋은 방향이다.</p>
<br>

<h3 id="2-3-의존성-삭제하기">2-3) 의존성 삭제하기</h3>
<p>**    $npm remove [package-name]**</p>
<ul>
<li>의존성 패키지를 삭제할 수 있다.</li>
<li>package.json의 dependencies와 devDependencies에서 삭제하고 node_modules에서도 삭제한다.</li>
</ul>
<br>

<h3 id="3-스크립트-실행하기">3) 스크립트 실행하기</h3>
<ul>
<li>스크립트란 간단한 동작을 수행하는 코드로 package.json의 scripts에 선언된 스크립트를 npm run [script-name] 명령어로 실행할 수 있다.</li>
<li>npm script 내에선 의존성 패키지를 사용할 수 있다.</li>
</ul>
<pre><code class="language-javascript">// 실행
$ npm run say-hi
&quot;hi&quot;

// package.json
{
    …
    &quot;scripts&quot;: {
        &quot;say-hi&quot;: &quot;echo \&quot;hi&quot;\&quot;
    },
    …
}
</code></pre>
<ul>
<li>npm 스크립트에는 run을 제외하고 사용할 수 있는 주요 스크립트들이 있다.<ul>
<li>test - 코드 유닛 테스트 등에 사용</li>
<li>start - 프로젝트 실행</li>
<li>stop - 프로젝트 종료</li>
</ul>
</li>
<li>run을 제외하고 사용할 수 있을 뿐, npm 내부적으로 코드를 제공해 주는 것은 아니다.</li>
</ul>
<br>
<br>

<table>
<thead>
<tr>
<th align="center">명령어</th>
<th align="center">의미</th>
<th align="center">주요 파일/디렉터리</th>
<th align="center">의미</th>
</tr>
</thead>
<tbody><tr>
<td align="center">npm init</td>
<td align="center">프로젝트 생성</td>
<td align="center">node_modules</td>
<td align="center">프로젝트 의존성 저장 디렉터리</td>
</tr>
<tr>
<td align="center">npm install</td>
<td align="center">의존성 추가</td>
<td align="center">package.json</td>
<td align="center">프로젝트 관리 (버전, 의존성, 스크립트, …)</td>
</tr>
<tr>
<td align="center">npm remove</td>
<td align="center">의존성 삭제</td>
<td align="center">package-lock.json</td>
<td align="center">의존성 버전 확인</td>
</tr>
<tr>
<td align="center">npm run</td>
<td align="center">스크립트 실행</td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
<br>
<br>

<h2 id="npm-레지스트리-npm-registry">npm 레지스트리 (npm Registry)</h2>
<ul>
<li>패키지를 업로드하는 공간 </li>
<li>Public/Private </li>
<li>개발자들은 registry로부터 필요한 서드파티 패키지를 받아 본인 코드에서 사용할 수 있다.</li>
<li>회사 내부에서만 사용하는 패키지는 private registry에 올려서 관리하는 경우가 많다.</li>
<li>*<em>NPM(inc.), GitHub Package Registry, JFrog, GitLab Package Registry *</em></li>
<li>소스 코드 자체를 관리하는 git repository와는 다르다. 완성된 제품을 저장하는 저장소에 가깝다. </li>
</ul>
<br>


<hr>
<br>

<h2 id="npx">NPX</h2>
<p><strong>npm 패키지를 설치하지 않고 사용할 수 있게 해주는 도구.</strong></p>
<ul>
<li><p>프로젝트에 추가하거나 전역 패키지로 추가하지 않고, npx를 이용하여 바로 실행할 수 있다.</p>
</li>
<li><p>npx를 사용하면 Node.js의 특정 버전을 사용하여 js 파일을 실행할 수 있다.</p>
</li>
<li><p>프로젝트의 Node.js 버전 별 실행환경을 확인할 때 유용하다.</p>
</li>
<li><p>npx를 이용하면 gist 코드를 다운받지 않고 바로 실행 가능하지만 git이 설치되어 있어야 한다. (gist는 github에 등록된 간단한 코드)</p>
</li>
<li><p>온라인상의 코드는 어떤 위험이 있을지 모르기에 코드를 잘 확인하고 실행해야 한다.</p>
</li>
</ul>
<br>
<br>




]]></description>
        </item>
        <item>
            <title><![CDATA[[TypeScript] 인터페이스 정의 및 활용법]]></title>
            <link>https://velog.io/@yuj_125/TypeScript-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%A0%95%EC%9D%98-%EB%B0%8F-%ED%99%9C%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@yuj_125/TypeScript-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%A0%95%EC%9D%98-%EB%B0%8F-%ED%99%9C%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Fri, 08 Sep 2023 07:09:12 GMT</pubDate>
            <description><![CDATA[<h2 id="인터페이스">인터페이스</h2>
<ul>
<li><p>일반적으로 변수, 함수, 클래스에 타입 체크를 위해 사용된다.</p>
</li>
<li><p>직접 인스턴스를 생성할 수 없고 모든 메소드가 추상 메소드이다.</p>
</li>
<li><p>추상 클래스의 추상 메소드와 달리 abstract 키워드는 사용할 수 없다.</p>
</li>
<li><p>ES6는 인터페이스를 지원하지 않지만 TypeScript는 인터페이스를 지원한다.</p>
</li>
<li><p>인터페이스를 타입으로 가지는 값은 인터페이스의 구조를 그 값으로 가지도록 강제된다.</p>
</li>
<li><p>인터페이스 이름은 보통 대문자를 사용한다.</p>
</li>
<li><p>상호 간에 정의한 약속이나 규칙을 의미하고 다음과 같은 범주에 대해 계약을 정의한다.
_ 1) 객체의 스팩(속성과 속성의 타입)
  2) 함수의 파라미터
  3) 함수의 스펙(파라미터, 반환 타입 등)
  4) 배열과 객체를 접근하는 방식
  5) 클래스_</p>
 <br>    
 <br>



</li>
</ul>
<pre><code class="language-javascript">    interface personAge {
            readonly name: string;    // readonly
            age?: number;            // Optional Properties
        }

        function logAge(obj: personAge) {    //error
            console.log(obj.name);
        }

        let person = {name:&#39;Capt&#39;};    
        logAge(person);</code></pre>
<blockquote>
<p> <strong>Optional Properties</strong> </p>
</blockquote>
<ul>
<li>속성의 끝에 ?를 붙이면 속성 생략 가능, 인터페이스에 속하지 않는 프로퍼티의 사용을 방지하면서, 사용가능한 프로퍼티를 기술할 때 사용한다. </li>
<li>객체 안의 몇 개의 프로퍼티만 채워 함수에 전달하는 &quot;option bags&quot;같은 패턴에 유용하다.</li>
</ul>
<blockquote>
<p><strong>readonly</strong></p>
</blockquote>
<ul>
<li>처음 생성할 때만 값을 할당하고 이후에는 변경할 수 없는 속성</li>
<li>객체를 const로 지정하면 객체의 값은 변경이 가능하다. const 변수는 재할당만 막아주는 것이지 객체 속성을 바꾸는 것까지 관여하지 않는다.</li>
<li>readonly는 객체의 속성을 변경하지 못하게 막고 객체가 처음 생성될 때만 값 설정이 가능하고 이후 수정이 불가능하다.</li>
<li>단, 컴파일시 에러가 발생하는 것이지 변환된 자바스크립트 파일에서는 변경된다.</li>
</ul>
   <br>    
   <br>

<h2 id="인터페이스-장점">인터페이스 장점</h2>
<p>1) extends로 복사 가능</p>
<pre><code class="language-javascript"> interface A extends B {
                key : type;
            }</code></pre>
<ul>
<li>type alias는 extends가 안되고 &amp; 기호로 intersection할 수 있다 (interface도 intersection 가능)</li>
<li>extends 쓸 때 타입끼리 중복속성이 발견될 경우 에러가 발생하는데 &amp;을 쓸 경우 에러가 안날 수도 있다.</li>
</ul>
<p>2) 타입이름 중복선언</p>
<pre><code class="language-javascript">        interface Animal { 
            name :string 
        } 
        interface Animal { 
            legs :number 
        }</code></pre>
<ul>
<li>타입이름 중복선언을 허용해주며 중복시 extends 한것과 동일하게 작용한다.</li>
<li><blockquote>
<p>type 선언을 자주 쓰는 외부 라이브러리 이용시 type 선언을 덮어쓰기, override하기 편함</p>
</blockquote>
</li>
</ul>
   <br>    
   <br>

<h2 id="interface-types">interface types</h2>
<ul>
<li>TypeScript에서 인터페이스는 함수, 클래스에서 사용할 수 있다.</li>
</ul>
<h3 id="함수">함수</h3>
<ul>
<li>자바스크립트 객체가 가질 수 있는 넓은 범위의 형태를 기술한다.</li>
<li>프로퍼티로 객체를 기술하는 것 외에도 인터페이스는 함수 타입을 설명한다.</li>
</ul>
<pre><code class="language-javascript">interface SearchFunc { 
    (source: string, subString: string): boolean 
}

// 변수로 직접 함수 값이 할당되었기 때문에 인수 타입 생략가능
// TypeScript의 문맥상 타이핑 (contextualtyping)이 인수 타입 추론

let mySearch: SearchFunc
mySearch = function (src, sub) { 
    let result = src.search(sub); 
    return result &gt; -1;
}</code></pre>
<br>

<h3 id="클래스">클래스</h3>
<ul>
<li>클래스가 특정 통신 프로토콜을 충족하도록 명시적으로 강제한다.</li>
<li>c#과 Java와 같은 언어에서 일반적으로 인터페이스를 사용하는 방법과 동일하다.</li>
</ul>
<pre><code class="language-javascript">interface Animal {
    makeSound(): void
}

class Dog implements Animal {
    makeSound(): void {
        console.log(&quot;멍멍&quot;); 
    }
}
</code></pre>
<br>

<h3 id="interface-확장">interface 확장</h3>
<ul>
<li>클래스와 마찬가지로 인터페이스도 인터페이스 간의 확장이 가능하다.</li>
</ul>
<pre><code class="language-javascript">interface Animal {
    makeSound(): void
}

interface Dog extends Animal {
    speed: number
}

class Bulldog implements Dog {
    speed: number
    makeSound(): void {
        console.log(&quot;멍멍&quot;);
    }
}</code></pre>
<br>

<h3 id="hybrid-type">hybrid type</h3>
<ul>
<li>자바스크립트의 유연하고 동적인 타입 특성에 따라 인터페이스 역시 여러 가지 타입을 조합할 수 있다.</li>
<li>함수 타입이면서 객체 타입을 정의할 수 있는 인터페이스도 구현할 수 있다.</li>
</ul>
<pre><code class="language-javascript">interface Counter { 
    (start: number): string
    interval: number
    reset(): void
}

function getCounter(): Counter {
    let counter = function (start: number) {} as Counter
    counter.interval = 123; 
    counter.reset = function () {}
    return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;</code></pre>
<br>
<br>

<h2 id="interface를-활용한-디자인-패턴">interface를 활용한 디자인 패턴</h2>
<ul>
<li>객체가 할 수 있는 행위들을 전략으로 만들어 두고 동적으로 행위의 수정이 필용한 경우 전략을 바꾸는 것만으로 수정이 가능하도록 만든 패턴이다.</li>
</ul>
<br>
<br>

<hr>
<br>

<h2 id="참고자료">참고자료</h2>
<ul>
<li><a href="https://ahnheejong.gitbook.io/ts-for-jsdev/04-interface-and-class/interface-basics">4.1 인터페이스 기초</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Typescript] 타입스크립트의 기초]]></title>
            <link>https://velog.io/@yuj_125/Typescript-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@yuj_125/Typescript-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Wed, 06 Sep 2023 08:01:02 GMT</pubDate>
            <description><![CDATA[<h2 id="타입스크립트-사용-이유">타입스크립트 사용 이유</h2>
<ul>
<li>동적 타입을 정적으로 선언가능</li>
<li>타입 유추를 통한 타입 제어가 가능</li>
<li>컴파일 시점에 오류를 포착</li>
<li>자바스크립트에서 찾을 수 없는 추가 코드 기능을 제공</li>
</ul>
<br>
<br>

<h2 id="타입스크립트의-type">타입스크립트의 type</h2>
<h3 id="1-기본-자료형">1) 기본 자료형</h3>
<ul>
<li>object와 reference 형태가 아닌 실제 값을 저장하는 자료형</li>
<li>기본 자료형 내장 함수를 사용 가능한 것은 자바스크립트 처리 방식 덕분</li>
<li>종류 : <strong>string, boolean, number, null, undefined, symbol</strong></li>
</ul>
<h3 id="2-참조-자료형">2) 참조 자료형</h3>
<ul>
<li>객체, 배열, 함수 등과 같은 Object형식의 타입</li>
<li>메모리에 값을 주소로 저장하고 출력시 메모리 주소와 일치하는 값을 출력</li>
<li>종류 : <strong>object, array, function</strong></li>
</ul>
<h3 id="3-추가-제공-자료형">3) 추가 제공 자료형</h3>
<ul>
<li>typescript에서 개발자의 편의를 위해 추가로 제공하는 타입</li>
<li>종류 : <strong>tuple, enum, any, void, never</strong></li>
</ul>
<br>
<br>

<h2 id="타입-추론-type-inference">타입 추론 type inference</h2>
<blockquote>
<p> 타입스크립트에서는 타입 표기가 없는 경우 코드를 읽고 분석하여 타입을 유추할 수 있음</p>
</blockquote>
<br>
<br>

<h2 id="타입-명시">타입 명시</h2>
<ul>
<li>변수를 선언할 때 변수값의 타입을 명시함으로써 변수 값의 데이터 타입을 지정하는것    (변수명 : 타입)<pre><code class="language-javascript">let x : string = &#39;hello&#39;;    // 문자일 경우
let arr : string[] = [&#39;kim&#39;, &#39;lee&#39;];    //배열일 경우        
let member : {mem1:string, mem2:string} = {        //객체일 경우
mem1:&#39;kim&#39;, 
mem2:&#39;lee&#39;
};    </code></pre>
</li>
<li>string, number, boolean, array, undefined, null 등</li>
<li>변수 생성시 타입스크립트가 타입을 자동으로 부여, 간단한 변수들은 타입을 생략</li>
</ul>
<br>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[Node.js 기초 맛보기]]></title>
            <link>https://velog.io/@yuj_125/Node.js-%EA%B8%B0%EC%B4%88-%EB%A7%9B%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@yuj_125/Node.js-%EA%B8%B0%EC%B4%88-%EB%A7%9B%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Tue, 05 Sep 2023 12:06:11 GMT</pubDate>
            <description><![CDATA[<h2 id="nodejs의-기초">Node.js의 기초</h2>
<h2 id="배경">배경</h2>
<ul>
<li>단방향 통신 위주였던  웹이 사용자와 상호작용을 하게 되면서 고성능의 javascript가 필요해지게 되고 V8엔진이 등장</li>
<li>고성능 javascript가 실행 가능하게 되고 브라우저 외부에서 사용할 수 있도록 발전한 것이 Node.js
=&gt; <strong>자바스크립트를 어느 환경에서나 실행할 수 있게 해주는 실행기</strong></li>
</ul>
<br>
<br>

<h2 id="특징">특징</h2>
<ul>
<li><p><strong>크로스 플랫폼</strong> 실행
✔  컴퓨터 프로그램, 운영 체제, 컴퓨터 언어, 프로그래밍 언어, 컴퓨터 소프트웨어 등이 여러 종류의 컴퓨터 플랫폼에서 동작할 수 있다는 것을 뜻하는 용어</p>
</li>
<li><p>웹 내부에 제한 되지 않는 동작</p>
</li>
<li><p>다양한 어플리케이션 개발</p>
</li>
<li><p>싱글 쓰레드로 한 번에 한 가지 동작만 실행 기능하다</p>
<blockquote>
<p>장점 - 쓰레드가 늘어나지 않기 때문에 리소스 관리에 효율적이고 경쟁상태나 교착 상태의 위험이 낮음
단점 - 쓰레드 기반의 작업들의 효율이 떨어짐 Ex) CPU 연산 작업
  =&gt; Node.js 는 비동기 동작으로 쓰레드 기반의 작업을 최소화합니다.</p>
</blockquote>
</li>
<li><p>이벤트 기반이다.</p>
<blockquote>
<p>비동기 동작의 완료를 처리하는 방법으로 비동기 방식은 특정 동작을 실행한 후, 해당 동작을 전혀 신경 쓰지 않는다.
대신 해당 동작이 완료될 경우 실행할 함수를 미리 등록하고 비동기 동작이 완료가 되면 미리 등록된 함수를 실행한다.</p>
</blockquote>
</li>
</ul>
<br>
<br>

<h2 id="nodejs-api">Node.js API</h2>
<p>대표적인 API (fs, path, process, console, http/https, crypto, timers, stream)</p>
<h3 id="1-fs">1) fs</h3>
<ul>
<li>파일 시스템에 접근할 수 있도록 해주는 모듈 </li>
<li>파일 생성 &amp; 읽기 &amp; 쓰기 </li>
<li>디렉토리 생성 &amp; 삭제 </li>
<li>파일 &amp; 디렉토리 정보 읽기 </li>
<li>기타 여러 가지 파일 시스템 관련된 작업이 가능</li>
<li>비동기적으로 파일을 읽기 위한 방법</li>
</ul>
<pre><code class="language-javascript">var fs = require(&#39;fs&#39;);
                                                        // 파일 읽기
var text = fs.readFileSync(&#39;text.txt&#39;, &#39;utf8&#39;);            // 동기적 읽기
console.log(text);

fs.readFile(&#39;text.txt&#39;, &#39;utf8&#39;, function(err, data) {    // 비동기적 읽기
    console.log(data);
});

var data = &#39;Hello FileSystem&#39;;                            // 파일 쓰기

fs.writeFile(&#39;text.txt&#39;, data, &#39;utf8&#39;, function(err) {
    console.log(&#39;비동기적 파일 쓰기 완료&#39;);
});

fs.writeFileSync(&#39;text2.txt&#39;, data, &#39;utf8&#39;);
console.log(&#39;동기적 파일 쓰기 완료&#39;);
</code></pre>
<h3 id="2-path">2) path</h3>
<ul>
<li>파일과 디렉토리의 경로를 위한 모듈</li>
<li>복잡한 파일 시스템의 경로 체계(절대 경로, 상대 경로)를 위한 모듈</li>
</ul>
<pre><code class="language-javascript">const path = require(&#39;path&#39;);

path.dirname(&#39;/foo/bar/baz/asdf/quux&#39;);             //디렉터리 이름 반환
// &#39;/foo/bar/baz/asdf&#39; 

path.isAbsolute(&#39;//server&#39;);                        // 절대 경로인지 확인
// true

path.join(&#39;/foo&#39;, &#39;bar&#39;, &#39;baz/asdf&#39;, &#39;quux&#39;, &#39;..&#39;);    //경로 설정
// Returns: &#39;/foo/bar/baz/asdf&#39;</code></pre>
<h3 id="3-process">3) process</h3>
<ul>
<li>현재 실행 중인 Node.js 프로세스 및 실행 환경에 관련된 데이터 제공</li>
<li>환경 변수, CPU 아키텍처, 현재 Node.js 프로세스가 실행된 경로, 프로세스 ID 등의 다양한 정보 확인 가능</li>
</ul>
<pre><code class="language-javascript">process.env;           // 컴퓨터 환경과 관련된 정보를 가진 객체
process.version;       // node.js의 버전
process.versions;      // node.js와 연관된 프로그램들의 버전을 가진 객체
process.arch;          // 프로세서의 아키텍처(arm/ia32/x64)
process.platform;      // 플랫폼(win32/linux/sunos/freebsd/darwin)
process.memoryUsage(); // 메모리 사용 정보를 가진 객체
process.uptime();      // 현재 프로그램이 실행된 시간
process.exit();           // 프로세스 강제 종료</code></pre>
<h3 id="4-timers">4) timers</h3>
<ul>
<li>익숙한 setTimeout, setInterval이 담겨져있는 모듈
setTimeout( 콜백함수, 밀리초 ) : 주어진 밀리초이후에 콜백 함수를 실행
setInterval( 콜백함수, 밀리초 ) : 주어진  밀리초마다 콜백 함수를 실행
setImmediate( 콜백함수 ) : 콜백 함수를 즉시 실행</li>
</ul>
<hr>
<h2 id="참고자료">참고자료</h2>
<ul>
<li><a href="https://opentutorials.org/module/938/7373">fs 모듈(File System)</a></li>
<li><a href="https://nodejs.org/api/path.html">Node.js v20.6.0 documentation</a></li>
<li><a href="https://opentutorials.org/module/938/7189">process 객체</a></li>
<li><a href="https://hakgu.tistory.com/8">node.js 타이머 함수 사용해보기! ( setTimeout, setInterval, setImmediate )</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 동적 프로그래밍이란?]]></title>
            <link>https://velog.io/@yuj_125/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%8F%99%EC%A0%81-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@yuj_125/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%8F%99%EC%A0%81-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Thu, 31 Aug 2023 09:38:07 GMT</pubDate>
            <description><![CDATA[<h2 id="📝-동적-프로그래밍이란">📝 동적 프로그래밍이란?</h2>
<blockquote>
<p> 특정 범위까지의 값을 구하기 위해서 그것과 다른 범위까지의 값을 이용하여 효율적으로 값을 구하는 알고리즘 기법이다.</p>
</blockquote>
<br>
<br>

<h2 id="🎯-동적-프로그래밍의-특징">🎯 동적 프로그래밍의 특징</h2>
<ul>
<li><strong>최적 부분 구조</strong> 문제에 효과적이다.
✔ 최적 부분 구조란 문제의 최적 해결 방법이 부분 문제에 대한 최적 해결 방법으로 구성된 구조를 의미한다.</li>
<li>동일한 문제를 여러번 구해야 하는 문제는 <strong>메모이제이션(Memoization)</strong> 기법으로 해결한다.
✔ 메모이제이션(memoization)은 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술이다. 동적 계획법의 핵심이 되는 기술이다.</li>
</ul>
<br>

<hr>
<br>


<h3 id="동적-프로그래밍-조건">동적 프로그래밍 조건</h3>
<ol>
<li><strong>Simple subproblems</strong> - 큰 문제를 작은 문제로 나눌 수 있어야 한다.</li>
<li><strong>Optimal substructure</strong> - 최적의 해를 찾는 구조를 만들 수 있어야 한다.</li>
<li><strong>Overlapping problems</strong> - 작은 문제들이 중복되어야 한다.</li>
</ol>
<br>

<h3 id="동적-프로그래밍-문제-해결-방법">동적 프로그래밍 문제 해결 방법</h3>
<h4 id="1-top-down">1. Top Down</h4>
<ul>
<li>탑다운 방식은 말 그대로 위에서 아래로(큰 문제에서 작은 문제로) 해결해 나가는 방식이다.</li>
<li>재귀 알고리즘을 사용하는 방식이다.</li>
<li>메모이제이션 기법은 탑다운 방식일 때 사용된다.</li>
</ul>
<h4 id="2-bottom-up">2. Bottom Up</h4>
<ul>
<li>바텀업 방식은 단순히 반복문을 통해서 가장 작은 문제에서 해결해야 하는 문제에 도달할 때까지 반복한다.</li>
</ul>
<br>

<h3 id="동적-프로그래밍-과정">동적 프로그래밍 과정</h3>
<ol>
<li>최적해를 구할 수 있는 구조를 정의한다.</li>
<li>최적해의 값을 재귀적으로 정의한다.</li>
<li>캐싱을 사용하는 탑다운 방식이나 바텀업 방식으로 값을 계산한다.</li>
<li>계산된 값으로 최적의 해를 구한다.</li>
</ol>
<br>

<hr>
<br>

<h2 id="참고자료">참고자료</h2>
<ul>
<li><a href="https://namu.wiki/w/%EB%8F%99%EC%A0%81%20%EA%B3%84%ED%9A%8D%EB%B2%95">동적 계획법 </a></li>
<li><a href="https://fomaios.tistory.com/entry/Algorithm-%EB%8F%99%EC%A0%81-%EA%B3%84%ED%9A%8D%EB%B2%95Dynamic-Programming%EC%9D%B4%EB%9E%80">[Algorithm] 동적 계획법(Dynamic Programming)이란?</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 재귀(Recursion)란?]]></title>
            <link>https://velog.io/@yuj_125/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9E%AC%EA%B7%80Recursion%EB%9E%80</link>
            <guid>https://velog.io/@yuj_125/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9E%AC%EA%B7%80Recursion%EB%9E%80</guid>
            <pubDate>Wed, 30 Aug 2023 16:36:36 GMT</pubDate>
            <description><![CDATA[<h2 id="📝-재귀-알고리즘이란">📝 재귀 알고리즘이란?</h2>
<blockquote>
<p>하나의 함수에서 자기 자신을 다시 호출하여 작업을 수행하는 알고리즘이다.</p>
</blockquote>
<br>

<h4 id="재귀-함수의-구조">재귀 함수의 구조</h4>
<pre><code class="language-javascript">function recurse() {
    // function code
    recurse();
    // function code
}

recurse();</code></pre>
<br>
<br>

<h2 id="🎯-재귀-함수의-특징">🎯 재귀 함수의 특징</h2>
<ul>
<li>스택처럼 호출한 함수를 쌓았다가 종료 조건을 만나면 위에서부터 하나씩 꺼내 처리하는 방식이다.</li>
<li>함수 호출을 중지하는 조건이 있어야 한다.</li>
<li>적용 예시) 1부터 n까지의 합 / !팩토리얼 / 최대공약수 문제 / 파보나치 수열 구하기 등</li>
</ul>
<br>

<hr>
<br>

<h3 id="📈-재귀-함수의-장점">📈 재귀 함수의 장점</h3>
<ul>
<li>코드의 가독성이 높아진다. 재귀적 호출을 통해 코드를 간결하게 작성할 수 있다.</li>
<li>일부 알고리즘에서는 반복문을 사용하는 것보다 재귀 함수를 사용하는 것이 더 직관적이다.</li>
</ul>
<br>

<h3 id="📉-재귀-함수의-단점">📉 재귀 함수의 단점</h3>
<ul>
<li>함수를 호출할 때마다 스택에 새로운 프레임을 생성한다. 스택이 너무 깊어지게 되면 스택 오버플로우가 발생할 수 있다.</li>
<li>함수의 호출이 반복적으로 일어나기 때문에 일반적으로 반복문을 사용하는 것보다 느리다.</li>
</ul>
<br>

<hr>
<br>

<h2 id="참고자료">참고자료</h2>
<ul>
<li><a href="https://www.programiz.com/javascript/recursion">자바스크립트 재귀</a></li>
<li><a href="https://medium.com/@sunnkis/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EC%9E%AC%EA%B7%80-8d96633be4cd">[데이터 구조] 재귀(recursive) 란?</a></li>
<li><a href="https://adjh54.tistory.com/194">[Java/알고리즘] 재귀 함수(Recursion Function) 이해하기</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>