<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>surra7.log</title>
        <link>https://velog.io/</link>
        <description>개발자 준비생</description>
        <lastBuildDate>Mon, 15 Apr 2024 15:32:06 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>surra7.log</title>
            <url>https://velog.velcdn.com/images/surra7/profile/df3cd380-e86a-442c-93c2-46fe68c52a74/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. surra7.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/surra7" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[랜딩 페이지 미니 프로젝트]]></title>
            <link>https://velog.io/@surra7/%EB%9E%9C%EB%94%A9-%ED%8E%98%EC%9D%B4%EC%A7%80-%EB%AF%B8%EB%8B%88-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@surra7/%EB%9E%9C%EB%94%A9-%ED%8E%98%EC%9D%B4%EC%A7%80-%EB%AF%B8%EB%8B%88-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Mon, 15 Apr 2024 15:32:06 GMT</pubDate>
            <description><![CDATA[<h1 id="인터렉티브한-랜딩-페이지-만들기---미니-프로젝트">인터렉티브한 랜딩 페이지 만들기 - 미니 프로젝트</h1>
<blockquote>
<p>마침 봄이니까 벚꽃 축제 안내 랜딩 페이지를 만들어보기로 했다. React, css, module.css를 사용하였고 netlify로 배포하였다.</p>
</blockquote>
<h3 id="contents">Contents</h3>
<ol>
<li>주요 기능들
 1.1 ScrollTrigger
 1.2 아래로 내려오는 요소
 1.3 네비게이션 메뉴</li>
<li>에러 해결</li>
<li>개선할 점</li>
</ol>
<hr />

<h2 id="1-주요-기능들">1. 주요 기능들</h2>
<h3 id="1-1-scrolltrigger">1-1. ScrollTrigger</h3>
<p>인터렉티브한 요소를 넣기 위해 스크롤하는것에 따라 요소를 움직이게 만드는 gsap의 scrollTrigger 라이브러리를 사용했다.</p>
<p>우선 gsap을 설치</p>
<pre><code class="language-bash">npm i gsap
npm i @gsap/react</code></pre>
<p>import로 가져온뒤 ScrollTrigger를 등록</p>
<pre><code class="language-js">import { useGSAP } from &quot;@gsap/react&quot;
import { ScrollTrigger } from &quot;gsap/ScrollTrigger&quot;
import gsap from &quot;gsap&quot;

gsap.registerPlugin(ScrollTrigger);</code></pre>
<p>사용법은 써보면 어렵진 않다. useEffect랑 비슷한 느낌. className이나 id로 gsap을 적용할 요소를 선택</p>
<pre><code class="language-js">useGSAP(() =&gt; {
    gsap.from(&quot;#timeline&quot;, {
      scrollTrigger: {
        trigger: &quot;#timeline&quot;, // 요소가 뷰포트에 드러나는 순간부터 애니메이션이 작동
        start: &quot;top bottom&quot;, // 애니메이션 시작지점, 마커 시작지점
        end: &quot;bottom center&quot;, // 애니메이션 종료지점, 마커 종료 지점
        toggleActions: &quot;play complete none reset&quot;,
      },
      yPercent: 100,
      opacity: 0,
      duration: 2,
    });

    ScrollTrigger.refresh();
  }, []);</code></pre>
<ul>
<li><strong><em>start: &quot;top bottom&quot;</em></strong> : 마커의 시작지점인 bottom과 요소 시작지점인 top이 만날때 애니메이션이 사작됨</li>
<li><strong><em>end: &quot;bottom center&quot;</em></strong> : 마커의 종료지점인 center와 요소의 종료지점인 bottom이 만날때 애니메이션이 종료됨</li>
</ul>
<p><img src="https://velog.velcdn.com/images/surra7/post/935f04b8-a364-4c34-90da-59379824faa3/image.gif" alt=""></p>
<br/>

<h3 id="1-2-아래로-내려오는-요소">1-2. 아래로 내려오는 요소</h3>
<p>FAQ와 공지사항을 만들때 질문을 누르면 답변이 숨겨져있다가 아래로 내려오면서 보이도록 구현하고 싶었다.</p>
<p>처음에는 <code>grid-template-rows: 0fr</code>로 주어 안보이게 함
클릭한 버튼의 id가 일치하는 경우 display 속성을 주어 1fr로 바꾸어서 보이도록 함
이렇게 하면 전체 요소의 크기가 자동으로 늘어나면서 다른 요소에 영향을 안미치면서 나타나게 할 수 있음</p>
<pre><code class="language-js">// js
&lt;div
   className={`${styles.answer} ${
      clickedId === 1 ? `${styles.display}` : &quot;&quot;
   }`}
&gt;&lt;/div&gt;</code></pre>
<pre><code class="language-css">/* css */
.answer {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.3s, padding 0.3s;
  padding: 0;
  will-change: grid-template-rows, padding;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: #333333;
}

.display {
  padding: 16px 0 0;
  grid-template-rows: 1fr;
}</code></pre>
<p><img src="https://velog.velcdn.com/images/surra7/post/2e721c91-fb01-49ed-aa2d-769158f8db16/image.gif" alt=""></p>
<br />

<h3 id="1-3-네비게이션-메뉴">1-3. 네비게이션 메뉴</h3>
<p><code>element.scrollIntoView</code>를 사용하면 스크롤을 원하는 위치로 이동시킬 수 있는데 이것을 이용하여 특정 요소로 바로 이동할 수 있는 hook을 만들어 사용함</p>
<pre><code class="language-js">// hook
function useMoveScroll() {
  const element = useRef(null);
  const onMoveToElement = () =&gt; {
    element.current?.scrollIntoView({ behavior: &quot;smooth&quot;, block: &quot;start&quot; });
  };
  return { element, onMoveToElement };
}</code></pre>
<pre><code class="language-js">// js
const navigationTabs = {
    0: useMoveScroll(&quot;행사 일정&quot;),
    1: useMoveScroll(&quot;마켓 신청&quot;),
    2: useMoveScroll(&quot;공지사항&quot;),
    length: 3,
  };

&lt;div
  onClick={navigationTabs[2].onMoveToElement}&gt;
    공지사항 // 이걸 누르면
&lt;/div&gt;

&lt;section ref={navigationTabs[2].element}&gt;
   &lt;Notice /&gt; // 이곳으로 이동
&lt;/section&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/surra7/post/80094447-e1b9-4dc7-8236-798e12b5e224/image.gif" alt=""></p>
<hr />

<h2 id="2-에러-해결">2. 에러 해결</h2>
<h3 id="2-1-환경-변수">2-1. 환경 변수</h3>
<p><a href="https://velog.io/@surra7/%EB%A6%AC%EC%95%A1%ED%8A%B8-env-%ED%99%98%EA%B2%BD-%EB%B3%80%EC%88%98-%EC%84%A4%EC%A0%95">env 환경 변수 설정에 관련한 에러</a></p>
<h3 id="2-2-netlify-배포">2-2. netlify 배포</h3>
<p><a href="https://velog.io/@surra7/netlify-%EB%B0%B0%ED%8F%AC-%EC%98%A4%EB%A5%98-%ED%99%98%EA%B2%BD%EB%B3%80%EC%88%98-%EC%84%A4%EC%A0%95-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EB%8F%84%EB%A9%94%EC%9D%B8">netlify 배포 후 발생한 에러</a></p>
<hr />


<h2 id="3-개선할-점">3. 개선할 점</h2>
<h3 id="css">css</h3>
<p>원래는 tailwindcss를 쓰려고 했으나 tailwindcss가 익숙하지 않아서 결국 그냥 css와 혼용해서 쓰다가 css 중첩문제로 module.css까지 쓰게 되었다. 그야말로 혼돈의 장.. 나중에 꼭 리펙토링해서 정리해야겠다.</p>
<h3 id="버튼-리스트-정리">버튼 리스트 정리</h3>
<p>FAQ와 공지사항 부분을 만들때 선택한 버튼의 요소를 구분하기 위해  <code>clickedId === 1 ? :</code> 이런식으로 하드코딩을 했다. 후에 이 부분 정리할 필요가 있을것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[netlify 배포 오류 - 환경변수 설정, 카카오 도메인]]></title>
            <link>https://velog.io/@surra7/netlify-%EB%B0%B0%ED%8F%AC-%EC%98%A4%EB%A5%98-%ED%99%98%EA%B2%BD%EB%B3%80%EC%88%98-%EC%84%A4%EC%A0%95-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EB%8F%84%EB%A9%94%EC%9D%B8</link>
            <guid>https://velog.io/@surra7/netlify-%EB%B0%B0%ED%8F%AC-%EC%98%A4%EB%A5%98-%ED%99%98%EA%B2%BD%EB%B3%80%EC%88%98-%EC%84%A4%EC%A0%95-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EB%8F%84%EB%A9%94%EC%9D%B8</guid>
            <pubDate>Mon, 15 Apr 2024 15:04:31 GMT</pubDate>
            <description><![CDATA[<h3 id="문제-상황">문제 상황</h3>
<p>react 프로젝트를 netlify로 배포를 완료하였으나 링크에 접속하면 하얀화면만 나옴. 개발자 도구를 확인하니 카카오맵이 안불러와지는 것 같음
배포할 때 .env파일은 가져오지 않으므로 설정해놓은 환경변수를 불러오지 못하는 것 </p>
<h3 id="해결">해결</h3>
<p>netlify의 <strong>Environment variables</strong>에서 따로 환경변수 값을 넣어줘야함 </p>
<p><img src="https://velog.velcdn.com/images/surra7/post/08521f6e-c7c6-49e8-8684-f8bbd000ca00/image.jpg" alt=""></p>
<p>이렇게 하고 Deploys에서 Options -&gt; Retry with latest branch commit로 재배포</p>
<p>그런데도 하얀화면만 나옴</p>
<p>Kakao Developers에서 사이트 도메인 등록을 안해줬기 때문!
기존에 <code>https://localhost:3000</code>으로 되어있던 걸 배포된 url주소로 바꿔줌</p>
<p>이제야 사이트가 제대로 보임!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 env 환경 변수 설정]]></title>
            <link>https://velog.io/@surra7/%EB%A6%AC%EC%95%A1%ED%8A%B8-env-%ED%99%98%EA%B2%BD-%EB%B3%80%EC%88%98-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@surra7/%EB%A6%AC%EC%95%A1%ED%8A%B8-env-%ED%99%98%EA%B2%BD-%EB%B3%80%EC%88%98-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Mon, 15 Apr 2024 12:37:36 GMT</pubDate>
            <description><![CDATA[<h2 id="cra로-만든-리액트-프로젝트에-env-환경-변수-설정">cra로 만든 리액트 프로젝트에 env 환경 변수 설정</h2>
<h3 id="문제-상황">문제 상황</h3>
<p>카카오 맵 api를 사용하기 위해 api key를 환경 변수로 설정하여 사용하려고 했다. 
npm i dotenv로 dotenv를 설치하고 env로 환경 변수를 설정한 뒤 사용하였는데 에러가 발생했다.
찾아보니 create-react-app으로 리액트 프로젝트를 만들면 자동으로 env를 사용할 수 있도록 설정이 되어있다고 한다.</p>
<h3 id="해결">해결</h3>
<p>npm uninstall dotenv로 dotenv를 제거한다음 다시 환경 변수를 설정했다. cra에 내장된 env를 사용하려면 key값이 <strong>REACT_APP</strong>으로 시작해야 한다고 한다. ex) REACT_APP_KAKAO_API_KEY</p>
<p>jsx에서 사용하는 방법은 똑같이 <span style='background-color: #d6d8da'>process.env.REACT_APP_KAKAO_API_KEY</span> 이런식으로 사용하면 됨</p>
<p>하지만 카카오 맵 api를 사용하려면 index.html에 api 키값을 넣어줘야 했음. html에 env 환경변수를 사용하는 방법은 다음과 같이 환경변수를 %%로 감싸서 사용해야 한다. ex) <span style='background-color: #d6d8da'>%REACT_APP_KAKAO_API_KEY%</span></p>
<p><img src="https://velog.velcdn.com/images/surra7/post/f53582ad-2b70-4d88-8914-c4152e597978/image.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[02. Express]]></title>
            <link>https://velog.io/@surra7/02.-Express</link>
            <guid>https://velog.io/@surra7/02.-Express</guid>
            <pubDate>Tue, 26 Mar 2024 09:55:49 GMT</pubDate>
            <description><![CDATA[<h2 id="33-express란">33. Express란?</h2>
<p>Express는 웹 및 모바일 애플리케이션 구축을 위한 광범위한 기능을 제공하는 <strong>노드 JS 웹 애플리케이션 프레임워크</strong>. 단일 페이지, 다중 페이지 및 하이브리드 웹 애플리케이션을 빌드하는데 사용됨
-&gt; Node.js의 API를 단순화하고 유용한 기능들을 더 추가하여 Node.js를 더 편리하고 유용하게 사용할 수 있도록 해줌</p>
<h3 id="express-js를-사용하는-이유">Express js를 사용하는 이유</h3>
<ul>
<li>Node.js의 API를 쉽게 사용할 수 있게 함</li>
<li>많은 사람들이 사용중</li>
<li>ExpressJS를 기반으로 하는 다른 프레임워크들도 만들어지고 있기 때문에, 이 프레임워크 하나만 배우면 다른 노드 js 프레임워크도 빠르게 배울 수 있음</li>
</ul>
<br>

<h2 id="36-resjson-vs-ressend">36. res.json vs res.send</h2>
<p>res.send와 res.json은 기능상으로 거의 동일</p>
<h3 id="resjson-소스-코드">res.json 소스 코드</h3>
<ol>
<li><strong>res.json(object)</strong>로 필요한 값들을 설정<ol>
<li>먼저 object로 들어오는 value들을 JSON 문자열로 변환</li>
<li>Content-Type 헤더가 셋팅되지 않았을 경우 this(res 객체)에 Content-Type으로 application/json을 셋팅</li>
</ol>
</li>
<li><strong>res.send(body)</strong>를 실행</li>
</ol>
<h3 id="ressend-소스-코드">res.send 소스 코드</h3>
<ol>
<li><strong>res.send(object)</strong>로 body의 타입 체크</li>
<li>타입이 object일 경우 <strong>res.json(object)</strong> 호출<ol>
<li>JSON 문자열로 변환</li>
<li>다시 <strong>res.send(string)</strong> 호출</li>
</ol>
</li>
</ol>
<h3 id="결론">결론</h3>
<p>res.send와 res.json은 외부에서 볼때는 차이가 없어 보이지만 res.send를 사용하면 내부에서 호출이 한 번 더 일어남. 또한 object를 보낼 때에는 res.json()을 이용하는 것이 더 직관적이기도 하므로 <strong>res.json()을 이용하는 것을 추천!</strong></p>
<br>

<h2 id="37-ressend-vs-resend">37. res.send vs res.end</h2>
<h3 id="resend">res.end()</h3>
<p>response가 있고 데이터를 수집하거나 호출자에게 제공하고 싶은 다른 작업을 수행하면 마지막 단계로 세션을 종료해야 함. 이를 res.end()를 호출하여 수행할 수 있음</p>
<h3 id="꼭-resend를-이용해서-세션을-종료해야-하나요">꼭 res.end()를 이용해서 세션을 종료해야 하나요?</h3>
<ul>
<li><h4 id="resend로-종료해야하는-때">res.end()로 종료해야하는 때</h4>
<p>데이터를 제공하지 않고 응답을 종료하려면 res.end()를 사용할 수 있음. 이것은 404 페이지에 유용할 수 있음</p>
</li>
<li><h4 id="resend로-종료하지-않아도-되는-때">res.end()로 종료하지 않아도 되는 때</h4>
<p>데이터를 res.json()이나 res.send()로 보내면 알아서 종료됨</p>
</li>
</ul>
<h3 id="resendpsome-htmlp-vs-ressendpsome-htmlp">res.end(&#39;&lt;p&gt;some html&lt;/p&gt;&#39;) vs. res.send(&#39;&lt;p&gt;some html&lt;/p&gt;&#39;)</h3>
<p>둘다 브라우저에 보이는 결과는 똑같음</p>
<p>하지만 Response Header 부분은 다름
<strong>res.end에는 Content-Type과 ETag가 없음</strong></p>
<blockquote>
<p><strong>ETag 란?</strong>
ETag HTTP 응답 헤더는 리소스의 특정 버전에 대한 식별자. 콘텐츠가 변경되지 않은 경우 웹 서버에서 전체 응답을 보낼 필요가 없으므로 캐시를 보다 효율적으로 사용하고 대역폭을 절약할 수 있음</p>
</blockquote>
<br>

<h2 id="38-포스트맨">38. 포스트맨</h2>
<p>Postman은 개발한 API를 테스트하고, 테스트 결과를 공유하여 API 개발의 생산성을 높여주는 플랫폼</p>
<p><a href="https://www.postman.com/downloads/">https://www.postman.com/downloads/</a></p>
<br>

<h2 id="40-middleware">40. middleware</h2>
<p>미들웨어 기능은 애플리케이션의 요청-응답 주기에서 요청 객체(req), 응답 객체(res), next 미들웨어 함수에 접근할 수 있는 기능. next 미들웨어 기능은 next라는 변수로 표시됨</p>
<pre><code class="language-js">const express = requrie(&#39;express&#39;)
const app = express()

// use -&gt; register middleware
app.use(req, res, next) =&gt; {
  console.log(&#39;Time:&#39;, Date.now())
  next() // 다음 미들웨어로 이동
})</code></pre>
<p><strong>Express 애플리케이션은 본질적으로 일련의 미들웨어 기능 호출</strong>임
ex) request -&gt; logger -&gt; bodyParser -&gt; cookieParser -&gt; ... -&gt; response</p>
<br>

<h2 id="43-model-view-controller">43. Model, View, Controller</h2>
<h3 id="mvc-pattern">MVC Pattern</h3>
<p>MVC(모델-뷰-컨트롤러)는 관련 프로그램 로직을 상호 연결된 3개의 요소로 나누어 사용자 인터페이스를 개발하는 데 일반적으로 사용되는 소프트웨어 아키텍쳐 패턴
소프트웨어의 비즈니스 로직과 화면을 구분하는데 중점을 둠</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a0/MVC-Process.svg/400px-MVC-Process.svg.png" alt="MVC"></p>
<blockquote>
<p>ex) <strong>View</strong>: 장바구니에 담기 버튼을 클릭 --Request--&gt; <br> <strong>Controller</strong>: Model에게 아이템을 추가하라고 알려줌 --Manipulate--&gt; <br> <strong>Model</strong>: 아이템을 추가하고 변경된 모델을 View에게 알려서 화면이 업데이트 되게 함</p>
</blockquote>
<h3 id="model">Model</h3>
<p><strong>데이터와 비즈니스 로직을 관리</strong>
앱이 포함해야 할 데이터가 무엇인지 정의. 데이터의 상태가 변경되면 일반적으로 뷰에게 알리며 가끔 컨트롤러에게 알리기도 함
주로 어떤 종류의 데이터베이스에 포함되어 있던 것</p>
<h3 id="view">View</h3>
<p><strong>레이아웃과 화면을 처리</strong>
앱의 데이터를 사용자에게 보여지는 방식을 정의. 표시할 데이터를 모델로부터 받음</p>
<h3 id="controller">Controller</h3>
<p><strong>명령을 모델과 뷰로 라우팅</strong>
사용자의 입력에 대한 응답으로 모델 또는 뷰를 업데이트하는 로직을 포함
단순히 데이터를 다른 형태로 나타내기 위해 뷰를 업데이트할 경우, (ex. 항목을 알파벳 순서로 정렬, 가격이 낮은 순으로 정렬) 컨트롤러는 모델을 업데이트할 필요 없이 바로 처리할 수 있음</p>
<br>

<h2 id="45-router-controller">45. Router, Controller</h2>
<h3 id="router-란">Router 란</h3>
<p>클라이언트의 요청 경로(path)에 따라 이 요청을 처리할 수 있는 곳으로 기능을 전달해주는 것</p>
<br>

<h2 id="46-restful-api">46. Restful API</h2>
<p>Restful API는 두 컴퓨터 시스템이 인터넷을 통해 정보를 안전하게 교환하기 위해 사용하는 인터페이스. 대부분의 비즈니스 애플리케이션은 다양한 태스크를 수행하기 위해 다른 내부 애플리케이션 및 서드 파티 애플리케이션과 통신해야함
-&gt; 이런한 통신을 할 때 안전하고 효율적이게 하기위해 사용</p>
<h3 id="rest">Rest</h3>
<p>REST(Representational State Transfer)는 처음에 인터넷과 같은 복잡한 <strong>네트워크에서 통신을 관리하기 위한 지침</strong>. REST 기반의 아키텍처를 사용해서 대규모 고성능 통신을 안정적으로 지원</p>
<ul>
<li>GET: 데이터를 서버로부터 받아옴</li>
<li>POST: 무언가를 생성하기 위해 서버에 데이터 블록을 수락하도록 요청</li>
<li>PUT: 데이터 전체를 업데이트</li>
<li>PATCH: 데이터 일부를 업데이트</li>
<li>DELETE: 데이터를 삭제</li>
<li>슬래시 구분자(/)는 계층 관계를 나타냄</li>
<li>띄어쓰기는 밑줄(_)보다는 하이픈(-) 사용</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[01. Node.js와 웹 서버]]></title>
            <link>https://velog.io/@surra7/01.-Node.js%EC%99%80-%EC%9B%B9-%EC%84%9C%EB%B2%84</link>
            <guid>https://velog.io/@surra7/01.-Node.js%EC%99%80-%EC%9B%B9-%EC%84%9C%EB%B2%84</guid>
            <pubDate>Fri, 22 Mar 2024 02:07:02 GMT</pubDate>
            <description><![CDATA[<h2 id="01-자바스크립트-엔진">01. 자바스크립트 엔진</h2>
<p>자바스크립트를 실행하려면 자바스크립트 엔진이 필요!
브라우저에는 이미 자바스크립트 엔진이 있기 때문에 자바스크립트를 실행할 수 있음</p>
<p>JavaScript 엔진은 자바스크립트 코드를 실행하는 소프트웨어 구성 요소. 최초의 JavaScript 엔진은 단순한 interpreter였지만, 모든 관련 최신 엔진은 성능 향상을 위해 Just-in-Time 컴파일을 사용. JavaScript 엔진은 일반적으로 웹 브라우저 공급업체에서 개발하며 모든 주요 브라우저에 하나가 있음</p>
<h3 id="컴퓨터가-소스-코드를-이해하려면">컴퓨터가 소스 코드를 이해하려면?</h3>
<p>컴퓨터 프로세서는 오직 0과 1만 이해할 수 있기 때문에 우리가 작성한 소스 코드를 머신 코드로 변환해 줘야 함. 이 변환 과정은 컴파일과 인터프리터를 통해 일어남</p>
<h4 id="interpreter">Interpreter</h4>
<p>High Level Language를 한 줄씩 번역하고 실행</p>
<h4 id="compiler">Compiler</h4>
<p>High Level Language를 한번에 기계어로 변환하여 실행</p>
<h3 id="jit-compilation-just-in-time">JIT Compilation (Just In Time)</h3>
<p>interpreter는 코드를 한줄 한줄 해석하고 실행하기 때문에 매우 느림. 따라서 더 나은 퍼포먼스를 위해 JIT 컴파일 사용</p>
<p>JIT compilation은 ahead-of-time compilation(AOT)와 interpretation 두 가지 방식의 결합</p>
<h3 id="자바스크립트-엔진의-종류">자바스크립트 엔진의 종류</h3>
<table>
<thead>
<tr>
<th align="center">브라우저</th>
<th align="center">자바스크립트 엔진</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Chrome</td>
<td align="center">V8</td>
</tr>
<tr>
<td align="center">Firefox</td>
<td align="center">SpiderMonkey</td>
</tr>
<tr>
<td align="center">Safari</td>
<td align="center">JavascriptCore</td>
</tr>
<tr>
<td align="center">Internet Explorer</td>
<td align="center">Chakra</td>
</tr>
</tbody></table>
<br>

<h2 id="08-module">08. Module</h2>
<p>Node.js에서 module은 &#39;필요한 함수들의 집합&#39;
사용하고자 하는 모든 기능을 처음부터 다 만들어서 사용할 수는 없음
다른 사람이 이미 만들어 놓은 모듈을 사용하거나 노드 JS에서 제공해주는 많은 모듈을 사용</p>
<h3 id="모듈을-불러오는-방법">모듈을 불러오는 방법</h3>
<pre><code class="language-js">const module = require(&quot;module_name&quot;)</code></pre>
<ul>
<li><h3 id="core-module">Core Module</h3>
<p>Node.js에서 기본으로 제공하는 모듈</p>
<ul>
<li>http: 서버를 생성하기 위한 클래스, 메소드, 이벤트를 포함</li>
<li>url: URL 확인 및 구문 분석을 위한 메소드 포함</li>
<li>querystring: 쿼리 문자열을 처리하는 메소드 포함</li>
<li>path: 파일 경로를 처리하는 메소드 포함</li>
<li>fs: 파일 I/O 작업을 위한 클래스, 메소드, 이벤트 포함</li>
<li>util: 프로그래머에게 유용한 유틸리티 기능이 포함</li>
</ul>
</li>
<li><h3 id="local-module">Local Module</h3>
<p>Node.js 애플리케이션에 사용자가 로컬로 생성한 모듈
Node.js 커뮤니티에서 사용할 수 있도록 패키지로 만들어 NPM을 통해 배포할 수 도 있음</p>
</li>
<li><h3 id="third-party-module">Third Party Module</h3>
<p>다른 사람이 만든 모듈을 NPM을 통해 가져와 사용할 수 있음</p>
</li>
</ul>
<br>

<h2 id="13-commonjs-vs-ecma-script-모듈">13. CommonJS vs. ECMA script 모듈</h2>
<h3 id="commonjs-module">CommonJS Module</h3>
<p><strong>module.exports로 내보내고 requrie로 가져오는 것</strong>은 CommonJS
이 CommonJS는 Node.js에서 기본 모듈로 사용되고 있음</p>
<h3 id="ecmascript-module">ECMAScript Module</h3>
<p>ECMAScript는 <strong>export, import를 이용해서 모듈을 내보내고 가져오는</strong> Syntax 사용</p>
<ul>
<li>ES 모듈은 JavaScript의 표준이고 CommonJS는 Node.js의 기본값</li>
<li>모든 주요 브라우저는 ES 모듈을 지원하며 React 및 Vue.js와 같은 프레임워크에서도 ES 모듈의 import와 export를 사용할 수 있음
이러한 프레임워크는 Babel과 같은 transpiler를 사용하여 이전 Node.js 버전이 기본적으로 지원하는 require()로 컴파일함</li>
<li>Node.js 13.2.0 버전부터 ECMAScript 모듈을 지원함</li>
</ul>
<br>

<h2 id="15-모듈-캐싱">15. 모듈 캐싱</h2>
<p>모듈에서 다른 모듈을 가져올 때 (load할 때) ECMAScript를 사용하든 CommonJS를 사용하든 해당 모듈을 캐싱함
따라서 한번 가져오면 다음에 다시 load할 필요없음</p>
<br>

<h2 id="17-npm">17. npm</h2>
<h3 id="npm-이란">npm 이란?</h3>
<ul>
<li>오픈 소스 Node.js 프로젝트 게시를 위한 온라인 레포지토리(저장소)
NPM 레지스트리 모듈들이 저장되어 있는 곳</li>
<li>패키지 설치, 버전 관리 및 종속성 관리를 지원하는 해당 저장소와 상호 작용하기 위한 명령줄 유틸리티</li>
</ul>
<br>

<h2 id="21-package-lockjson">21. package-lock.json</h2>
<p>package-lock.json이 생성되는 시점의 의존성 트리(node_modules)에 대한 정보를 가지고 있는 파일</p>
<h3 id="package-lockjson-파일을-사용하는-이유">package-lock.json 파일을 사용하는 이유</h3>
<ul>
<li>이 파일은 소스 레포지토리에 커밋하기 위한 것이며 다양한 용도로 사용됨</li>
<li>팀원, 배포 및 지속적인 통합이 정확히 동일한 종속성을 절치하도록 보장하는 종속성 트리의 단일 표현을 설명함</li>
<li>사용자가 디렉토리 자체를 커밋하지 않고도 node_moduels의 이전 상태로 돌아갈 수 있는 기능을 제공</li>
<li>읽을 수 있는 소스 제어 diff를 통해 트리 변경 사항을 더 쉽게 볼 수 있음</li>
<li>npm이 이전에 설치된 패키지에 대해 반복되는 메타데이터 확인을 건너뛸 수 있도록 하여 설치 프로세스를 최적화</li>
</ul>
<br>

<h2 id="22-npm-audit">22. npm audit</h2>
<p>audit 명령은 프로젝트에 구성된 종속성에 대한 설명을 기본 레지스트리에 제출하고 알려진 취약성에 대한 보고서를 요청. 취약점이 발견되면 적절한 교정도 해줌. fix 인수가 제공되면 수정사항이 패키지 트리에 적용됨</p>
<br>

<h2 id="24-yarn">24. Yarn</h2>
<p>Yarn은 페이스북에서 만든 자바스크립트 패키지 매니저</p>
<p>원래는 npm만을 이용해서 패키지 관리를 했지만 Facebook에서 npm의 단점들(보안 및 성능)에 대응하기 위해 yarn을 개발하게 됨
Yarn은 npm보다 속도와 보안에서 더 향상된 성능을 가짐</p>
<ul>
<li><h4 id="패키지-병령-설치">패키지 병령 설치</h4>
<p>npm은 패키지들을 설치할 때 설치하는 패키지를 다 설치하고 난 후에 다른 패키지를 순차적으로 실행. yarn은 병렬로 패키지를 설치하기 때문에 더 빠르게 설치할 수 있음</p>
</li>
<li><h4 id="lock-파일-생성">lock 파일 생성</h4>
<p>npm으로 패키지를 설치하면 package-lock.json 파일을 생성하는 것처럼 yarn으로 패키지를 설치하면 <strong>yarn.lock</strong> 파일을 생성하게 됨
package-lock.json과 마찬가지로 yarn.lock에도 <strong>최초 패키지 추가 시에 설치된 버전들</strong>이 들어 있음
yarn.lock 파일이 있으면 레지스트리에 패키지의 더 최신 버전이 있어서 yarn install로 패키지를 설치할때 yarn.lock에 있는 버전을 사용하므로 패키지 버전 문제를 최소화할 수 있음</p>
</li>
<li><h4 id="향상된-보안">향상된 보안</h4>
<p>yarn은 패키지를 다운로드하는 동안 백그라운드 프로세스로 보안 검사를 수행. 패키지 라이센스 정보를 사용하여 악성 스크립트를 다운로드하거나 종속성 충돌을 일으키지 않도록 함</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React Native 04~13]]></title>
            <link>https://velog.io/@surra7/04.-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C-Firebase-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0-09.-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C-%EB%AA%A8%EB%B0%94%EC%9D%BC-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@surra7/04.-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C-Firebase-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0-09.-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C-%EB%AA%A8%EB%B0%94%EC%9D%BC-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 20 Mar 2024 09:36:47 GMT</pubDate>
            <description><![CDATA[<h2 id="28-react-navigation">28. React Navigation</h2>
<p>리액트 네이티브에서 sreen간의 이동을 구현하기 위해서 React Navigation이라는 모듈 사용</p>
<h3 id="필요한-모듈-설치">필요한 모듈 설치</h3>
<pre><code class="language-bash">npm install @react-navigation/native
expo install react-native-screens react-native-safe-area-context
npm install @react-navigatin/native-stack</code></pre>
<br>

<h2 id="44-tailwindcss">44. TailWindCSS</h2>
<h3 id="tailwindcss-란">TailWindCSS 란?</h3>
<p>HTML안에서 CSS 스타일을 만들 수 있게 해주는 CSS 프레임워크</p>
<h3 id="css-프레임워크란">CSS 프레임워크란?</h3>
<p>CSS 프레임워크는 레이아웃 및 여러 컴포넌트의 구성, 브라우저 호환성을 보장하는데 소요되는 시간을 최소화하기 위해 여러 웹 개발/디자인 프로젝트에 적용할 수 있는 CSS 파일 모음
애플리케이션을 더 빠르게 스타일링 하는데 도움을 줌</p>
<h4 id="css-프레임워크-종류-for-react-js">css 프레임워크 종류 for React JS</h4>
<ul>
<li>Material UI</li>
<li>React Bootstrap</li>
<li>Semantic UI</li>
<li>Ant Design</li>
<li>Materialize</li>
</ul>
<h3 id="tailwind-css의-장점">Tailwind CSS의 장점</h3>
<p>Tailwind CSS는 부트스트랩과 비슷하게 m-1, flex와 같이 미리 셋팅된 Utility Class를 활용하는 방식으로 HTML에서 CSS를 스타일링 할 수 있음</p>
<ul>
<li>따라서 빠르게 스타일링 작업이 가능</li>
<li>class 혹은 id명을 작성하기 위한 고생을 하지 않아도 됨</li>
<li>유틸리티 클래스가 익숙해지기 위한 시간이 필요할 수 있지만 InteliiSense 플러그인이 제공되어 쉽게 익숙해 질 수 있음</li>
</ul>
<br>

<h2 id="45-tailwind-css-적용하기">45. Tailwind CSS 적용하기</h2>
<p><a href="https://www.nativewind.dev/quick-starts/expo">https://www.nativewind.dev/quick-starts/expo</a></p>
<br>

<h2 id="53-uselayouteffect">53. useLayoutEffect</h2>
<p>useLayoutEffect는 useEffect와 사용 문법이 똑같음
useEffect는 모든 DOM의 mutation이 끝나고 나서 실행. useLayoutEffect는 브라우저에 페인트를 하기 전에 실행됨</p>
<br>

<h2 id="72-react-navigation을-이용해서-라우팅-구현하기">72. React Navigation을 이용해서 라우팅 구현하기</h2>
<h3 id="indexjs-엔트리-파일">index.js 엔트리 파일</h3>
<p>AppRegistry는 모든 React Native 앱을 실행하기 위한 JS진입점
App 루트 컴포넌트는 AppRegistry.registerComponent에 자신을 등록해야함. 그러면 기본 시스템은 앱에 대한 번들을 로드한 다음 AppRegistry.runAplication을 호출하여 앱이 준비되면 앱을 실행할 수 있음</p>
<pre><code class="language-tsx">function AppRegistry.registerComponent(appKey: string, getComponentFunc: ComponentProvider, section?: boolean | undefined): string</code></pre>
<h4 id="appkey">appKey</h4>
<p>appKey는 app.json에 있는 name</p>
<ul>
<li>name: 프로젝트에 사용되는 짧은 이름이며 TitleCase여야 함</li>
<li>displayName: 홈 화면의 앱 이름</li>
</ul>
<h3 id="stack-vs-tab">Stack vs Tab</h3>
<p>Stack Navigator는 React Native 앱이 Stack을 사용하여 화면 간에 전환을 할 수 있는 방법을 제공
예를 들어 로그인에서 가입 화면으로 이동하면 가입 화면이 로그인 화면 맨위에 쌓이고 뒤로 이동하면 가입 화면이 스택에서 꺼짐</p>
<p>Tab Navigator는 화면 하단이나 상단에 Tab이 있는 Navigator이며 다른 화면 사이를 전환하는데 사용
Tab Navigator는 Screen을 Component로 사용하거나 Stack을 Component로 사용할 수 있음</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React Native  01~03]]></title>
            <link>https://velog.io/@surra7/01.-React-Native-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-02.-React-Native-%EB%A6%AC%EB%8D%95%EC%8A%A4</link>
            <guid>https://velog.io/@surra7/01.-React-Native-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-02.-React-Native-%EB%A6%AC%EB%8D%95%EC%8A%A4</guid>
            <pubDate>Fri, 08 Mar 2024 07:43:04 GMT</pubDate>
            <description><![CDATA[<h2 id="01-react-native란">01. React Native란?</h2>
<p>React Native는 React와 앱 플랫폼의 기본 기능을 사용하여 Android 및 iOS 애플리케이션을 빌드하기 위한 오픈소스 프레임워크
사용자 인터페이스(UI)를 구축하기 위한 React를 기반으로 하지만 React는 브라우저를 대상으로 하고 React Native는 모바일 플랫폼을 대상으로 함
대부분의 코드를 플랫폼 간에 공유할 수 있기 때문에 Android와 iOS 모두에서 동시에 쉽게 개발할 수 있음</p>
<h3 id="리액트-네이티브의-장점">리액트 네이티브의 장점</h3>
<ol>
<li><p>WebView를 사용하는 다른 크로스 플랫폼과는 다르게 실제 호스트 플랫폼의 표준 렌더링 API를 사용해서 렌더링함
=&gt; WebView를 사용하면 성능상의 문제와 Native에서 사용하는 기본 UI 요소나 애니메이션을 Javascript, HTML 및 CSS 조합으로 모방하려고 하게에 한계가 있음
=&gt; 타 플랫폼에서는 웹에서 만들고 그것을 앱에 임베딩해서 사용, React Native는 마크업 요소를 실제 네이티브 요소로 변환해서 사용함</p>
</li>
<li><p>리액트 네이티브는 리액트와 마찬가지로 state와 props가 변경되면 React Native의 뷰를 다시 렌더링하는 것과 같이 React와 대부분의 기능이 비슷
React Native와 React의 주요 차이점은 React Native가 HTMl 및 CSS 마크업을 사용하는 대신 호스트 플랫폼의 UI 라이브러리를 활용한다는 것</p>
</li>
<li><p>크로스 플랫폼이란 이름과 같이 대부분의 비슷한 소스 코드로 iOS와 Android 모두를 위한 앱 개발을 할 수 있음. 따라서 많은 시간과 비용을 절약해서 앱을 만들 수 있음</p>
</li>
</ol>
<br>

<h2 id="02-core-components--native-components">02. Core Components &amp; Native Components</h2>
<h3 id="native-components">Native Components</h3>
<p>Android 개발에서는 Kotlin 또는 Java로 View를 작성
iOS 개발에서는 Swift 또는 Objective-C를 사용
React Native를 사용하면 React Component를 사용하여 JavaScript로 이러한 View를 호출할 수 있음
<strong>런타임 시 React Native는 해당 구성 요소에 해당하는 Android 및 iOS View를 생성</strong>. React Native 구성 요소는 Android 및 iOS와 동일한 보기에서 지원되기 때문에 React Native 앱은 다른 앱과 같은 모양, 느낌 및 성능을 제공. 이러한 플랫폼 지원 구성 요소를 Native Component라고 함</p>
<h3 id="core-components">Core Components</h3>
<p>Native Components는 누구나 각자 원하는 바에 맞게 만들 수 있음
Core Components는 <strong>리액트에서 기본으로 제공하는 Native Components</strong>
ex) &lt;View&gt; &lt;Text&gt; &lt;Image&gt; &lt;ScrollView&gt; &lt;TextInput&gt;...</p>
<br>

<h2 id="03-리액트-네이티브를-사용하기-위한-개발환경">03. 리액트 네이티브를 사용하기 위한 개발환경</h2>
<p>리액트 네이티브를 이용하기 위한 개발 환경을 세팅하는 방법은 대표적으로 두 가지</p>
<h3 id="1-expo">1. Expo</h3>
<ul>
<li>무료로 사용하는 3rd Party 서비스. 개발을 쉽게 할 수 있도록 도와줌</li>
<li>쉬운 배포 및 버전 업데이트 Android Studio/X-code 없이 본인의 휴대폰으로 테스트 가능. 빠르고 간단한 설치 및 환경 설정</li>
<li>Expo에서 제공하는 기능만 사용 가능. 모듈을 만들어서 사용 불가. native 파일 제어 불가. 간단하고 편리한 대신 복잡하고 섬세하게 제어를 못한다는 단점</li>
</ul>
<h3 id="2-react-native-cli">2. React Native CLI</h3>
<ul>
<li>React Team에서 만들었으며, Expo 같은 툴을 사용하지 않고 React Native만을 이용해서 개발하는 것</li>
<li>네이티브 파일 및 모듈 사용 가능. 네이티브 소스 코드 작성 가능</li>
<li>Expo에 비해 편의성 부족. 사용자가 직접 기본 구성을 해야해서 시간이 오래걸림. Android Studio/X-code를 설치해서 빌드 및 배포를 해야함</li>
</ul>
<br>

<h2 id="11-stypesheet를-이용한-스타일링">11. StypeSheet를 이용한 스타일링</h2>
<p>React Native에서는 CSS가 아닌 Javascript로 스타일링을 함</p>
<h3 id="react-native에서-스타일링하는-방법">React Native에서 스타일링하는 방법</h3>
<ul>
<li>inline styles 사용</li>
<li>StyleSheet 객체 사용</li>
</ul>
<h3 id="stylesheet를-이용한-스타일링이-추천되는-이유">StyleSheet를 이용한 스타일링이 추천되는 이유</h3>
<ol>
<li>스타일링 코드를 분리해줘서 전체 소스 코드의 가독성을 높임</li>
<li>StyleSheet를 사용하면 이미 정해놓은 스타일을 캐시해주기 때문에 다시 렌더링 할 때 inline styles를 사용할 때 보다 성능이 좋음</li>
</ol>
<br>

<h2 id="15-react-native에서-svg-사용하기">15. React Native에서 SVG 사용하기</h2>
<p>리액트 네이티브에서는 기본적으로 SVG 파일을 지원하지 않기 때문에 SVG를 사용하려면 설정을 해줘야 함</p>
<h3 id="사용방법">사용방법</h3>
<h4 id="react-native-svg-모듈-설치">react-native-svg 모듈 설치</h4>
<p>svg 요소나 속성들을 React Native에서 사용할 수 있게 해줌</p>
<pre><code class="language-bash">npm install react-native-svg --save</code></pre>
<h4 id="react-native-svg-transformer-모듈-설치">react-native-svg-transformer 모듈 설치</h4>
<p>svg 파일을 import해서 사용할 수 있게 해줌</p>
<pre><code class="language-bash">npm install -D react-native-svg-transformer</code></pre>
<h4 id="metroconfigjs-파일-설정">metro.config.js 파일 설정</h4>
<pre><code class="language-js">const { getDefaultConfig } = require(&quot;expo/metro-config&quot;);

module.exports = (() =&gt; {
  const config = getDefaultConfig(__dirname);

  const { transformer, resolver } = config;

  config.transformer = {
    ...transformer,
    babelTransformerPath: require.resolve(&quot;react-native-svg-transformer&quot;)
  };
  config.resolver = {
    ...resolver,
    assetExts: resolver.assetExts.filter((ext) =&gt; ext !== &quot;svg&quot;),
    sourceExts: [...resolver.sourceExts, &quot;svg&quot;]
  };

  return config;
})();</code></pre>
<p>참고: <a href="https://www.npmjs.com/package/react-native-svg-transformer">https://www.npmjs.com/package/react-native-svg-transformer</a></p>
<h4 id="svg-다운받기">svg 다운받기</h4>
<p><a href="https://www.svgrepo.com/">https://www.svgrepo.com/</a></p>
<br>

<h2 id="27-todo-리스트-나열하기">27. Todo 리스트 나열하기</h2>
<p>리액트 네이티브에서 리스트를 나열하기</p>
<ul>
<li>FlatList</li>
<li>ScrollView</li>
</ul>
<p>ScrollView는 Component가 로드된 직후 Item을 로드함. 모든 데이터가 RAM에 저장되어 한 번에 보여주기 때문에 많은 양의 데이터가 있는 경우 성능 저하기 일어남
반면에 FlatList는 10개(기본값)의 Item을 화면에 탑재하고 사용자가 보기를 스크롤하면 다른 Item이 탑재됨. 이러한 점에서 FlatList를 사용하는 것이 더 좋음</p>
<p>적은 수의 Item에는 ScrollView를 사용하고 많은 수의 Item에는 FlatList를 사용</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[07. Next.js와 TypeScript]]></title>
            <link>https://velog.io/@surra7/07.-Next.js%EC%99%80-TypeScript</link>
            <guid>https://velog.io/@surra7/07.-Next.js%EC%99%80-TypeScript</guid>
            <pubDate>Wed, 06 Mar 2024 07:13:08 GMT</pubDate>
            <description><![CDATA[<h2 id="135-nextjs-란">135. NextJS 란?</h2>
<p>React의 SSR(Server Side Rendering)을 쉽게 구현할 수 있도록 도와주는 간단한 프레임워크
리액트로 개발할 때 SPA와 CSR(Client Side Rendering)을 하기 때문에 좋은 점도 있지만 단점도 있음. 그것이 바로 검색엔진 최적화(SEO) 부분
Client Side Rendering을 하면 첫페이지에서 빈 html을 가져와서 JS파일을 해석하여 화면을 구성하기 때문에 포털 검색에 거의 노출되지 않음</p>
<p>하지만 Next.js에서는 Pre-Rendering을 통해 페이지를 미리 렌더링하여 완성된 html을 가져오기 때문에 사용자와 검색 엔진 크롤러에게 바로 렌더링 된 페이지를 전달할 수 있게됨</p>
<p>리액트에서도 SSR을 지원하지만 구현하기에 굉장히 복잡하기 때문에 Next.js를 통해서 이 문제를 해결</p>
<h3 id="ssrserver-side-rendering">SSR(Server Side Rendering)</h3>
<ul>
<li>클라이언트 대신 서버에서 페이지를 준비하는 원리</li>
<li>원래 리액트에서는 클라이언트 사이드 렌더링을 하기 때문에 서버에 영향을 미치지 않고 서버에서 클라이언트로 응답해서 보낸 html도 거의 비어있음
  =&gt; 이 방식은 서버에서 데이터를 가져올 때 지연시간 발생으로 UX 측면에서 좋지 않을 수 있음
  =&gt; 검색 엔진에 검색 시 웹 크롤링이 동작할 때 내용을 제대로 가져와 읽을 수 없기에 검색엔진 최적화에 문제가 생김</li>
<li>Next.js에서는 서버 사이드 렌더링을 이용하므로 사용자와 검색 엔진 크롤러에게 바로 렌더링 된 페이지를 전달 할 수 있어서 검색엔진 최적화에 좋음</li>
</ul>
<br>

<h2 id="138-data-fetching">138. Data Fetching</h2>
<h3 id="nextjs에서-데이터를-가져오는-방법">Next.js에서 데이터를 가져오는 방법</h3>
<p>보통 리액트에서는 useEffect로 데이터를 가져옴. 하지만 next.js에서는 여러가지 방법이 있으며 사용 용도에 따라 사용하면 됨</p>
<ul>
<li><strong>getStaticProps</strong>: Static Generation으로 빌드할 때 데이터를 불러옴 (미리 만들어둠)</li>
<li><strong>getStaticPaths</strong>: Static Generation으로 데이터에 기반하여 pre-render시 특정한 동적 라우팅 구현 (pages/post/[id].js)</li>
<li><strong>getServerSideProps</strong>: Server Side Rendering으로 요청이 있을 때 데이터를 불러옴</li>
</ul>
<h3 id="getstaticprops">getStaticProps</h3>
<p>getStaticProps 함수를 async로 export하면 getStaticProps에서 리턴되는 props를 가지고 빌드 타임에 페이지를 pre-render함</p>
<h4 id="getstaticprops를-사용해야-할-때">getStaticProps를 사용해야 할 때</h4>
<ul>
<li>사용자의 요청보다 먼저 build 시간에 페이지를 렌더링하는데 필요한 데이터를 가져올 때</li>
<li>Headless CMS에서 데이터를 가져올 때</li>
<li>데이터를 공개적으로 캐시할 수 있을 때 (사용자별 x)</li>
<li>페이지는 미리 렌더링되어야 하고 (SEO의 경우) 매우 빨라야 할 때 (getStaticProps는 성능을 위해 CDN에서 캐시할 수 있는 HTML 및 JSON 파일을 생성)</li>
</ul>
<h3 id="getstaticpaths">getStaticPaths</h3>
<p>동적 라우팅이 필요할 때 getStaticPaths로 경로 리스트를 정의하고, 빌드 시간에 HTML에 렌더링 됨
Next.js는 pre-render에서 정적으로 getStaticPaths에서 호출하는 경로들을 가져옴</p>
<h4 id="paths">Paths</h4>
<ul>
<li>어떠한 경로가 pre-render 될지 결정</li>
<li>예시) 
만약 pages/posts/[id].js 라는 이름의 동적 라우팅을 사용하는 페이지가 있다면 아래와 같이 작성<pre><code class="language-jsx">return {
paths: [
  { params: { id: &#39;1&#39; } },
  { params: { id: &#39;2&#39; } }
],
fallback: ...
}</code></pre>
빌드하는 동안 /posts/1과 /posts/2를 생성하게 됨</li>
</ul>
<blockquote>
<p><strong>fallback</strong></p>
</blockquote>
<ul>
<li>false인 경우: getStaticPaths로 리턴되지 않는 것은 모두 404 페이지가 뜸</li>
<li>true인 경우: getStaticPaths로 리턴되지 않는 것은 404로 뜨지 않고, fallback 페이지가 뜨게 됨</li>
</ul>
<h3 id="getserversideprops">getServerSideProps</h3>
<p>getServerSideProps 함수를 async로 export하면, Next.js는 각 요청마다 리턴되는 데이터를 getServerSideProps로 pre-render함
build 타임에 한번에 가져오는게 아니라 요청할 때 마다 가져옴</p>
<h4 id="getserversideprops를-사용해야-할-때">getServerSideProps를 사용해야 할 때</h4>
<ul>
<li>요청할 때 데이터를 가져와야하는 페이지를 pre-render해야 할 때 사용</li>
<li>서버가 모든 요청에 대한 결과를 계산하고, 추가 구성없이 CDN에 의해 결과를 캐시할 수 없기 때문에 첫번째 바이트까지의 시간은 getStaticProps보다 느림</li>
</ul>
<br>

<h2 id="139-typescript">139. TypeScript</h2>
<h3 id="typescript가-나오게-된-배경">TypeScript가 나오게 된 배경</h3>
<p>JavaScript의 코드가 커질수록 소스 코드가 복잡해져서 코드를 유지 관리하고 재사용하기가 어려워짐. 더욱이 Type 검사 및 컴파일 시 오류 검사의 기능을 수용하지 못하기 때문에 이것을 해결하기 위해 TypeScript가 제시됨.</p>
<h3 id="typescript-란">TypeScript 란?</h3>
<p><strong>타입스크립트는 자바스크립에 타입을 부여한 언어</strong>. 타입스크립트는 자바스크립트를 <strong>타입 시스템</strong>으로 감싼 자바스크립트의 확장된 언어라고 할 수 있음. 
타입스크립트는 자바스크립트와 달리 브라우저에서 실행하려면 파일을 한번 변환해주어야 함. 이 변환 과정을 <strong>컴파일</strong>이라고 부름</p>
<h3 id="type-system">Type System</h3>
<ul>
<li>개발 환경에서 에러를 잡는 걸 도와줌</li>
<li>type annotation을 사용해서 코드를 분석할 수 있음</li>
<li>오직 개발 환경에서만 활성화 됨</li>
<li>타입 스크립트와 성능 향상과는 관계가 없음</li>
</ul>
<h3 id="typescript를-사용해야-하는-이유">TypeScript를 사용해야 하는 이유</h3>
<ul>
<li>TypeScript는 JavaScript 코드를 단순화하여 더 쉽게 읽고 디버깅 할 수 있게 함</li>
<li>TypeScript는 오픈 소스</li>
<li>정적 검사와 같은 JavaScript IDE 및 사례를 위한 매우 생산적인 개발 도구를 제공</li>
<li>ES6의 모든 이점을 포함한 더 많은 생산성을 제공</li>
<li>TypeScript는 타입 검사를 통해 JavaScript를 작성할 때 개발자가 일반적으로 겪는 고통스러운 버그를 피하는데 도움이 됨</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[06. Redux 와 TDD - 2]]></title>
            <link>https://velog.io/@surra7/06.-Redux-%EC%99%80-TDD-2</link>
            <guid>https://velog.io/@surra7/06.-Redux-%EC%99%80-TDD-2</guid>
            <pubDate>Tue, 05 Mar 2024 00:59:44 GMT</pubDate>
            <description><![CDATA[<h2 id="116-테스트-주도-개발-tdd">116. 테스트 주도 개발 (TDD)</h2>
<h3 id="테스트-주도-개발-test-driven-development">테스트 주도 개발 (Test Driven Development)</h3>
<p>실제 코드를 작성하기 전에 테스트 코드를 먼저 작성함
테스트 코드를 작성한 후 그 테스트 코드를 Pass 할 수 있는 실제 코드를 작성</p>
<h3 id="tdd를-하면-좋은-점">TDD를 하면 좋은 점</h3>
<ol>
<li>TDD를 하면 많은 기능을 테스트하기에 소스 코드에 안정감이 부여됨</li>
<li>실제 개발하면서 많은 시간이 소요되는 부분은 디버깅 부분이기에 TDD를 사용하면 디버깅 시간이 줄어들고 실제 개발 시간도 줄어듬</li>
<li>소스 코드 하나하나를 더욱 신중하게 짤 수 있기 때문에 깨끗한 코드가 나올 확률이 높음</li>
</ol>
<br>

<h2 id="117-react-testing-library">117. React Testing Library</h2>
<p>Create React App으로 리액트 앱을 생성하면 기본적으로 테스팅할 때 React Testing Library를 사용함</p>
<h3 id="react-testing-library란">React Testing Library란?</h3>
<p>DOM Testing Library는 DOM 노드를 테스트하기 위한 매우 가벼운 솔루션
React Testing Library는 이 DOM Testing Library 위에 React 구성요소 작업을 위한 API를 추가하여 구축됨</p>
<p>React Testing Library는 에어비앤비에서 만든 Enzyme를 대체하는 솔루션
Enzyme는 구성 요소의 구현 세부 정보를 테스트하는 반면, React Testing Library는 개발자를 React 애플리케이션의 사용자 입장에 둠</p>
<ul>
<li>Enzyme: 구현 주도 테스트 (Implementation Driven Test)</li>
<li><strong>React Testing Library</strong>: <strong>행위 주도 테스트</strong> (Behavior Driven Test)</li>
</ul>
<br>

<h2 id="118-jest">118. Jest</h2>
<h3 id="jest란">Jest란?</h3>
<p>FaceBook에 의해 만들어진 테스팅 프레임 워크
최소한의 설정으로 동작하며 Test Case를 만들어 애플리케이션 코드가 잘 돌아가는지 확인해줌. 단위(Unit) 테스트를 위해 이용</p>
<h3 id="jest가-test-파일을-찾는-방법">Jest가 Test 파일을 찾는 방법</h3>
<ol>
<li>{filename}.test.js</li>
<li>{filename}.spec.js</li>
<li>&quot;tests&quot; 폴더 안에 테스트 파일을 넣기</li>
</ol>
<br>

<h2 id="119-jest-파일-구조-및-사용법">119. Jest 파일 구조 및 사용법</h2>
<ul>
<li><strong>describe</strong> (과일)<ul>
<li><strong>it</strong> 사과 </li>
<li><strong>it</strong> 바나나</li>
<li><strong>it</strong> 복숭아</li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>&quot;describe&quot;</strong> <em>argument(name, fn)</em>
여러 관련 테스트를 그룹화하는 블록을 만듬</p>
</blockquote>
<blockquote>
<p><strong>&quot;it&quot;</strong> (=== &quot;test&quot;) <em>argument(name, fn, timeout)</em>
개별 테스트를 수행하는 곳. 각 테스트를 작은 문장처럼 설명함
expect &lt;---&gt; matcher 로 구성</p>
</blockquote>
<ul>
<li><p><strong>expect</strong>
expect 함수는 값을 테스트 할 때 마다 사용됨
혼자서는 거의 사용되지 않으며 matcher와 함께 사용됨</p>
</li>
<li><p><strong>matcher</strong>
다른 방법으로 값을 테스트하도록 &quot;매처&quot;를 사용
ex) toBe, toBeCalledWith, toStrictEqual, toBeTruthy ...</p>
</li>
</ul>
<br>

<h2 id="121-쿼리-함수">121. 쿼리 함수</h2>
<h3 id="쿼리-함수란">쿼리 함수란?</h3>
<p>쿼리는 페이지에서 요소를 찾기 위해 테스트 라이브러리가 제공하는 방법
&quot;get&quot;, &quot;find&quot;, &quot;query&quot;가 있음. 이들 간의 차이점은 요소가 발견되지 않으면 쿼리에서 오류가 발생하는지, 또는 Promise를 반환하고 다시 시도하는지 여부</p>
<ul>
<li><p><strong>&quot;getBy...&quot;</strong>
쿼리에 대해 일치하는 노드를 반환하고 일치하는 요소가 없거나 둘 이상일 경우 <strong>오류를 발생</strong>시킴. (둘 이상의 요소가 예상되는 경우 getAllBy 사용)</p>
</li>
<li><p><strong>&quot;queryBy...&quot;</strong>
쿼리에 대해 일치하는 노드를 반환하고 일치하는 요소가 없으면 <strong>null을 반환</strong>. 이것은 존재하지 않는 요소를 어션설하는데 유용. 둘 이상의 일치 항목이 발생되면 오류 발생. (대신 queryAllBy 사용)</p>
</li>
<li><p><strong>&quot;findBy...&quot;</strong>
주어진 쿼리와 일치하는 요소가 발견되면 <strong>Promise 반환</strong>. 요소가 발견되지 않거나 기본 제한 시간인 1000ms 후에 둘 이상의 요소가 발견되면 Promise가 거부됨. (둘 이상의 요소가 예상되는 경우 findAllBy 사용)</p>
</li>
</ul>
<blockquote>
<p><strong>findBy = getBy + waitFor</strong></p>
</blockquote>
<ul>
<li><strong>waitFor</strong>: 일정기간 동안 기다려야 할 때 (비동기 요청) waitFor를 사용하여 기대가 통과될때까지 기다림</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[06. Redux와 TDD - 1]]></title>
            <link>https://velog.io/@surra7/06.-Redux%EC%99%80-TDD-1</link>
            <guid>https://velog.io/@surra7/06.-Redux%EC%99%80-TDD-1</guid>
            <pubDate>Thu, 29 Feb 2024 03:04:26 GMT</pubDate>
            <description><![CDATA[<h2 id="106-리덕스란">106. 리덕스란?</h2>
<h3 id="redux">Redux</h3>
<p>리덕스는 자바스크립트 애플리케이션을 위한 상태 관리 라이브러리</p>
<h3 id="redux-데이터-flow">Redux 데이터 Flow</h3>
<p>redux의 데이터 흐름은 strict unidirectional data flow 으로 한 방향으로 흘러감</p>
<p>Action -&gt; Reducer -&gt; Redux Store -&gt; React Component -&gt; Action</p>
<h4 id="action">Action</h4>
<p>Action은 간단한 자바스크립트 객체. 여기에는 우리가 수행하는 작업의 유형을 지정하는 &#39;type&#39; 속성이 있으며 선택적으로 redux 저장소에 일부 데이터를 보내는데 사용되는 &#39;payload&#39; 속성을 가질 수도 있음</p>
<h4 id="reducer">Reducer</h4>
<p>reducer는 애플리케이션 상태의 변경 사항을 결정하고 업데이트된 상태를 반환하는 함수. 인수로 조치를 취하고 store 내부의 상태를 업데이트함</p>
<p>이전 State와 action object를 받은 후에 next State를 return 함</p>
<pre><code class="language-jsx">(previousSate, action) =&gt; nextSate</code></pre>
<blockquote>
<p><strong>reducer는 순수 함수!</strong>
하지말아야 될 것들</p>
</blockquote>
<ul>
<li>매개변수 변경</li>
<li>API 호출이나 라우팅 변경과 같은 side effects</li>
<li>non-pure 함수 호출 <em>ex) Date.now(), Math.random()</em></li>
</ul>
<h4 id="store">Store</h4>
<p>객체 저장소 Store는 애플리케이션의 전체 상태 트리를 보유. 내부 상태를 변경하는 유일한 방법은 해당 상태에 대한 Action을 전달하는 것. Redux Store는 클래스가 아님. 몇 가지 메소드가 있는 객체일 뿐!</p>
<blockquote>
<p><strong>subscribe()</strong>
change listener를 추가. 작업이 전달될 때마다 호출되며 상태 트리의 일부가 잠재적으로 변경되면 getState()를 호출하여 콜백 내부의 현재 상태 트리를 읽음</p>
</blockquote>
<p>예시)</p>
<pre><code class="language-jsx">const store = createStore(counter);

const render = () =&gt;
  root.render(
    &lt;React.StrictMode&gt;
      &lt;App
        value={store.getState()}
        onIncrement={() =&gt; store.dispatch({ type: &quot;INCREMENT&quot; })}
        onDecrement={() =&gt; store.dispatch({ type: &quot;DECREMENT&quot; })}
      /&gt;
    &lt;/React.StrictMode&gt;
  );

render();
store.subscribe(render);</code></pre>
<br>

<h2 id="109-redux-provider">109. Redux Provider</h2>
<h3 id="provider란">Provider란?</h3>
<p>&lt;Provider&gt; 구성 요소는 Redux Store 저장소에 엑세스해야 하는 모든 중첩 구성 요소에서 Redux Store 저장소를 사용할 수 있도록 해줌</p>
<p>Redux의 모든 React 구성 요소는 저장소에 연결할 수 있으므로 대부분의 응용 프로그램은 전체 앱의 구성 요소가 트리 내부에 있는 최상위 수준에서 &lt;Provider&gt;를 렌더링 함
그런 다음 Hooks 및 연결 API는 React의 컨텍스트 메커니즘을 통해 제공된 저장소 인스턴스에 엑세스 할 수 있음</p>
<br>

<h2 id="110-useselector--usedispatch">110. useSelector &amp; useDispatch</h2>
<h3 id="provider로-둘러-쌓인-컴포넌트에서-store-접근">provider로 둘러 쌓인 컴포넌트에서 store 접근</h3>
<p>리액트에 Hooks가 있듯이 리덕스에도 Hooks가 있는데 그게 바로 useSelector와 useDispatch
이 두 개를 이용해서 provider로 둘러 쌓인 컴포넌트에서 store에 접근 가능</p>
<h3 id="useselector">useSelector</h3>
<p>useSelector Hooks를 이용해서 스토어의 값을 가져올 수 있음</p>
<pre><code class="language-jsx">const counter = useSelector((state) =&gt; state.counter)</code></pre>
<h3 id="usedispatch">useDispatch</h3>
<p>store에 있는 dispatch 함수에 접근하는 Hooks</p>
<br>

<h2 id="111-리덕스-미들웨어">111. 리덕스 미들웨어</h2>
<h3 id="리덕스-미들웨어란">리덕스 미들웨어란?</h3>
<p>Redux 미들웨어는 액션을 dispatch 전달하고 리듀서에 도달하는 순간 사전에 지정된 작업을 실행할 수 있게 해주는 중간자</p>
<p>로깅, 출돌 보고, 비동기 API와 통신, 라우팅 등을 위해 Redux 미들웨어를 사용</p>
<br>

<h2 id="112-redux-thunk">112. Redux Thunk</h2>
<h3 id="리덕스-thunk란">리덕스 Thunk란?</h3>
<p>Redux Thunk도 리덕스 미들웨어이며, 리덕스를 사용하는 앱에서 비동기 작업을 할 때 많이 사용하는 방법</p>
<h3 id="thunk-뜻">Thunk 뜻</h3>
<p>&quot;thunk&quot;라는 단어는 &quot;일부 지연된 작업을 수행하는 코드 조각&quot;을 의미하는 프로그래밍 용어
지금 일부 로직을 실행하는 대신 나중에 작업을 수행하는데 사용할 수 있는 함수 본문이나 코드를 작성할 수 있음</p>
<h3 id="결론">결론</h3>
<p>리덕스 thunk를 사용함으로써 액션 생성자가 그저 하나의 액션 객체를 생성할 뿐 아니라 그 내부 안에서 여러 가지 작업도 할 수 있게 만들어 줌</p>
<br>

<h2 id="113-리덕스-툴킷-redux-toolkit">113. 리덕스 툴킷 (redux toolkit)</h2>
<h3 id="리덕스-툴킷">리덕스 툴킷</h3>
<p>Redux 툴킷은 리덕스 로직을 작성하기 위한 공식 권장 접근 방식
Redux 코어를 둘러싸고 있으며 Redux 앱을 빌드하는데 필수적이라고 생각하는 패키지와 기능이 포함되어 있음
리덕스 툴킷은 제안된 모범 사례를 기반으로 대부분의 리덕스 작업을 단순화하고 일반적인 실수를 방지해주며 리덕스 애플리케이션을 더 쉽게 작성할 수 있도록 함</p>
<br>

<h2 id="114-리덕스-툴킷-apis">114. 리덕스 툴킷 APIs</h2>
<h3 id="store-생성">Store 생성</h3>
<p>기존 Redux는 createStore를 통해 Store 생성
리덕스 툴킷에서는 <strong>configureStore</strong>를 통해 생성</p>
<h3 id="action-생성">Action 생성</h3>
<p>액션 타입 상수와 액션 생성자 함수 생성을 createAction 함수 하나로 처리</p>
<ul>
<li>createAction은 type만 넣으면 자동으로 해당 type을 가진 action creator 함수를 생성함</li>
<li>생성된 함수를 호출할 때 인수를 추가로 넣으면 이 값은 payload 프로퍼티 값으로 들어감</li>
</ul>
<h3 id="reducer-생성">Reducer 생성</h3>
<p>createReducer에서 Action을 처리하기 위해 케이스 리듀서를 정의하는 방법은 &quot;빌더 콜백&quot;(builder callback) 표기법과 &quot;맵 객체&quot;(map object) 표기법 두 가지가 있음. 둘 다 동일한 기능이지만 타입스크립트와의 호환성을 위해 &quot;빌더 콜백&quot; 표기법이 더 선호됨</p>
<h4 id="builder-callback-표기법">builder callback 표기법</h4>
<p>createReducer(initialState, builderCallback)</p>
<ul>
<li><p><strong>builder.addCase(actionCreator, reducer):</strong>
액션 타입과 정확히 맵핑되는 케이스 리듀서를 추가하여 액션을 처리
addMatcher 또는 addDefaultCase 보다 먼저 작성되어야 함</p>
</li>
<li><p><strong>builder.addMatcher(matcher, reducer):</strong>
새로 들어오는 모든 액션에 대해서 주어진 패턴과 일치하는지 확인하고 리듀서를 실행함</p>
</li>
<li><p><strong>builder.addDefaultCase(reducer):</strong>
다른 케이스 리듀서나 매처 리듀서가 실행되지 않았다면 실행되는 기본 케이스 리듀서</p>
</li>
</ul>
<h4 id="map-object-표기법">map object 표기법</h4>
<p>createReducer(initialState, actionMap, actionMatchers, defaultCaseReducer)</p>
<ul>
<li><p><strong>initialSate:</strong> 리듀서를 처음 호출할 때 사용해야 하는 초기 상태 값</p>
</li>
<li><p><strong>actionsMap:</strong> 액션 타입이 케이스 리듀서에 맵핑되어 있는 객체</p>
</li>
<li><p><strong>actionMatchers:</strong> 
{matcher, reducer} 형식으로 정의된 배열
케이스 리듀서가 일치하는지 여부에 관계없이 모든 일치하는 리듀서가 순서대로 실행됨</p>
</li>
<li><p><strong>defaultCaseReducer:</strong>
케이스 리듀서 및 매처 리듀서가 실행되지 않은 경우 실행되는 기본 케이스 리듀서</p>
</li>
</ul>
<h3 id="createslice">createSlice()</h3>
<p>이 API는 Redux Logic을 작성하기 위한 표준 접근 방식
createSlice 내부에 createAction과 createReducer를 사용</p>
<p>createSlice 함수는 리듀서 함수의 초기 상태와 &#39;slice 이름&#39;을 받아 리듀서와 상태에 해당하는 액션 생성자와 액션 타입을 자동으로 생성하는 함수</p>
<h3 id="extrareducers">extraReducers</h3>
<p>extraReducers를 사용하면 createSlice가 생성한 action type 외에 다른 action type에 응답할 수 있음</p>
<p>extra Reducers로 지정된 케이스 리듀서는 &#39;외부&#39;액션을 참조하기 위한 것으로, 그들은 slice.actions에서 생성된 액션을 가지지 않음</p>
<h3 id="createasyncthunk">createAsyncThunk</h3>
<p>createAction의 비동기 버전</p>
<pre><code class="language-jsx">function createAsyncThunk(type, payloadCreator, options)</code></pre>
<ul>
<li><p><strong>type</strong>: 비동기 요청의 생명주기를 나타내는 추가 Redux <strong>action type 상수를 생성하는데 사용되는 문자열</strong>
예를들어 &#39;users/requestStatus&#39; type 인수는 다음과 같은 action type을 생성</p>
<ul>
<li>pending: &#39;users/requestStatus/pending&#39;</li>
<li>fulfilled: &#39;users/requestStatus/fulfilled&#39;</li>
<li>rejected: &#39;users/requestStatus/rejected&#39;</li>
</ul>
</li>
<li><p><strong>payloadCreator</strong>: Promise를 반환하는 콜백 함수</p>
<ul>
<li><strong>thunkAPI</strong>: 일반적으로 Redux thunk 함수에 전달되는 모든 매개변수와 추가 옵션을 포함하는 객체</li>
<li><strong>dispatch</strong>: Redux 스토어 dispatch 메서드</li>
<li><strong>getState</strong>: Redux 스토어 getState 메서드</li>
<li><strong>extra</strong>: 설정시 thunk 미들웨어에 제공되는 &#39;추가 인수&#39;(사용 가능한 경우)</li>
<li><strong>requestId</strong>: 이 요청 시퀀스를 식별하기 위해 자동으로 생성되는 고유 문자열 ID 값</li>
<li><strong>signal</strong>: 앱 로직의 다른 부분이 이 요청을 취소가 필요한 것으로 표시했는지 확인하는데 사용할 수 있는 AbortController.signal 객체</li>
<li><strong>rejectWithValue(value, [meta])</strong>: 정의된 페일드 및 메타와 함께 거부된 응답을 반환하기 위해 작업 생성자에서 반환(또는 throw)할 수 있는 유틸리티 함수</li>
<li><strong>fulfilledWithValue(value, meta)</strong>: fulfilledAction.meta에 추가할 수 있는 기능을 가지고 있는 동안 값으로 이행하기 위해 작업 생성자에서 반환할 수 있는 유틸리티 함수</li>
</ul>
</li>
</ul>
<h3 id="cancellation">cancellation</h3>
<p>thunk 실행 중 취소하기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[05. React Context]]></title>
            <link>https://velog.io/@surra7/05.-React-Context</link>
            <guid>https://velog.io/@surra7/05.-React-Context</guid>
            <pubDate>Tue, 27 Feb 2024 06:45:47 GMT</pubDate>
            <description><![CDATA[<h2 id="88-리액트-context란">88. 리액트 Context란?</h2>
<p>리액트에서 한 컴포넌트 안에서 데이터를 생성하고 업데이트하거나 다른 컴포넌트와 데이터를 공유해서 사용하는 방법은 여러가지가 있음</p>
<p>리액트에서 데이터 흐름을 컨트롤하는 방법 (state 관리하는 방법)</p>
<ul>
<li>state와 props를 사용해서 컴포넌트 간에 전달</li>
<li><strong>React Context</strong> 사용</li>
<li>mobx 사용</li>
<li>redux 사용</li>
<li>...</li>
</ul>
<h3 id="react-context">React Context</h3>
<p>React Context는 컴포넌트 트리의 깊이에 관계없이 props를 전달하지 않고도 다른 컴포넌트에 데이터를 제공함. Context는 전역 데이터를 관리하는데 사용됨
ex) 전역 상태, 테마, 서비스, 사용자 설정 등</p>
<h3 id="react-context를-사용하는-이유">React Context를 사용하는 이유</h3>
<p>상태를 내려줄 부모와 자식 컴포넌트 사이의 깊이가 1이라면 상관없지만 깊이가 깊으면 props를 이용해서 계속 내려줘야 하므로 번거로움</p>
<br>

<h2 id="89-context-api-살펴보기">89. Context API 살펴보기</h2>
<h3 id="reactcreatecontext">React.createContext</h3>
<pre><code class="language-jsx">const MyContext = React.createContext(defaultValue);</code></pre>
<p>Context 객체를 생성. React가 이 Context 객체를 구독하는 구성 요소를 렌더링 할 때 트리에서 그 위에 가장 근접하게 일치하는 Provider에서 현재 Context 값을 읽어옴</p>
<p>defaultValue 인수는 트리에서 구성 요소 위에 일치하는 공급자가 없는 경우에만 사용됨
Context를 사용하고자하는 컴포넌트들을 Provider로 감싸줌. 그러면 그 자식 컴포넌트들은 모두 Context를 사용할 수 있음</p>
<h3 id="reactprovider">React.Provider</h3>
<p>모든 Context 객체에는 Consumer Component가 Context 변경 사항을 구독할 수 있도록 하는 Provider React 구성 요소가 함께 제공됨</p>
<pre><code class="language-jsx">&lt;MyContext.Provider value={/* some value */}&gt;
  &lt;AComponent /&gt;
  &lt;BComponent /&gt;
  &lt;CComponent /&gt;
&lt;/MyContext.Provider&gt;</code></pre>
<p>A, B, C Component가 모두 Context를 구독중
Context value에 변경 사항이 생기면 컴포넌트를 다시 렌더링 함</p>
<p>변경 사항은 Object.js와 동일한 알고리즘(sameValue)을 사용하여 새 값과 이전 값을 비교하여 결정됨</p>
<h3 id="classcontexttype">Class.contextType</h3>
<p>클래스 컴포넌트에서는 contextType 속성에 React.createContext()에 의해 생성된 Context 객체를 할당하여 context를 사용할 수 있음</p>
<p>this.context를 사용하여 해다 context 유형의 가장 가까운 현재 value를 사용할 수 있음. 렌더링 기능을 포함한 모든 수명 추가 메서드에서 이를 참조할 수 있음</p>
<h4 id="objectis-vs-">Object.is vs ===</h4>
<p>Object.is 와 &#39;===&#39; 둘 다 타입을 구분해서 비교를 해줌. 하지만 &#39;===&#39;은 +0과 -0을 같다고 판단함</p>
<pre><code class="language-jsx">+0 === -0 // ---&gt; true
Object.is(+0, -0) // ---&gt; false</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[03. 만들면서 배우는 React (Apple TV) - 2]]></title>
            <link>https://velog.io/@surra7/03.-%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-React-Apple-TV-2</link>
            <guid>https://velog.io/@surra7/03.-%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-React-Apple-TV-2</guid>
            <pubDate>Thu, 22 Feb 2024 05:33:11 GMT</pubDate>
            <description><![CDATA[<h2 id="65-react-router-dom">65. React Router Dom</h2>
<h3 id="react-router-dom이란">React Router Dom이란?</h3>
<p>React Router Dom을 사용하면 웹 앱에서 동적 라우팅을 구현할 수 있음
라우팅이 실행 중인 웹 외부의 구성에서 처리되는 기존 라우팅 아키텍처와 달리 React Router Dom은 앱 및 플랫폼의 요구 사항에 따라 컴포넌트 기반 라우팅을 용이하게 함</p>
<h3 id="single-page-applicationspa">Single Page Application(SPA)</h3>
<p>리액트는 SPA이기 때문에 하나의 index.html 템플릿 파일을 가지고 있음. 자바스크립트를 이용해서 다른 컴포넌트를 이 index.html 템플릿에 넣음으로써 페이지를 변경함. 이 때 React Router Dom 라이브러리가 새로운 컴포넌트로 라우팅/탐색을 하고 렌더링하는데 도움을 줌</p>
<h3 id="설치하기">설치하기</h3>
<ul>
<li>npm install react-router-dom --save</li>
<li>yarn add react-router-dom</li>
</ul>
<h3 id="설정하기">설정하기</h3>
<p>설치 후 앱 어디에서나 React Router를 사용할 수 있도록 설정하려면 src 폴더에 있는 index.js 파일을 열고 react-router-dom에서 BrowserRouter를 가져온다음 루트 구성요소(App 구성 요소)를 그 안에 래핑하면 됨</p>
<pre><code class="language-jsx">import { BrowserRouter } from &#39;react-router-dom&#39;;

ReactDOM.render(
  &lt;BrowserRouter&gt;
    &lt;App /&gt;
  &lt;/BrowserRouter&gt;
  document.getElementById(&#39;root&#39;)
);</code></pre>
<blockquote>
<p><strong>BrowserRouter</strong>
HTML5 Histroy API(pushState, replaceState 및 popstate 이벤트)를 사용하여 UI를 URL과 동기화된 상로 유지해줌</p>
</blockquote>
<h4 id="여러-컴포넌트에-라우트-정의하기">여러 컴포넌트에 라우트 정의하기</h4>
<pre><code class="language-jsx">function App(){
  return (
    &lt;div className=&quot;App&quot;&gt;
      &lt;Routes&gt;
        &lt;Route path=&quot;/&quot; elements={&lt;Home /&gt;} /&gt; // https://localhost:3000/
        &lt;Route path=&quot;about&quot; elements={&lt;About /&gt;} /&gt; // https://localhost:3000/about
        &lt;Route path=&quot;contact&quot; elements={&lt;Contact /&gt;} /&gt; // https://localhost:3000/contact
      &lt;/Routes&gt;
    &lt;/div&gt;
  )
}</code></pre>
<blockquote>
<p><strong>Routes</strong>
Routes는 앱에서 생성될 모든 개별 경로에 대한 컨테이너/상위 역할
Route로 생성된 자식 컴포넌트 중에서 매칭되는 첫번째 Route를 렌더링 해줌</p>
</blockquote>
<blockquote>
<p><strong>Route</strong>
Route는 단일 경로를 만드는 데 사용함. 두가지 속성을 가짐</p>
</blockquote>
<ul>
<li>path: 원하는 컴포넌트의 URL 경로를 지정. 이 경로 이름을 원하는 대로 정할 수 있음
경로 이름이 &#39;/&#39;인 컴포넌트는 앱이 처음 로드될 때마다 먼저 랜더링됨</li>
<li><blockquote>
<p>Home 구성 요소가 맨 처음으로 렌더링됨</p>
</blockquote>
</li>
<li>element: 경로에 맞게 렌더링되어야 하는 컴포넌트를 지정</li>
</ul>
<h4 id="link-를-이용해-경로-이동">&lt;Link /&gt;를 이용해 경로 이동</h4>
<pre><code class="language-jsx">import { Link } from &#39;react-router-dom&#39;;

function Home() {
  return (
    &lt;div&gt;
      &lt;h1&gt;홈페이지&lt;/h1&gt;
      &lt;Link to=&quot;about&quot;&gt;About 페이지를 보여주기&lt;/Link&gt;
      &lt;Link to=&quot;contact&quot;&gt;Contact 페이지를 보여주기&lt;/Link&gt;
    &lt;/div&gt;
  );
}

export default Home;</code></pre>
<p>Link 구성 요소는 HTML의 앵커 요소 &lt;a /&gt;와 유사함. to 속성으로 링크가 이동할 경로를 지정함</p>
<br>

<h2 id="66-react-router-dom-apis">66. React Router Dom APIs</h2>
<h3 id="중첩-라우팅nested-routes">중첩 라우팅(Nested Routes)</h3>
<p>중첩 라우팅은 React Router의 가장 강력한 기능 중 하나
복잡한 레이아웃 코드를 좀 더 간결하게 해결해줌
대부분의 레이아웃은 URL의 세그먼트에 연결되며 React Router는 이를 완전히 수용</p>
<pre><code class="language-jsx">&lt;BrowserRouter&gt;
  &lt;Routes&gt;
    // App 컴포넌트에 Header나 Footer 등의 Layout
    &lt;Route path=&quot;/&quot; element={&lt;App /&gt;}&gt;
      // localhost:3000/ =&gt; Home 컴포넌트 렌더링
      &lt;Route index element={&lt;Home /&gt;} /&gt;
      // localhost:3000/teams =&gt; Teams 컴포넌트가 Layout
      &lt;Route path=&quot;teams&quot; element={&lt;Teams /&gt;}&gt;
        // localhost:3000/teams/13 =&gt; Team 컴포넌트
        &lt;Route path=&quot;:teamId&quot; element={&lt;Team /&gt;} /&gt;
        &lt;Route path=&quot;new&quot; element={&lt;NewTeamForm /&gt;} /&gt;
        // localhost:3000/teams =&gt; LeagueStandings 컴포넌트 렌더링
        &lt;Route index element={&lt;LeagueStandings /&gt;} /&gt;
      &lt;/Route&gt;
    &lt;/Route&gt;
  &lt;/Routes&gt;
&lt;/BrowserRouter&gt;</code></pre>
<h3 id="outlet">Outlet</h3>
<p>자식 경로 요소를 렌더링하려면 부모 경로 요소에서 &lt;Outlet /&gt;을 사용해야 함. 이렇게 하면 하위 경로가 렌더링될 때 중첩된 UI가 표시될 수 있음. 부모 라우트가 정확히 일치하면 자식 인덱스 라우트를 렌더링하거나 인덱스 라우트가 없으면 아무것도 렌더링 하지 않음</p>
<h3 id="usenavigate">useNavigate</h3>
<p>경로를 바꿔줌. ex) navigate(&#39;/home&#39;) ===&gt; localhost:3000/home</p>
<h3 id="useparams">useParams</h3>
<p>:style 문법을 path 경로에 사용하였다면 useParams()로 읽을 수 있음</p>
<pre><code class="language-jsx">function App() {
  return (
    &lt;Routes&gt;
      &lt;Route path=&quot;invoices/:invoiceId&quot; element={&lt;Invoice /&gt;} /&gt;
    &lt;/Routes&gt;
  );
}

function Invoice(){
  let params = useParams();
  return &lt;h1&gt;Invoice {params.invoiceId}&lt;/h1&gt;;
}</code></pre>
<h3 id="uselocation">useLocation</h3>
<p>이 Hooks는 현재 위치의 객체를 반환. 현재 위치가 변경될 때 마다 일부 side effect를 수행하려는 경우에 유용</p>
<h3 id="useroutes">useRoutes</h3>
<p>useRoutes Hooks는 &lt;Routes&gt;와 기능적으로 동일하지만 &lt;Route&gt; 요소 대신 JavaScript 객체를 사용하여 경로를 정의함
이러한 객체는 일반 &lt;Route&gt; 요소와 동일한 속성을 갖지만 JSX가 필요하지 않음</p>
<br>

<h2 id="71-usedebouce-custom-hooks-만들기">71. useDebouce Custom Hooks 만들기</h2>
<h3 id="debounce란">Debounce란?</h3>
<p>원래는 입력창에 입력한 값이 onChange를 이용하면 바로 화면에 적용됨
하지만 debounce function을 이용하면 미리 결정해 놓은 시간 동안 타이핑을 멈출 때까지 keyup 이벤트의 처리를 지연시킴</p>
<p>입력된 모든 문자를 처리하면 성능이 저하되고 밴엔드에 불필요한 로드가 추가될 수 있음. 하지만 debounce를 이용하면 UI 코드가 모든 이벤트를 처리할 필요가 없고 서버로 전송되는 API 호출 수도 크게 줄어듬</p>
<br>

<h2 id="75-useonclickoutside-hookds-생성">75. useOnClickOutside Hookds 생성</h2>
<p>모달창 바깥을 클릭했을 때 모달창이 닫히도록 만들기 -&gt; 어디를 클릭했는지 구분해주어야 함 -&gt; useRef</p>
<h3 id="useref란">useRef란?</h3>
<ul>
<li>변수 관리</li>
<li>특정 DOM을 선택할 때 사용하는 React 빌트인 Hooks</li>
</ul>
<h3 id="변수-관리">변수 관리</h3>
<p>state를 사용하면 state가 변할때 컴포넌트가 다시 렌더링 되지만 ref를 사용하면 리 렌더링이 되지 않음 (생명주기 동안 ref 값은 유지됨)</p>
<h3 id="특정-dom-선택하기">특정 DOM 선택하기</h3>
<p>보통 JavaScript에서는 getElementById나 querySelector 같은 DOM Selector 함수를 사용해서 특정 DOM 선택
리액트에서는 ref를 이용해서 DOM을 선택함</p>
<ul>
<li>클래스형 컴포넌트: React.createRef()라는 함수 사용</li>
<li>함수형 컴포넌트: useRef() 사용</li>
</ul>
<h4 id="useref-사용법">useRef 사용법</h4>
<p>useRef()를 이용해 Ref 객체를 만들고, 이 객체를 특정 DOM에 ref 값으로 설정. 이렇게 되면 Ref 객체의 .current 값이 특정 DOM을 가리키게 됨</p>
<h4 id="dom을-직접-선택해야하는-경우들">DOM을 직접 선택해야하는 경우들</h4>
<ol>
<li>앨리먼트에 포커스를 설정해줘야 할 때</li>
<li>앨리먼트 크기를 가져와야 할 때</li>
<li>스크롤바 위치를 가져와야 할 때 등</li>
</ol>
<br>

<h2 id="78-react-portal로-모달-생성">78. React Portal로 모달 생성</h2>
<h3 id="문제점">문제점</h3>
<p>구조가 복잡하게 짜여있는 경우 Modal 요소 부분이 DOM 계층 구조에서 z-index 등의 영향을 받아서 맨 앞으로 가지 못하거나 원하는 모달 스타일을 가지지 못할 수가 있음</p>
<h3 id="portal">Portal</h3>
<p>Portal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링하는 최고의 방법을 제공</p>
<h4 id="이벤트-버블링-가능">이벤트 버블링 가능</h4>
<p>Portal의 특징 중 하나는 이벤트 버블링이 가능하다는 것
이벤트 버블링이란 중첩된 자식 요소에서 이벤트가 발생할 때 그 이벤트가 부모로 전달되는 것
비록 포탈로 생성한 부분이 부모 DOM 밖에 생성되더라도 DOM 트리에서의 위치에 상관없이 portal은 여전히 React 트리에 존재. 따라서 React 트리에 포함된 상위로 이벤트 버블링이 가능함</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[03. 만들면서 배우는 React (Apple TV) - 1]]></title>
            <link>https://velog.io/@surra7/03.-%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-React-Apple-TV-1</link>
            <guid>https://velog.io/@surra7/03.-%EB%A7%8C%EB%93%A4%EB%A9%B4%EC%84%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-React-Apple-TV-1</guid>
            <pubDate>Tue, 20 Feb 2024 09:37:33 GMT</pubDate>
            <description><![CDATA[<h2 id="46-vite란">46. Vite란?</h2>
<h3 id="vite를-사용하는-이유">Vite를 사용하는 이유</h3>
<p>vite의 가장 큰 장점은 빌드 속도나 새로운 코드를 적용했을 때의 반영 속도 같은 Feedback 속도의 엄청난 개선</p>
<ul>
<li>브라우저에서 ES 모듈을 사용할 수 있기 전에는 개발자에게 모듈화된 방식으로 JavaScript를 작성하는 기본 메커니즘이 없었음 </li>
<li>그래서 &#39;번들링&#39;이 필요. webpack, Rollup 및 Parcel과 같은 도구로 번들링 해결</li>
<li>그러나 점점 더 큰 애플리케이션을 구축하기 시작하면서 처리하는 JavaScript와 모듈의 양이 크게 증가</li>
<li>자바스크립트 기반 도구에 대한 성능 병목 현상이 발생하기 시작함. 개발 서버를 가동하는 데 종종 너무 오랜 시간이 걸리거나 HMR을 사용하더라도 파일 편집이 반영되는 데 몇 초가 걸리는 문제점이 생김</li>
</ul>
<p>-&gt; Vite는 생태계의 새로운 발전을 활용하여 이러한 문제를 해결하는 것을 목표로 함</p>
<h3 id="vite를-이용해서-속도-개선을-하는-방법">Vite를 이용해서 속도 개선을 하는 방법</h3>
<p>개발 서버를 스타트할 때 번들러 기반 빌드 설정은 서비스를 제공하기 전에 전체 애플리케이션을 열심히 크롤링하고 빌드해야 함</p>
<h4 id="--느린-서버-시작-속도">-&gt; 느린 서버 시작 속도</h4>
<p>vite는 먼저 애플리케이션의 모듈을 <strong>종속성</strong>과 <strong>소스 코드</strong>의 두 가지 범주로 나누어 개발 서버 시작 시간을 개선함</p>
<ul>
<li><p><strong>종속성(Dependencies)</strong>은 대부분 개발 중에 자주 변경되지 않는 일반 JavaScript. 일부 큰 종속성도 처리하는데 큰 비용이 듬. 종속성은 다양한 모듈 형식 (ESM, CommonJS 등)으로 제공 될 수 있음</p>
</li>
<li><p>vite는 <strong>esbuild를 사용하여 종속성을 사전 번들로 제공</strong>. esbuild는 Go로 작성되어 있으며 JavaScript 기반 번들러보다 10~100배 더 빠르게 종속성을 사전 번들링함</p>
</li>
<li><p><strong>Soure Code</strong>에는 변환이 필요한 일반 JavaScript가 아닌 경우가 많으며 매우 자주 편집됨. 또한 모든 소스 코드를 동시에 로드할 필요는 없음</p>
</li>
<li><p>vite는 Native ESM을 통해 소스 코드 제공. 이것은 브라우저가 번들러 작업의 일부를 인계받게 하는 것. vite는 <strong>브라우저가 요청할 때만 소스 코드를 변환하고 제공하기만 하면 됨</strong>. 조건부 동적 가져오기 뒤에 있는 코드는 현재 화면에서 실제로 사용되는 경우에만 처리됨</p>
</li>
</ul>
<h4 id="--느린-서버-업데이트-속도">-&gt; 느린 서버 업데이트 속도</h4>
<p>번들러 기반 빌드 설정에서 파일을 편집할 때 명백한 이유로 전체 번들을 다시 빌드하는 것은 비효율적. 업데이트 속도는 앱 크기에 따라 선형적으로 저하됨</p>
<p>일부 번들러는 개발 서버는 파일이 변경될 때 모듈 그래프의 일부만 무효화하면 되지만 전체 번들을 다시 구성하고 웹 페이지를 다시 로드해야 하도록 메모리에서 번들링을 실행함. 번들을 재구성하는데 비용이 많이 들 수 있으며 페이지를 다시 로드하면 애플리케이션의 현재 상태가 손상됨. 이것이 일부 번들러가 핫 모듈 교체(HMR)을 지원하는 이유.
<strong>페이지의 나머지 부분에 영향을 주지 않고 모듈 자체를 &quot;Hot Module Replacement&quot;</strong> 할 수 있음. 이것은 DX(Developer Experience)를 크게 향상시킴. 그러나 실제로 HMR 업데이트 속도도 응용 프로그램의 크기가 증가함에 따라 크게 저하된다는 것을 발견함</p>
<h3 id="hmrhot-module-replace란">HMR(Hot Module Replace)란?</h3>
<p>파일을 편집할 때 전체 번들을 다시 빌드하는 것이 아닌 페이지의 나머지 부분에 영향을 주지 않고 변경된 모듈 자체를 교체해서 빠르게 화면에 반영되게 하는 것</p>
<p>Vite에서 HMR은 기본 ESM을 통해 수행됨. 파일이 편집될 때 Vite는 편집된 모듈과 가장 가까운 <strong>HMR 경계(대부분의 경우 모듈 자체만) 사이의 체인을 정확하게 무효화하여 애플리케이션의 크기에 관계없이 HMR 업데이트가 일관되게 빨라짐</strong></p>
<p>Vite는 또한 HTTP 헤더를 활용하여 전체 페이지 로드 속도를 높임. 소스 코드 모듈 요청은 &#39;304 Not Modified&#39;를 통해 조건부로 이루어지며 종속성 모듈 요청은 &#39;Cache-Control: max-age=31536000, immutable&#39;을 통해 강력하게 캐시됨. 따라서 한 번 캐시되면 서버에 다시 도달하지 않음</p>
<h3 id="typescript-transpiling-속도">Typescript Transpiling 속도</h3>
<p>Vite를 이용하면 기본적으로 Typescript 사용을 지원하며 esbuild를 이용해서 transpiling을 하기 때문에 훨씬 빠른 속도로 할 수 있음. 하지만 타입 checking 기능은 없음. 이미 에디터 내에서 다른 것들이 타입 체킹을 하기 때문에 transpiling만 제공</p>
<br>

<h2 id="47-the-movie-db-api-생성하기">47. The Movie DB API 생성하기</h2>
<p><a href="https://www.themoviedb.org/">https://www.themoviedb.org/</a></p>
<br>

<h2 id="48-axois-인스턴스-생성-및-요청-보내기">48. Axois 인스턴스 생성 및 요청 보내기</h2>
<h3 id="axois란">Axois란?</h3>
<p>Axois는 브라우저, Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리
백엔드와 프론트엔드의 통신을 쉽게하기 위해 Ajax와 더불어 사용함</p>
<h3 id="사용방법">사용방법</h3>
<ul>
<li>axois 모듈 설치: npm install axios --save</li>
<li>axios.get(&#39;&#39;)</li>
</ul>
<h3 id="axios를-인스턴스화-하는-이유">axios를 인스턴스화 하는 이유</h3>
<p>중복된 부분을 계속 입력하지 않아도 되기 때문에</p>
<br>

<h2 id="50-styled-component">50. Styled Component</h2>
<h3 id="styled-component란">Styled Component란?</h3>
<p>Styled Component란 CSS-in-JS라고 하는 Javascript 파일 안에서 CSS를 처리할 수 있게 해주는 대표적인 라이브러리</p>
<p><a href="https://styled-components.com/docs/basics">https://styled-components.com/docs/basics</a></p>
<h3 id="장점">장점</h3>
<ul>
<li><p>컴포넌트는 props를 내려줄 수 있음. 마찬가지로 styled 컴포넌트에도 props를 사용할 수 있으며 내려받은 props를 이용해 조건을 줘서 다양한 스타일을 적용해 줄 수 있음 </p>
</li>
<li><p>클래스는 확장(extending)이 가능함. 마찬가지로 styled 컴포넌트도 부모 컴포넌트를 확장 받을 수 있음</p>
</li>
</ul>
<h3 id="설치-방법">설치 방법</h3>
<ul>
<li>npm install --save styled-components</li>
<li>yarn add styled-components</li>
</ul>
<br>

<h2 id="57-비디오-배너-생성하기">57. 비디오 배너 생성하기</h2>
<h3 id="iframe이란">Iframe이란?</h3>
<p>유튜브 비디오를 가져오기 위해서 사용!</p>
<p>Iframe은 HTML Inline Frame 요소이며 inline frame의 약자이다
효과적으로 <strong>다른 HTML 페이지를 현재 페이지에 포함</strong>시키는 중첩된 브라우저로 iframe 요소를 이용하면 해당 웹 페이지 안에 어떠한 제한 없이 다른 페이지를 불러와서 삽입할 수 있음</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[02. React 활용해 보기 - 2]]></title>
            <link>https://velog.io/@surra7/02.-React-%ED%99%9C%EC%9A%A9%ED%95%B4-%EB%B3%B4%EA%B8%B0-2</link>
            <guid>https://velog.io/@surra7/02.-React-%ED%99%9C%EC%9A%A9%ED%95%B4-%EB%B3%B4%EA%B8%B0-2</guid>
            <pubDate>Mon, 19 Feb 2024 07:52:44 GMT</pubDate>
            <description><![CDATA[<h2 id="39-reactmemo를-이용한-성능-최적화">39. React.memo를 이용한 성능 최적화</h2>
<p>React.memo를 이용해 B 컴포넌트의 성능 최적화하기</p>
<h3 id="현재-b-컴포넌트의-문제점">현재 B 컴포넌트의 문제점</h3>
<p>B 컴포넌트는 B, List, ListItem, message 컴포넌트로 나눠져 있음
input에 글을 타이핑 할 때 원래는 message 컴포넌트와 그 state를 갖고 있는 app 컴포넌트만 렌더링이 돼야 하는데 현재는 상관 없는 다른 부분들까지 모두 렌더링 되고 있음</p>
<h3 id="reactmemo-적용으로-문제-해결">React.memo 적용으로 문제 해결</h3>
<p>React.memo 적용은 간단하게 원하는 컴포넌트를 React.memo로 감싸주면 됨
-&gt; 렌더링이 필요치 않은 List, ListItem 컴포넌트는 렌더링이 안됨</p>
<p><img src="https://velog.velcdn.com/images/surra7/post/b1fe5776-9adf-45ff-8015-751980a175bd/image.jpg" alt=""></p>
<p>-&gt; B 컴포넌트의 성능이 확연히 좋아짐 (A: 1.5ms, B: 0.1ms)</p>
<h3 id="reactmemo란">React.memo()란?</h3>
<p>React는 먼저 컴포넌트를 렌더링 한 뒤, 이전에 렌더링 된 결과와 비교하여 DOM 업데이트를 결정
만약 렌더링 결과가 이전과 다르다면, React는 DOM을 업데이트 함</p>
<p>이 과정에서 만약 컴포넌트가 React.memo()로 둘러 쌓여 있다면, <strong>React는 컴포넌트를 렌더링하고 결과를 메모이징(Memoizing)</strong>한다. 그리고 다음 렌더링이 일어날 때 렌더링하는 컴포넌트의 props가 같다면, React는 메모이징된 내용을 재사용한다.</p>
<blockquote>
<p><strong>메모제이션 (Memoization)</strong> 이란?
Memoization은 주어진 입력값에 대한 결과를 저장함으로써 같은 입력값에 대해 함수가 한 번만 실행되는 것을 보장함</p>
</blockquote>
<h4 id="react-memo가-props를-비교하는-방법은">React Memo가 props를 비교하는 방법은?</h4>
<p>React.memo()는 props 혹은 props의 객체를 비교할 때 <strong>얕은 비교</strong>를 함</p>
<h4 id="react-memo-props-비교-방식-수정하기">React Memo Props 비교 방식 수정하기</h4>
<p>비교 방식을 원하는 대로 수정하고 싶다면 React.memo()의 두 번째 매개변수로 비교함수를 넣어주면 됨</p>
<p>예시)</p>
<pre><code class="language-jsx">React.memo(Component, [compareFunction(prevProps, nextProps)]);

function compareFunction(prevProps, nextProps) {
  return (
    prevProps.a === nextProps.a &amp;&amp;
    prevProps.b === nextProps.b
  )
}</code></pre>
<h4 id="react-memo-사용을-지양해야하는-상황">React Memo 사용을 지양해야하는 상황</h4>
<p>렌더링 될 때 props가 다른 경우가 대부분인 컴포넌트인 경우, 메모이제이션 기법의 이점을 얻기 힘듬</p>
<p>props가 자주 변하는 컴포넌트를 React.memo()로 래핑 할지라도, React는 두 가지 작업을 렌더링 할때마다 수행함</p>
<ol>
<li>이전 props와 다음 props의 동등 비교를 위해 비교 함수 수행</li>
<li>비교 함수는 거의 항상 false를 반환할 것이기 때문에, React는 이전 렌더링 내용과 다음 렌더링 내용을 비교함</li>
</ol>
<p>-&gt; 비교 함수 결과가 대부분 false 라면 props 비교는 불필요</p>
<h4 id="reactmemo는-리-렌더링을-막기-위한-도구보다-성능-개선의-도구">React.memo()는 리 렌더링을 막기 위한 도구보다 성능 개선의 도구</h4>
<p>React에서 메모이제이션은 성능 개선을 위한 하나의 도구
대부분의 상황에서 React는 메모이징 된 컴포넌트의 리 렌더링을 피할 수 있지만, 렌더링을 막기 위해 메모이제이션에 너무 의존하면 안됨 (버그 유발 가능성)</p>
<h4 id="결론">결론</h4>
<p>리액트에서 렌더링 성능 최적화를 위해서는 컴포넌트를 분리하고 React.memo를 사용하면 됨
또한 React.memo 사용은 항상 좋은 것은 아니기에 profiler를 이용해서 성능상 이점이 있는지 확인 후 사용하면 좋음</p>
<br>

<h2 id="40-얕은-비교-shallow-equal">40. 얕은 비교 (Shallow Equal)</h2>
<h3 id="얕은-비교란">얕은 비교란?</h3>
<p>숫자, 문자열 등 원시 자료형은 값을 비교
배열, 객체 등 참조 자료형은 값 혹은 속성을 비교하지 않고, 참조되는 위치를 비교</p>
<pre><code class="language-jsx">const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };

console.log(obj1 === obj2); // false</code></pre>
<h3 id="깊은-비교란">깊은 비교란?</h3>
<p>얕은 비교와 달리 깊은 비교는 객체의 경우에도 갚으로 비교함</p>
<ol>
<li>Object depth가 깊지 않은 경우: JSON.stringify() 사용</li>
<li>Object depth가 깊은 경우: lodash 라이브러리의 isEqual() 사용</li>
</ol>
<pre><code class="language-jsx">const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };

console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // true</code></pre>
<h3 id="얕은-비교는-언제-사용하나요">얕은 비교는 언제 사용하나요?</h3>
<ol>
<li>React.memo()에서 props를 비교할 때</li>
<li>리액트 컴포넌트가 리 렌더링을 하기 전<ul>
<li>state의 변경이 있을 때</li>
<li>부모 컴포넌트가 랜더링 될 때</li>
</ul>
</li>
</ol>
<blockquote>
<p><strong>참고) 리액트에서 컴포넌트가 리랜더링 되는 경우</strong></p>
</blockquote>
<ol>
<li>state 변경이 있을 때</li>
<li>부모로부터 받은 값(props)이 바뀐 경우</li>
<li>부모가 리랜더링 되는 경우
+ <span style='color: gray'><em>shouldComponentUpdate에서 true가 반환될 때</em></span>
+ <span style='color: gray'><em>forceUpdate가 실행 될 때</em></span></li>
</ol>
<blockquote>
<p><strong>참고) App.js 에는 꼭 필요한 경우가 아니면 상태를 넣지 않는다</strong>
-&gt; 렌더링 최적화를 위해. 컴포넌트화를 해서 거기에서 상태관리</p>
</blockquote>
<br>

<h2 id="41-usecallback을-이용한-함수-최적화">41. useCallback을 이용한 함수 최적화</h2>
<p>원래 <strong>컴포넌트가 렌더링 될 때 그 안에 있는 함수도 다시 만들게 됨</strong>. 하지만 똑같은 함수를 컴포넌트가 리 렌더링 된다고 해서 계속 다시 만드는 것은 좋은 현상이 아님
그리고 만약 리 렌더링이 되는 컴포넌트에서 이 함수를 자식 컴포넌트에 props로 내려 준다면 그 함수를 포함하고 있는 컴포넌트가 리 렌더링 될 때마다 <strong>자식 컴포넌트도 함수가 새롭게 만들어지니 계속 리 렌더링을 하게 됨</strong></p>
<p><img src="https://velog.velcdn.com/images/surra7/post/a6266555-ebe3-488f-b037-b3d4b471f130/image.jpg" alt=""></p>
<p>-&gt; 원래 React.memo로 감싸줘서 리 렌더링이 되지 않던 컴포넌트들이 함수를 props로 받으니 input에 문자를 입력할 때 마다 다시 리 렌더링됨</p>
<h3 id="reactusecallback-적용으로-문제-해결">React.useCallback 적용으로 문제 해결</h3>
<p>useCallback은 메모이제이션된 함수를 반환하는 함수
useCallback 적용은 useCallback 안에 콜백함수와 의존성 배열을 순서대로 넣어주면 됨</p>
<p>예시)</p>
<pre><code class="language-jsx">const testFunction = useCallback(() =&gt; {}, []);</code></pre>
<ul>
<li>함수 내에서 참조하는 state, props가 있다면 의존성 배열에 추가하면 됨</li>
<li>useCallback으로 인해서 <strong>의존성 배열에 추가해준 state 혹은 props가 변하지 않는다면 함수는 새로 생성되지 않음</strong></li>
<li>새로 생성되지 않기 때문에 메모리에 새로 할당되지 않고 동일 참조 값을 그대로 사용</li>
<li>의존성 배열에 아무것도 없다면 컴포넌트가 최초 렌더링될 시에만 함수가 생성되며 그 이후에는 동일한 참조 값을 사용하는 함수가 됨</li>
</ul>
<p><img src="https://velog.velcdn.com/images/surra7/post/15238be9-88fe-4508-b14d-4cd455a127a0/image.jpg" alt=""></p>
<p>-&gt; useCallback 함수로 감싸주니 리 렌더링이 안됨</p>
<br>

<h2 id="42-usememo를-이용한-결과-값-최적화">42. useMemo를 이용한 결과 값 최적화</h2>
<h3 id="memoization">Memoization</h3>
<p>메모이제이션은 비용이 많이 드는 함수 호출의 결과를 저장하고 동일한 입력이 다시 발생할 때 캐시된 결과를 반환하여 컴퓨터 프로그램의 속도를 높이는데 주로 사용되는 최적화 기술</p>
<pre><code class="language-jsx">function Component({ a, b }) {
  const result = conpute(a, b);
  return &lt;div&gt;{result}&lt;/div&gt;
}</code></pre>
<p>Component 내의 compute 함수가 만약 복잡한 연산을 수행하면 결과 값을 리턴하는데 오랜 시간이 걸리게 됨
이럴 때 컴포넌트가 리 렌더링 된다면 연산을 계속 수행하는데 오랜 시간이 걸려서 성능에 안 좋은 영향을 미치게 되며, UI 지연 현상이 일어남</p>
<p>-&gt; 이런 현상을 useMemo를 이용해 해결
compute <strong>함수에 넘겨주는 a, b의 값이 이전과 동일하다면 컴포넌트가 리 렌더링 되더라도 연산을 다시 하지 않고 이전 렌더링 때 저장해 두었던 값을 재사용</strong></p>
<h3 id="usememo-적용하기">useMemo 적용하기</h3>
<p>useMemo로 감싸준 후에 첫번째 인수에 compute함수를, 두번째 인수인 의존성 함수에는 compute 함수에서 사용하는 값을 넣어줌</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[02. React 활용해 보기 - 1]]></title>
            <link>https://velog.io/@surra7/02.-React-%ED%99%9C%EC%9A%A9%ED%95%B4-%EB%B3%B4%EA%B8%B0-1</link>
            <guid>https://velog.io/@surra7/02.-React-%ED%99%9C%EC%9A%A9%ED%95%B4-%EB%B3%B4%EA%B8%B0-1</guid>
            <pubDate>Mon, 19 Feb 2024 06:05:23 GMT</pubDate>
            <description><![CDATA[<h2 id="28-리액트-불변성-지키기">28. 리액트 불변성 지키기</h2>
<h3 id="리액트에서-불변성이란">리액트에서 불변성이란?</h3>
<p>불변성이란 값이나 상태를 변경할 수 없는 것을 의미</p>
<h3 id="자바스크립트-타입을-통한-불변성-의미">자바스크립트 타입을 통한 불변성 의미</h3>
<p>원시 타입은 불변성(immutable)을 가지고 있고 참조 타입은 변할 수 있음 (mutable)</p>
<ul>
<li>원시 타입: Boolean, Number, null, undenfined, Symbol</li>
<li>참조 타입: Object, Array</li>
</ul>
<p>기본적으로 자바스크립트는 원시 타입에 대한 참조 및 값을 저장하기 위해 Call Stack 메모리 공간을 사용하지만 참조 타입의 경우 Heap이라는 별도의 메모리 공간을 사용. 참조 타입은 Call Stack 메모리에 객체 및 배열의 값이 아닌 Heap 메모리 참조 ID를 값으로 저장함</p>
<table>
<thead>
<tr>
<th align="center">원시 타입</th>
<th align="center">참조 타입</th>
</tr>
</thead>
<tbody><tr>
<td align="center">고정된 크기로 Call Stack 메모리에 값 저장 <br> 실제 데이터가 변수에 할당됨</td>
<td align="center">데이터 크기가 정해지지 않고 데이터의 값은 Heap에 저장되며 <br> Call Stack 메모리에는 Heap 메모리의 주소값이 할당됨</td>
</tr>
<tr>
<td align="center">변수에 원시 값을 재할당할 때는 원래 할당된 메모리에 있는 값은 그대로 두고 <br> 새로운 메모리 영역에 새로운 값을 할당해서 참조값을 업데이트함</td>
<td align="center">배열에 대한 요소를 추가하거나 객체 속성 값을 변경할 때 <br> Call Stack의 참조 ID는 동일하게 유지하고 Heap 메모리에 있는 값을 변경함</td>
</tr>
<tr>
<td align="center"><strong>불변성을 가지고 있음</strong></td>
<td align="center"><strong>불변성을 유지하지 않음</strong></td>
</tr>
</tbody></table>
<h3 id="불변성을-지켜야하는-이유">불변성을 지켜야하는 이유?</h3>
<ol>
<li>참조 타입에서 객체나 배열의 값이 변할 때 원본 데이터가 변경되기 때문에 이 원본 데이터를 참조하고 있는 다른 객체에서 예상치 못한 오류가 발생할 수 있기 때문</li>
<li>리액트에서 화면을 업데이트할 때 원본 데이터와 이전 데이터를 비교해서 변경된 사항을 확인한 후 업데이트 해줘야 하기 때문에 불변성을 지켜줘야 함</li>
</ol>
<h3 id="불변성을-지키는-방법">불변성을 지키는 방법</h3>
<p>참조 타입에서 값을 바꾸면 불변성을 유지할 수 없으므로 아예 새로운 배열을 반환하는 메소드를 사용해야함
-&gt; spread operator, map, filter, slice, reduce</p>
<blockquote>
<p>원본 데이터를 변경하는 메소드: splice, push -&gt; 사용 x</p>
</blockquote>
<br>

<h2 id="29-전개-연산자-spread-operator">29. 전개 연산자 (Spread Operator)</h2>
<h3 id="전개-연산자란">전개 연산자란?</h3>
<p>전개 연산자는 ECMAScript6(2015)에서 새롭게 추가되었으며, 특정 객체 또는 배열의 값을 다른 객체, 배열로 복제하거나 옮길 때 사용. &#39;...&#39;으로 사용</p>
<br>

<h2 id="35-react-profiler">35. React Profiler</h2>
<h3 id="리액트-프로파일러란">리액트 프로파일러란?</h3>
<p>React Profiler는 React 16.5에서 새로운 DevTools 프로파일러 플러그인에 대한 지원을 추가
이 플러그인은 React의 Profiler API를 사용하여 React 애플리케이션의 성능 병목 현상을 식별하기 위해 렌더링되는 각 구성 요소에 대한 타이밍 정보를 수집합니다.</p>
<h3 id="리액트-프로파일러를-이용한-성능-측정하기">리액트 프로파일러를 이용한 성능 측정하기</h3>
<h4 id="가짜-데이터-가져오기">가짜 데이터 가져오기</h4>
<p>성능을 측정하기 위해서는 어느 정도 많은 데이터가 있어야 하기에 jsonplaceholder를 이용해 가짜 데이터를 받아옴</p>
<pre><code class="language-jsx">useEffect () =&gt; {
  fetch(&#39;http://jsonplaceholder.typicode.com/posts&#39;)
      .then(response =&gt; response.json())
      .then(posts =&gt; setPosts(posts));
}, []);</code></pre>
<blockquote>
<p>response는 HTTP 응답 전체를 나타내는 객체로, JSON 본문 콘텐츠를 추출하기 위해서는 json() (en-US) 메서드를 호출해야 함</p>
</blockquote>
<ul>
<li><p><strong>use Effect</strong>
컴포넌트가 렌더링 될 때 특정 작업을 실행할 수 있도록 하는 Hook
여기서는 App 컴포넌트가 한 번 렌더링 된 후에 jsonplaceholder라는 곳의 서버에 비동기 요청을 보내서 posts 데이터를 가져오기 위해서 사용됨</p>
</li>
<li><p><strong>fetch() 메소드</strong>
원격 API에 요청을 보내기 위해 사용할 수 있는 메소드
전역 fetch() 메소드는 네트워크에서 리소스를 가져오는 프로세스를 시작하여 Response 응답을 사용할 수 있게 되면 이행된 Promise를 return 함</p>
</li>
<li><p><strong>jsonplaceholder</strong>
jsonplaceholder는 가짜 데이터가 필요할 때 사용할 수 있는 무료 온라인 REST API
posts, users, photos 등 여러가지 가짜 데이터를 가져올 수 있음</p>
</li>
</ul>
<br>

<h2 id="38-react-profiler로-성능-측정하기">38. React Profiler로 성능 측정하기</h2>
<ul>
<li>개발자 도구의 Profiler 탭으로 이동</li>
<li>여기서 프로파일링을 수행해서 성능 데이터를 기록하고 측정할 수 있음</li>
<li>프로 파일링을 수행하려면 레코드 버튼을 눌러야함</li>
<li>Profiler는 컴포넌트가 리 랜더링 될 때 마다 성능을 기록함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/surra7/post/53cb3fc6-d4fb-4088-b6a1-2159441bdfc3/image.jpg" alt=""></p>
<ul>
<li>A 컴포넌트는 모든 요소를 하나의 컴포넌트에 넣은것</li>
<li>B 컴포넌트는 요소들을 여러 컴포넌트로 쪼갠 것</li>
<li>그런데 A 컴포넌트보다 B 컴포넌트의 성능이 더 안 좋게 나옴 (A: 2.1ms, B: 5.2ms)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[01. React 기본 다지기 - 5]]></title>
            <link>https://velog.io/@surra7/01.-React-%EA%B8%B0%EB%B3%B8-%EB%8B%A4%EC%A7%80%EA%B8%B0-5</link>
            <guid>https://velog.io/@surra7/01.-React-%EA%B8%B0%EB%B3%B8-%EB%8B%A4%EC%A7%80%EA%B8%B0-5</guid>
            <pubDate>Thu, 15 Feb 2024 05:43:28 GMT</pubDate>
            <description><![CDATA[<h2 id="23-react-hooks란-무엇인가">23. React Hooks란 무엇인가?</h2>
<h3 id="react-hooks">React Hooks</h3>
<p>React Hooks는 ReactConf 2018에서 발표된 class 없이 state를 사용할 수 있는 새로운 기능</p>
<h3 id="react-hooks가-필요한-이유">React Hooks가 필요한 이유</h3>
<p>주로 Class Component로 사용되어온 React에서 느껴왔던 불편함이나 문제점들을 해결하기 위해 개발되었음
React Hooks는 Functional Component를 사용함</p>
<table>
<thead>
<tr>
<th align="center">Class Component</th>
<th align="center">Functional Component</th>
</tr>
</thead>
<tbody><tr>
<td align="center">더 많은 기능 제공</td>
<td align="center">더 적은 기능 제공</td>
</tr>
<tr>
<td align="center">더 긴 코드 양</td>
<td align="center">짧은 코드 양</td>
</tr>
<tr>
<td align="center">더 복잡한 코드</td>
<td align="center">더 간단한 코드</td>
</tr>
<tr>
<td align="center">더딘 성능</td>
<td align="center">더 빠른 성능</td>
</tr>
</tbody></table>
<h3 id="원래-functional-component의-문제점">원래 Functional Component의 문제점</h3>
<p>React Hooks가 없었을 때의 함수형 컴포넌트는 리액트의 생명주기를 사용하지 못했기 때문에 클래스 컴포넌트보다 더 적은 기능을 제공했었음</p>
<p><img src="https://gdsc-university-of-seoul.github.io/assets/images/post-life-cycle/lifecycle_1.png" alt="리액트 생명주기"></p>
<p>함수형 컴포넌트가 더 간결하고 빠르더라도 중요한 리액트 생명주기를 사용하지 못했기 때문에 클래스형 컴포넌트를 써왔었음</p>
<p>하지만 React 16.8 Hooks 업데이트 이후로 함수형 컴포넌트도 생명주기를 사용할 수 있게 됨
컴포넌트를 시작하자마자 API를 호출하는 등 많은 부분을 할 수 있게 됨</p>
<pre><code class="language-jsx">// 클래스형 컴포넌트 사용시
import React, { Component } from &#39;react&#39;;
import Axios form &#39;axios&#39;;

export default class Hello extends Component {
  constructor(props) {
    super(props);
    this.state = { name: &quot;&quot; };
  }

  componentDidMount() {
    Axios.get(&#39;/api/user/name&#39;)
      .then(response =&gt; {
        this.setState({ name: response.data.name })
    })
  }

  render() {
    return (
      &lt;div&gt;
        My name is {this.state.name}
      &lt;/div&gt;
    )
  }
}</code></pre>
<pre><code class="language-jsx">// 함수형 컴포넌트 사용시
import React, { userEffect, userState } from &#39;react&#39;;
import Axios from &#39;axios&#39;

export default function Hello() {
  const [Name, setName] = userState(&quot;&quot;)

  userEffect{() =&gt; {
    Axios.get(&#39;/api/user/name&#39;)
      .then(response =&gt; {
          setName(response.data.name)
    })
  }, [])

  return (
    &lt;div&gt;
      My name is {Name}
    &lt;/div&gt;
  )
}</code></pre>
<blockquote>
<p><strong>Hooks에서 state를 업데이트 하는 방법</strong>
-&gt; state를 정의해줄 때 const[name, setName] = userState(&quot;&quot;); 이런식으로 해주고 여기에서 setName을 이용해서 state를 업데이트 시켜줄 수 있음</p>
</blockquote>
<h3 id="react-hooks의-장점">React Hooks의 장점</h3>
<ul>
<li><p>코드가 간결해 짐
클래스형 컴포넌트에서는 생명주기를 사용할 때 componentDidMount와 componentDidUdate, componentWillUnmount 이렇게 각각 다르게 처리를 해주지만, <strong>React Hook을 사용할 때는 userEffect</strong> 안에서 다 처리를 해주기 때문에 훨씬 간결함</p>
</li>
<li><p><strong>HOC 컴포넌트를 Custom React Hooks로 대체</strong>해서 너무나 많은 Wrapper 컴포넌트를 줄이게 됨</p>
</li>
</ul>
<blockquote>
<p><strong>HOC (Higher Order Component)란?</strong>
화면에서 재사용 가능한 로직만을 분리해서 component로 만들고, 재사용 불가능한 UI와 같은 다른 부분들은 parameter로 받아서 처리하는 방법
컴포넌트를 인자로 받아서 새로운 리액트 컴포넌트를 리턴하는 함수</p>
</blockquote>
<br>

<h2 id="24-crud-앱을-함수형-컴포넌트로-바꾸기">24. CRUD 앱을 함수형 컴포넌트로 바꾸기</h2>
<h3 id="컴포넌트-자체를-바꾸기">컴포넌트 자체를 바꾸기</h3>
<pre><code class="language-jsx">export default class ExpenseForm extends Component {}
// -&gt;
const ExpenseForm = () =&gt; {}
export default ExpenseForm;</code></pre>
<p>클래스형 컴포넌트는 render()안에 return()을 하지만 함수형 컴포넌트는 render()없이 바로 return()</p>
<blockquote>
<p>클래스형 컴포넌트에서 render()는 컴포넌트를 랜더링하는(화면에 나타내는 메소드)</p>
</blockquote>
<h3 id="state를-usestate-hook을-이용해-표현하기">State를 useState Hook을 이용해 표현하기</h3>
<pre><code class="language-jsx">// const [변수 이름 getter, State를 정하는 함수 setter] = expenses, setExpenses를 리턴하고 초기 State 값을 정하는 Hook
const [expenses, setExpenses] = useState([
    { id: 1, charge: &#39;콜라&#39;, amount: 2000 },
    { id: 2, charge: &#39;빵&#39;, amount: 1000 },
    { id: 3, charge: &#39;맥북&#39;, amount: 20000 },
]);</code></pre>
<p>함수형에서 state를 가져올때 this.state.state이름 대신 그냥 state이름을 써서 가져올 수 있음
state를 업데이트 할때도 this.setState 대신 setter를 이용하면 됨</p>
<h3 id="props-사용하기">props 사용하기</h3>
<pre><code class="language-jsx">// 함수에서 props를 받아와서 사용
const ExpenseItem = (props) =&gt; {
    this.props.expense.charge
      // -&gt;
      props.expense.charge
}</code></pre>
<p>더 깔끔하게 표현하기 위해 구조분해 할당을 이용하면 props를 생략하고 사용할 수 있음</p>
<pre><code class="language-jsx">const ExpenseList = ({ initialExpenses, handleDelete }) =&gt; {
    props.initialExpenses
      // -&gt;
      initialExpenses
}</code></pre>
<br>

<h2 id="25-구조-분해-할당">25. 구조 분해 할당</h2>
<h3 id="구조-분해-할당-destructuring">구조 분해 할당 (Destructuring)</h3>
<p>배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 Javascript 표현식</p>
<p>-&gt; 주로 클린 코드를 위해 사용</p>
<h3 id="객체-구조-분해-할당">객체 구조 분해 할당</h3>
<pre><code class="language-jsx">function buildAnimal(animalData){
  let accessory = animalData.accessory,
      animal = animalData.animal,
      color = animalData.color,
      hairType = animalData.hairType;
}
// ===
function buildAnimal(animalData){
  let {accessory, animal, color, hairType} = animalData;
}</code></pre>
<h4 id="깊게-들어간-객체-구조-분해-할당">깊게 들어간 객체 구조 분해 할당</h4>
<pre><code class="language-jsx">let person = {
  name: &#39;Maya&#39;,
  age: 30,
  phone: &#39;123&#39;,
  address: {
    zipcode: 1234,
    street: &#39;rainbow&#39;,
    number: 42
  }
}

let {address: {zipcode, street, number}} = person;
console.log(zipcode, street, number); // 1234, rainbow, 42</code></pre>
<h3 id="배열-구조-분해-할당">배열 구조 분해 할당</h3>
<pre><code class="language-jsx">[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(rest); // [30, 40, 50]</code></pre>
<pre><code class="language-jsx">const week = [&#39;monday&#39;, &#39;tuesday&#39;, &#39;wednesday&#39;, &#39;thuresday&#39;, &#39;friday&#39;];
const [day1, day2, day3, day4, day5] = week;
console.log(day2) // tuesday</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[01. React 기본 다지기 - 4]]></title>
            <link>https://velog.io/@surra7/01.-React-%EA%B8%B0%EB%B3%B8-%EB%8B%A4%EC%A7%80%EA%B8%B0-4</link>
            <guid>https://velog.io/@surra7/01.-React-%EA%B8%B0%EB%B3%B8-%EB%8B%A4%EC%A7%80%EA%B8%B0-4</guid>
            <pubDate>Wed, 14 Feb 2024 08:52:58 GMT</pubDate>
            <description><![CDATA[<h2 id="20-react-state란">20. React State란?</h2>
<p>리액트에서 데이터가 변할 때 화면을 다시 랜더링 해주기 위해서는 React State를 사용해야 한다</p>
<h3 id="react-state">React State</h3>
<p>React State란 컴포넌트의 랜더링 결과물에 영향을 주는 데이터를 갖고 있는 객체
State가 변경되면 컴포넌트는 리랜더링 됨. 또한 State는 컴포넌트 안에서 관리됨</p>
<h4 id="리액트-state-생성하기">리액트 State 생성하기</h4>
<pre><code class="language-jsx">constructor(props){
  super(props);
  // 이름이 expenses인 state 생성
  this.state = {
    expenses: [
      { id: 1, charge: &#39;콜라&#39;, amount: 2000 },
      { id: 2, charge: &#39;빵&#39;, amount: 1000 },
      { id: 3, charge: &#39;맥북&#39;, amount: 20000 },
    ]
  }
}</code></pre>
<h4 id="state-사용하기">state 사용하기</h4>
<pre><code class="language-jsx">// initialExpenses={this.initialExpenses} 대신 state 사용
initialExpenses={this.state.expenses}</code></pre>
<h4 id="state를-이용해서-변경된-상태-업데이트하기">state를 이용해서 변경된 상태 업데이트하기</h4>
<pre><code class="language-jsx">// setState를 이용해 state 업데이트
this.setState({ expenses: newExpense });</code></pre>
<br>

<h2 id="21-superprops란">21. super(props)란?</h2>
<p>constructor 안에 super키워드를 써줘야 밑에 this 키워드를 사용할 수 있음</p>
<h3 id="constructor">Constructor</h3>
<p>constructor(생성자)를 사용하면 인스턴스화된 객체에서 다른 메서드를 호출하기 전에 수행해야하는 사용자 지정 초기화를 제공
클래스를 <strong>new 키워드를 사용해 인스턴스 객체로 생성하면 넘겨받은 인수와 함께 constructor가 먼저 실행됨</strong></p>
<p>예시)</p>
<pre><code class="language-jsx">class User {
  constructor(name){
    this.name = name;
  }
}

let user = new User(&quot;John&quot;);
// 이때 넘겨받은 인수인 John이 this.name에 할당 됨</code></pre>
<h3 id="자바스크립트에서-super">자바스크립트에서 super</h3>
<p>super 키워드는 자식 클래스 내에서 부모 클래스의 생성자를 호출하거나 메소드를 호출할 때 사용됨</p>
<p>예시)</p>
<pre><code class="language-jsx">class Car {
  constructor(brand) {
    this.carname = brand;
  }
  present() {
    return &#39;I have a &#39; + this.carname;
  }
}

class Model extends Car {
  constructor(brand, mod) {
    super(brand);
    this.model = mod;
  }
  show() {
    return super.present() + &#39;, it is a &#39; + this.model;
  }
}

let myCar = new Model(&quot;Ford&quot;, &quot;Mustang&quot;);
mycar.show();</code></pre>
<h3 id="super-이후에-this-키워드">super 이후에 this 키워드</h3>
<p>생성자에서는 super 키워드 하나만 사용하거나 this 키워드가 사용되기 이전에 호출되어야 함</p>
<h4 id="super-이후에-this-키워드가-나와야-하는-이유">super 이후에 this 키워드가 나와야 하는 이유</h4>
<p>부모 클래스의 생성자를 호출하기 전에 this를 사용해서 부모에 있는 객체에 접근하려고 하면 오류가 발생하기 때문
React에서도 마찬가지로 super가 this보다 먼저 사용되어야 함</p>
<h3 id="react에서-super에-props를-인자로-전달하는-이유">React에서 super에 props를 인자로 전달하는 이유</h3>
<p>React.component 객체가 생성될 때 props 속성을 초기화하기 위해 부모 컴포넌트에게 props를 전달
그래야 생성자 내부에서도 this.props를 정상적으로 사용할 수 있음</p>
<br>

<h2 id="22-state와-props">22. State와 Props</h2>
<h3 id="props">Props</h3>
<ul>
<li>부모 컴포넌트로 부터 자식 컴포넌트에 데이터를 전달</li>
<li>읽기 전용</li>
</ul>
<h3 id="state">State</h3>
<ul>
<li>해당 컴포넌트 내에서 데이터를 전달</li>
<li>변경 가능</li>
<li>State가 변경되면 화면이 re-render됨</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[01. React 기본 다지기 - 3]]></title>
            <link>https://velog.io/@surra7/01.-React-%EA%B8%B0%EB%B3%B8-%EB%8B%A4%EC%A7%80%EA%B8%B0-3</link>
            <guid>https://velog.io/@surra7/01.-React-%EA%B8%B0%EB%B3%B8-%EB%8B%A4%EC%A7%80%EA%B8%B0-3</guid>
            <pubDate>Wed, 14 Feb 2024 07:36:37 GMT</pubDate>
            <description><![CDATA[<h2 id="10-spa-single-page-application란">10. SPA (Single Page Application)란?</h2>
<h3 id="페이지가-꾸며지는-순서">페이지가 꾸며지는 순서</h3>
<ol>
<li>public/index.html: HTML 템플릿 파일. div 앨리먼트의 id를 root로 해놓음</li>
<li>src/index.js: 자바스크립트 시작점. id가 root인 div 앨리먼트를 잡아주고 App.js에 연결해서 그 앨리먼트를 꾸밀 수 있게 됨</li>
<li>App.js: 여기에서 잡아놓은 앨리먼트를 꾸밈</li>
</ol>
<h3 id="single-page-application-spa">Single Page Application (SPA)</h3>
<p>원래 전통적인 방식의 웹 사이트는 Multi Page Application으로 여러개의 페이지를 만들어서 각 페이지를 연결하는 식으로 만들었음</p>
<p>하지만 요즘에는 <strong>앱 사이트의 전체 페이지를 하나의 페이지에 담아 동적으로 화면을 바꿔가면서 보여주는 방식</strong>을 사용함. 이것이 Single Page Application</p>
<h3 id="spa에서-화면-변경이-이루어지는-원리">SPA에서 화면 변경이 이루어지는 원리</h3>
<p>Multi Page Application에서는 a 페이지에서 b 페이지로 전환할 때 a.html을 보여주다가 b.html을 보여주면 됐지만, index.html 하나밖에 없는 SPA에서는 어떻게 페이지 전환(브라우징)을 할까?
-&gt; <strong>HTML 5의 History API</strong>를 사용
React-Router-Dom에서 History API를 사용해서 현재 페이지 내에서 화면 이동이 일어난 것처럼 작동하게 해줌</p>
<h4 id="history-api">History API</h4>
<table>
<thead>
<tr>
<th align="center">메서드</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">History.back()</td>
<td align="center">세션 기록의 바로 뒤 페이지로 이동하는 비동기 메서드. 브라우저의 뒤로 가기를 누른 것과 같은 효과</td>
</tr>
<tr>
<td align="center">History.forward()</td>
<td align="center">세션 기록의 바로 앞 페이지로 이동하는 비동기 메서드. 브라우저의 앞으로 가기를 누른 것과 같은 효과</td>
</tr>
<tr>
<td align="center">History.go()</td>
<td align="center">특정한 세션 기록으로 이동하게 해주는 비동기 메서드. 1을 넣어 호출하면 바로 앞 페이지로, -1을 넣어 호출하면 뒤 페이지로 이동</td>
</tr>
<tr>
<td align="center">History.pushState()</td>
<td align="center">주어진 데이터를 세션 기록 스택에 넣음. 직렬화 가능한 모든 Javascript 객체를 저장하는 것이 가능</td>
</tr>
<tr>
<td align="center">History.replaceState()</td>
<td align="center">최근 세션 기록 스택의 내용을 주어진 데이터로 교체</td>
</tr>
</tbody></table>
<br>

<h2 id="11-crud-앱-소개-및-jsx-알아보기">11. CRUD 앱 소개 및 JSX 알아보기</h2>
<h3 id="jsx-javascript-syntax-extension란">JSX (Javascript syntax extension)란?</h3>
<p>JSX는 자바스크립트의 확장 문법이다. 리액트에서는 이 JSX를 이용해서 화면의 UI를 정의한다</p>
<p>JSX를 사용하면 UI를 나타낼때 자바스크립트 로직과 HTML 구조를 같이 사용할 수 있기 때문에 기본 UI에 데이터가 변하는 것들이나 이벤트들이 처리되는 부분을 더욱 쉽게 구현할 수 있음</p>
<h3 id="jsx를-사용하지-않으면">JSX를 사용하지 않으면?</h3>
<p>JSX를 사용하지않고 원래 리액트에서 화면을 그리는 방식은 React.createElement API를 사용해서 앨리먼트를 생성한 후, 이 앨리먼트를 In-Memory에 저장. 그리고 ReactDOM.render 함수를 사용해서 실제 웹 브라우저에 그려줌</p>
<h3 id="jsx는-createelement를-쉽게-사용하기-위해-사용함">JSX는 createElement를 쉽게 사용하기 위해 사용함</h3>
<p>모든 UI를 만들때 마다 createElement를 사용해서 컴포넌트를 만들면 너무 복잡함. 따라서 JSX를 사용해서 작성 후 그걸 바벨이 내부에서 자동적으로 createElement로 바꿔서 사용함</p>
<h3 id="jsx를-사용하면서-주의해야-할-문법-문법-규칙">JSX를 사용하면서 주의해야 할 문법 (문법 규칙)</h3>
<p>JSX로 작성할 때 컴포넌트안에 여러 앨리먼트 요소가 있다면 반드시 부모 요소 하나로 감싸줘야 함</p>
<p>예시)</p>
<pre><code class="language-jsx">// 잘못된 코드
function hello(){
    return (
      &lt;div&gt;Hello world!&lt;/div&gt;
      &lt;div&gt;what are you doing&lt;/div&gt;
    )
}

// 올바른 코드
function hello(){
    return &lt;div&gt;
      &lt;div&gt;Hello world!&lt;/div&gt;
      &lt;div&gt;what are you doing&lt;/div&gt;
      &lt;/div&gt;;
}</code></pre>
<br>

<h2 id="15-리액트-아이콘-사용하기">15. 리액트 아이콘 사용하기</h2>
<p>리액트에서 아이콘을 사용하는 방법은 여러가지지만 주로 react-icons 모듈을 이용해서 아이콘을 구현함</p>
<h3 id="사용방법">사용방법</h3>
<ul>
<li>필요한 패키지 설치: <em>npm install react-icons</em></li>
<li>사용법: <a href="https://react-icons.github.io/react-icons/">https://react-icons.github.io/react-icons/</a></li>
</ul>
<br>

<h2 id="16-props를-통해-컴포넌트-간-데이터-전달">16. Props를 통해 컴포넌트 간 데이터 전달</h2>
<h3 id="props란">Props란?</h3>
<p>Props는 Properties의 줄인말</p>
<ul>
<li>Props는 상속하는 부모 컴포넌트로부터 자녀 컴포넌트에 데이터 등을 전달하는데 사용됨</li>
<li>Props는 읽기 전용으로 자녀 컴포넌트 입장에서는 변하지 않음
(변하게 하고자 하려면 부모 컴포넌트에서 state를 변경시켜 줘야함)</li>
</ul>
<p>예시)</p>
<pre><code class="language-jsx">// 부모 컴포넌트에서 내려주기
initialExpenses = [
    { id: 1, charge: &#39;콜라&#39;, amount: 2000 },
    { id: 2, charge: &#39;빵&#39;, amount: 1000 },
    { id: 3, charge: &#39;맥북&#39;, amount: 20000 },
]

&lt;자식컴포넌트 initialExpenses={this.initialExpenses} /&gt;

// 자식 컴포넌트에서 받아오기
this.props.initialExpenses</code></pre>
<br>

<h2 id="18-jsx-key-속성-이해하기">18. JSX Key 속성 이해하기</h2>
<h3 id="jsx-key-속성">JSX Key 속성</h3>
<p>리액트에서 요소의 리스트를 나열할 때는 key를 넣어줘야 됨
키는 react가 변경, 추가 또는 제거된 항목을 식별하는 데 필요
요소에 안정적인 ID를 부여하려면 배열 내부의 요소에 키를 제공해야 함</p>
<p><strong>리액트는 가상 돔을 이용해서 바뀐 부분만 실제 돔에 적용</strong>
이때 바뀐 부분을 식별하기 위해서는 Key가 필요</p>
<h3 id="key-사용-방법">Key 사용 방법</h3>
<p><strong>key에는 유니크한 값을 넣어줘야 함 (index는 비추천!)</strong>
index도 0부터 시작하는 유니크한 값을 가지지만 만약 리스트가 추가되거나 삭제되면 해당 리스트들의 key 값도 전부 바뀌게 됨</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[01. React 기본 다지기 - 2]]></title>
            <link>https://velog.io/@surra7/02.-React-%EA%B8%B0%EB%B3%B8-%EB%8B%A4%EC%A7%80%EA%B8%B0-2</link>
            <guid>https://velog.io/@surra7/02.-React-%EA%B8%B0%EB%B3%B8-%EB%8B%A4%EC%A7%80%EA%B8%B0-2</guid>
            <pubDate>Wed, 14 Feb 2024 02:46:07 GMT</pubDate>
            <description><![CDATA[<h2 id="04-nodejs-설치">04. Node.js 설치</h2>
<h3 id="nodejs란">Node.js란?</h3>
<p>리액트 프로젝트를 만들기 위해서는 Node.js와 npm을 먼저 설치해야 함
Node.js를 설치하면 자동으로 npm도 같이 설치됨</p>
<p>Node.js란 크롬 V8 자바스크립트 엔진으로 빌드한 자바스크립트 런타임으로서, 웹 브라우저 환경이 아닌 곳에서도 자바스크립트를 사용하여 연산 할 수 있게 해줌</p>
<h3 id="react-설치-시-nodejs가-필요한-이유">React 설치 시 Node.js가 필요한 이유</h3>
<p>리액트 앱은 웹 브라우저에서 실행되는 코드여서 Node.js와 직접적인 연관은 없지만, 프로젝트를 개발하는 데 필요한 주요 도구들이 Node.js를 사용하기 때문에 필요
이 때 필요한 개발 도구에는 바벨, 모듈화된 코드를 한 파일로 합치고 코드를 수정할 때 마다 웹 브라우저를 리로딩하는 등 여러기능을 지닌 웹팩 등이 있음</p>
<br>

<h2 id="05-브라우저가-그려지는-원리-및-가상돔">05. 브라우저가 그려지는 원리 및 가상돔</h2>
<p>리액트의 주요 특징 중 하나는 가상돔을 사용한다는 것</p>
<h3 id="웹-페이지-빌드-과정-critical-rendering-path-crp">웹 페이지 빌드 과정 (Critical Rendering Path, CRP)</h3>
<p>브라우저가 서버에서 페이지에 대한 HTML 응답을 받고 화면에 표시하기 전에 여러 단계가 있음
웹 브라우저가 HTML 문서를 읽고, 스타일을 입히고 뷰포트에 표시하는 과정</p>
<ul>
<li><strong>DOM tree 생성</strong>: 렌더 엔진이 문서를 읽어들여서 그것들을 파싱하고 어떤 내용을 페이지에 렌더링할지 결정함</li>
<li><strong>Render tree 생성</strong>: 브라우저가 DOM과 CSSDOM을 결합하는 단계이며, 이 프로세스는 화면에 보이는 모든 콘텐츠와 스타일 정보를 모두 포함하는 최종 렌더링 트리를 출력. <em>즉, 화면에 표시되는 모든 노드의 콘텐츠 및 스타일 정보를 포함</em></li>
<li><strong>Layout (reflow)</strong>: 브라우저가 페이지에 표시되는 각 요소의 크기와 위치를 계산하는 단계</li>
<li><strong>Paint</strong>: 실제 화면에 그리는 단계</li>
</ul>
<blockquote>
<p>❗️문제점
어떤 인터렉션에 의해 DOM에 변화가 발생하면 그때마다 Render Tree가 재생성 됨. 즉, 모든 요소들의 스타일을 다시 계산하고 Layout, Repaint 과정을 다시 거쳐야 함
인터렉션이 적은 웹이면 괜찮지만 만약 인터렉션이 많다면?
불필요하게 DOM을 조작하는 비용이 너무 크게됨
-&gt; 이러한 문제로 인해 나오게 된 것이 <strong>가상 돔, Virtual Dom</strong></p>
</blockquote>
<h3 id="가상-돔-virtual-dom이란">가상 돔 Virtual Dom이란?</h3>
<p>가상 돔이란 실제 DOM을 메모리에 복사해둔 것으로 생각하면 됨</p>
<h4 id="가상돔의-작동-원리">가상돔의 작동 원리</h4>
<p>데이터가 바뀌면 가상돔에 렌더링되고 이전에 생긴 가상돔과 비교해서 바뀐 부분만 실제 돔에 적용 시켜줌. 바뀐 부분을 찾는 과정을 Diffing이라고 부르며, 바뀐 부분만 실제 돔에 적용시켜 주는 것을 재조정(reconfiliation)이라고 부름</p>
<h4 id="가상돔의-장점">가상돔의 장점</h4>
<p>만약 한번에 많은 요소가 변하였다고 하더라도 한 번에 묶어서 실제 돔 수정은 한 번만 처리하므로 돔을 조작하는 비용이 줄어들게 됨</p>
<br>

<h2 id="06-create-react-app을-이용해서-리액트-설치하기">06. Create React App을 이용해서 리액트 설치하기</h2>
<p>요즘에는 &#39;<em>npx create-react-app &lt;폴더이름&gt;</em>&#39;이라는 명령어로 간단하게 리액트를 설치할 수 있음</p>
<h3 id="이전에-래액트-앱을-설치하던-방법">이전에 래액트 앱을 설치하던 방법</h3>
<p>이전에는 Webpack이나 Babel 같은 모듈을 설치하고 설정해야 리액트 앱을 시작할 수 있었음</p>
<h3 id="webpack이란">Webpack이란?</h3>
<p>웹팩은 오픈 소스 자바스크립트 모듈 번들러로써 여러개로 나누어져 있는 파일들을 하나의 자바스크립트 코드로 압축하고 최적화하는 라이브러리</p>
<h4 id="webpack의-장점">Webpack의 장점</h4>
<ol>
<li>여러 파일의 자바스크립트 코드를 압축하여 최적화 할 수 있기 때문에 로딩에 대한 네트워크 비용을 줄일 수 있음</li>
<li>웹팩이 파일을 압축해주므로 개발 단계에서 모듈 단위로 개발이 가능하며, 가독성과 유지보수가 쉬움</li>
</ol>
<h3 id="babel이란">Babel이란?</h3>
<p>최신 자바스크립트 문법을 지원하지 않는 브라우저들을 위해서 최신 자바스크립트 문법을 구형 브라우저에서도 돌 수 있게 변환시켜주는 라이브러리</p>
<h3 id="create-react-app">create-react-app</h3>
<p>create-react-app을 사용하면 webpack이나 babel을 따로 설치하고 설정할 필요없이 자동으로 설정이 되므로 간단하게 리액트를 설치할 수 있음</p>
<h3 id="npx란">npx란?</h3>
<p>npx는 노드 패키지 실행을 도와주는 도구로, create-react-app 이란 npm 레지스트리에 있는 패키지를 react-app 폴더에서 실행해서 리액트를 설치해 주는 것</p>
<h4 id="npm-레지스트리">npm 레지스트리</h4>
<p>다양한 라이브러리들이 저장되어 있는 곳, create-react-app 패키지도 포함되어 있음</p>
<blockquote>
<p><strong>npx vs npm</strong>
npx는 단지 실행을 도와주는 도구, npm은 실제로 로컬에 설치를 해주는 도구</p>
</blockquote>
<br>

<h2 id="08-create-react-app으로-설치-된-리액트-기본-구조-살펴보기">08. Create React App으로 설치 된 리액트 기본 구조 살펴보기</h2>
<h3 id="이름이-수정되면-안되는-파일들">이름이 수정되면 안되는 파일들</h3>
<ol>
<li>public/index.html -&gt; 페이지 템플릿</li>
<li>src/index.js -&gt; 자바스크립트 시작점</li>
</ol>
<blockquote>
<p>public 폴더 내부의 파일만 public/index.html에서 사용할 수 있음</p>
</blockquote>
<blockquote>
<p>src 폴더 내부에 JS 파일과 CSS 파일들을 넣으면 된다
webpack은 src 폴더 내에 있는 파일들만 처리하기 때문에 이 폴더 외부에 있는 파일들은 webpack에 의해 처리되지 않음</p>
</blockquote>
<h3 id="indexhtml">index.html</h3>
<p>index.html은 관습적으로 사용되어온 것으로, 방문자가 사이트를 요청할 때 다른 페이지가 지정되지 않은 경우 웹 사이트에 표시될 기본 페이지에 사용되는 가장 일반적인 이름
즉, index.html은 웹 사이트의 홈페이지에 사용된 이름이다</p>
<blockquote>
<p><em><a href="http://www.abc.com">www.abc.com</a></em> 이라고 된 것은 사실 <em><a href="http://www.abc.com/index.html">www.abc.com/index.html</a></em> 이다</p>
</blockquote>
<h3 id="src-폴더">src 폴더</h3>
<p>대부분의 리액트 소스 코드들은 이곳에 작성</p>
<h3 id="packagejson-파일">Package.json 파일</h3>
<p>해당 프로젝트에 대한 정보들이 들어있음. 포로젝트 이름, 버전, 필요한 라이브러리와 라이브러리의 버전들이 명시되어 있음
앱을 시작할 때 사용할 스크립트, 앱을 빌드할때, 테스트할 때 사용할 스크립트 등이 명시되어 있음</p>
<blockquote>
<p>프로젝트에서 자주 실행해야하는 명령어를 scripts로 작성해두면 npm 명령어로 실행 가능</p>
</blockquote>
<pre><code class="language-js">&quot;scripts&quot;: {
    &quot;start&quot;: &quot;react-scripts start&quot;,
    &quot;build&quot;: &quot;react-scripts build&quot;,
    &quot;test&quot;: &quot;react-scripts test&quot;,
    &quot;eject&quot;: &quot;react-scripts eject&quot;
}
// -&gt; npm start 라고 하면 앱이 시작고 npm build라고 하면 앱이 빌드 됨</code></pre>
<blockquote>
<p>소스 코드를 입력할 때 문법이나 코드 포멧을 체크해주는 것에 대한 설정을 명시함</p>
</blockquote>
<pre><code class="language-js">&quot;eslintConfig&quot;: {
    &quot;extends&quot;: [
        &quot;react-app&quot;,
        &quot;react-app/jest&quot;
    ]
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[01. React 기본 다지기 - 1]]></title>
            <link>https://velog.io/@surra7/01.-React-%EA%B8%B0%EB%B3%B8-%EB%8B%A4%EC%A7%80%EA%B8%B0</link>
            <guid>https://velog.io/@surra7/01.-React-%EA%B8%B0%EB%B3%B8-%EB%8B%A4%EC%A7%80%EA%B8%B0</guid>
            <pubDate>Tue, 13 Feb 2024 09:15:21 GMT</pubDate>
            <description><![CDATA[<h2 id="01-리액트란-무엇인가요">01. 리액트란 무엇인가요</h2>
<p>React는 사용자 인터페이스를 만들기 위한 JavaScript 라이브러리
리액트는 인터렉션이 많은 웹, 앱을 개발하기 위해 주로 사용됨
이와 같은 웹, 앱을 만드는 Vue나 Angular와 많이 비교하게 됨</p>
<h3 id="react-vs-vue-vs-angular">React vs Vue vs Angular</h3>
<p>Vue와 Angular는 프레임 워크이고 React는 라이브러리임</p>
<h4 id="framework-vs-library">Framework vs Library</h4>
<ul>
<li>프레임 워크는 어떠한 앱을 만들기 위해 필요한 대부분의 것을 가지고 있는 것</li>
<li>라이브러리는 어떠한 특정 기능을 모듈화 해놓은 것</li>
</ul>
<p>프레임 워크는 라이브러리를 포함하고 있으며 작성한 소스 코드를 호출함
그리고 소스 코드는 어떠한 기능을 구현하기 위해서 라이브러를 호출하게 됨</p>
<h3 id="리액트가-프레임-워크가-아닌-라이브러리인-이유">리액트가 프레임 워크가 아닌 라이브러리인 이유</h3>
<p>리액트는 전적으로 UI(사용자 인터페이스)를 렌더링하는 데 관여하기 때문</p>
<blockquote>
<p>리액트는 보이는 부분, view에 관여를 하는데 페이지 이동이나 상태 관리 등은 어떻게 할까?
-&gt; <strong>리액트 생태계</strong>, 다른 라이브러리들의 도움을 받음</p>
</blockquote>
<ul>
<li>라우팅 (페이지 이동): react-router-dom</li>
<li>상태 관리: redux, recoll, mobx</li>
<li>테스트: Jest, Mocha</li>
</ul>
<br>

<h2 id="02-리액트를-사용하는-이유">02. 리액트를 사용하는 이유</h2>
<ul>
<li>상대적으로 배우기 쉬운 라이브러리</li>
<li>여러 기능들을 위한 라이브러리 환경이 이미 잘 만들어져 있음</li>
<li>많은 기업들의 사용으로 검증이 된 라이브러리</li>
</ul>
<br>

<h2 id="03-리액트-컴포넌트란-무엇인가요">03. 리액트 컴포넌트란 무엇인가요</h2>
<p>리액트는 여러 컴포넌트를 이용해서 웹 앱을 개발함</p>
<h3 id="컴포넌트component란">컴포넌트(Component)란?</h3>
<p>리액트로 만들어진 앱을 이루는 최소한의 단위</p>
<p>여러개의 컴포넌트가 모여 하나의 페이지를 이루게 됨</p>
<h3 id="리액트-컴포넌트의-2가지-유형">리액트 컴포넌트의 2가지 유형</h3>
<h4 id="클래스형-컴포넌트-class-components">클래스형 컴포넌트 (Class Components)</h4>
<p>예시)</p>
<pre><code class="language-tsx">class App extends Component {
    render(){
        return &lt;h1&gt;안녕하세요.&lt;/h1&gt;;
    }
}</code></pre>
<h4 id="함수형-컴포넌트-functional-components">함수형 컴포넌트 (functional Components)</h4>
<p>예시)</p>
<pre><code class="language-tsx">function App() {
    return &lt;h1&gt;안녕하세요.&lt;/h1&gt;
}</code></pre>
<p>원래 리액트는 클래스 컴포넌트를 이용해서 많이 개발을 했지만 리액트에서 리액트 Hooks라는 것을 발표한 이후부터는 함수형 컴포넌트를 이용해서 많이 개발을 하는 추세</p>
]]></description>
        </item>
    </channel>
</rss>