<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Daehyunii's Dev-blog</title>
    <link>https://pinetree93.tistory.com/</link>
    <description> 2023 개발자가 되기 위한 나의 발자취 </description>
    <language>ko</language>
    <pubDate>Wed, 12 Aug 2026 11:49:56 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Daehyunii</managingEditor>
    <image>
      <title>Daehyunii's Dev-blog</title>
      <url>https://tistory1.daumcdn.net/tistory/5420448/attach/25db8ae3312b426295b562f80e7d046c</url>
      <link>https://pinetree93.tistory.com</link>
    </image>
    <item>
      <title>블로그를 이전했습니다! 많이 놀러와 주세요 </title>
      <link>https://pinetree93.tistory.com/341</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp; &amp;nbsp;저의 목표 중 하나였던 개인 블로그를 개설했습니다!  &lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이름은 &quot;&lt;b&gt;woodaelog&lt;/b&gt;&quot; 제 이름을 그대로 사용했습니다~ 부족한 점이 많지만 그래도 제 나름대로의 원하는 바를 이뤄서 기분이 좋네요!&amp;nbsp; &lt;b&gt;github login&lt;/b&gt;을 통해 댓글도 달 수 있으니 언제든지 놀러오셔서 부족한 점 많이 많이 말씀해주시면 열심히 열심히 수정해 나가보겠습니다~ &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;많은 관심 부탁드려요~&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;URL: &lt;a title=&quot;우대현의 개인 블로그&quot; href=&quot;https://woodaelog.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://woodaelog.com/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679726742561&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;WooDaeHyun Blog&quot; data-og-description=&quot;WooDaeHyun Dev-Blog&quot; data-og-host=&quot;woodaelog.netlify.app&quot; data-og-source-url=&quot;https://woodaelog.com/&quot; data-og-url=&quot;https://woodaelog.netlify.app/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/VpEai/hyR2HzTWyg/ywvW4oyvHBiy2UG6zBdPPk/img.png?width=2000&amp;amp;height=1125&amp;amp;face=0_0_2000_1125,https://scrap.kakaocdn.net/dn/y4UPt/hyR2Sg6xr5/CgK79vk4PhURgUYJzEiAU0/img.png?width=2000&amp;amp;height=1125&amp;amp;face=0_0_2000_1125&quot;&gt;&lt;a href=&quot;https://woodaelog.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://woodaelog.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/VpEai/hyR2HzTWyg/ywvW4oyvHBiy2UG6zBdPPk/img.png?width=2000&amp;amp;height=1125&amp;amp;face=0_0_2000_1125,https://scrap.kakaocdn.net/dn/y4UPt/hyR2Sg6xr5/CgK79vk4PhURgUYJzEiAU0/img.png?width=2000&amp;amp;height=1125&amp;amp;face=0_0_2000_1125');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;WooDaeHyun Blog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;WooDaeHyun Dev-Blog&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;woodaelog.netlify.app&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Gatsby</category>
      <category>블로그</category>
      <author>Daehyunii</author>
      <guid isPermaLink="true">https://pinetree93.tistory.com/341</guid>
      <comments>https://pinetree93.tistory.com/341#entry341comment</comments>
      <pubDate>Sat, 25 Mar 2023 15:46:56 +0900</pubDate>
    </item>
    <item>
      <title>[데브코스] 데이터 시각화</title>
      <link>https://pinetree93.tistory.com/339</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;1. 데이터 시각화란?&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;말 그대로 데이터를 시각화 한다는 것이다. 예를 들면 코로나 지역별 확진자 수를 보여주는 지도나 대시보드 전략지표 시스템 모니터링 등 일반적인 실무에서 사용되는 데이터 시각화를 들 수 있다. 스크롤링 시각화와 스토리텔링도 많이 사용되는 예시 중 하나이다. 그럼 왜 데이터를 시각화 해야할까? 왜냐하면 시각화가 데이터에 형태를 부여하여 데이터를 한 눈에 파악할 수 있게 해주기 때문이다. 데이터의 패턴을 비교하여 포인트 등을 파악할 수 있고, 시각화를 통해 인사트를 얻을 수 있게 하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 어떻게 만들어야 할까? 일반적으로 자바스크립트를 기반으로 한 데이터 시각화 라이브러리가 많이 있다. 그리고 그 중 우리가 앞으로 내가 공부할 내용은 D3.js 데이터 시각화 라이브러리이고 현재 가장 인기가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;2. 데이터 시각화 만드는 방법을 알아보자!&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;u&gt;그렇다면 데이터 시각화를 어떻게 만들어야할까?&lt;/u&gt; 우선은 무엇이 좋은 데이터 시각화인지 고민하고 시작하는것이 중요하다 우리가 개발을 하면서 코드를 작성하는 것과 마찬가지로 말이다. 큰 순서를 정해보자면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 데이터 시각화 기획(데이터, 독자, 구성 세 가지 큰 틀을 정하는게 중요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 데이터 확보: 풍부하고 유용한 데이터(사람들이 관심을 가질 만큼)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;3. 독자: 독자의 니즈 파악하기&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 내용의 구성: (데이터에서 출발하는 방법, 분석에서 출발하는 방법)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 데이터에서 출발이란? 데이터에서 바로 측정가능 한 수치들을 찾고 시각화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 분석에서 출발이란? 데어터의 양상을 가지고 소결을 만들고 증명하고 결론을 내는 방법(주로 스토리텔링 방식으로 많이 진행함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;u&gt;그럼 무엇이 좋은 데이터 시각화일까?&lt;/u&gt; 좋은 데이터 시각화란, 풍부하고 유용한 데이터, 명료하고 보기 좋은 시각화, 한 눈에 내용이 잘 전달되는 구성을 갖은 데이터 시각화가 좋은 데이터 시각화라고 볼 수 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 명확하고 보기 좋은 시각화를 만들려면 어떻게 해야할까? 주제에 따른 정말 필요한 정보만 보여주고 인지를 해치지 않는 적절한 시각적 속성으로 구성하고 군더더기 없는 부가 설명을 포함하는 것이 좋은 시각화라고 할 수 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;3. 다양한 데이터 시각화 종류들에 대해 알아보자!&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터는 여러 형태로 존재하는데 데이터 유형에 따라 어떤 그래프나 차트를 이용하면 좋을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;-&lt;/i&gt;수량을 보여주려면 뭐가 좋을까? &lt;b&gt;주로 표, 막대 차트로 일반적으로 시각화&lt;/b&gt; 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;-&lt;/i&gt;여러 범주의 수량을 보여주려면 뭐가 좋을까? &lt;b&gt;묶음 막대, 멀티 차트로 일반적으로 시각화&lt;/b&gt; 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;-&lt;/i&gt;비율을 보여주려면 뭐가 좋을까? &lt;b&gt;파이 차트, 누적 막대 도표, 모자이크 도표, 트리맵으로 일반적으로 시각화&lt;/b&gt; 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;-&lt;/i&gt;시계열과 추세를 보여주려면 뭐가 좋을까? &lt;b&gt;선 그래프로 일반적으로 시각화&lt;/b&gt; 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;-&lt;/i&gt;지리 공간을 시각화 하는 방법은? &lt;b&gt;단계 구분도로 일반적으로 시각화&lt;/b&gt; 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;4. 효과적인 시각화를 위해 꼭 알아야할 점 6가지를 알아보자!&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-선형 스케일 차트는 항상 0에서 출발해야 한다. 좌표계!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-무분별한 색 사용은 오히려 시각적인 혼란을 불러 일으킵니다. (3~5 가지 색이 적당함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-색각 이상자를 배려합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-제목을 적당히 활용합니다. 그럼 오히려 사람들이 차트를 이해하기 쉽게 만들 수 있음!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-테두리와 격자를 적당히 활용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-3D 시각화는 하지 말자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;5. 앞으로 공부하게 될 D3에 대해서 알아보자!&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;-&lt;/i&gt;자바스크립트 라이브러리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-Mike bostock이 주도해서 만듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-데이터 시각화에 적합한 오픈소스임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-Data Deriven Documents&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-데이터 기반으로 DOM을 다루는 라이브러리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-다양한 데이터 포맷 처리 &amp;amp; import 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-HTML SVG 웹 표준 기술을 다양하게 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-데이터와 DOM element를 결합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;6. SVG란?&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크기를 축소/확대하면 해상도를 조절해 주며 HTML과 비슷한 마크업 언어로 작성한다. 작성 방법을 알아보자!&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;svg width=&quot;500px&quot; height=&quot;500px&quot;&amp;gt;
    &amp;lt;circle cx='100' cy='50' r='20' /&amp;gt;
&amp;lt;/svg&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 작성됨(동그라미)&lt;/p&gt;
&lt;pre class=&quot;processing&quot;&gt;&lt;code&gt;&amp;lt;svg width=&quot;500px&quot; height=&quot;500px&quot;&amp;gt;
    &amp;lt;rect x='0' y='0' width='100' height='50' rx='10' ry='10' /&amp;gt;
&amp;lt;/svg&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 작성됨(직사각형)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;D3는 이러한 SVG를 활용한다! 이를 통해 데이터와 DOM element를 D3가 결합해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;{&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;name&amp;rdquo;: &amp;ldquo;극한직업&amp;rdquo;, &amp;mdash;&amp;gt; element - 16264984&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;value&amp;rdquo;: 16264984&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;},&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;{&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;name&amp;rdquo;: &amp;ldquo;어벤져스:엔드게임&amp;rdquo;, &amp;mdash;&amp;gt;element - 13977602&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;value&amp;rdquo;: 13977602&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;}&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;]&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면 rect element의 속성을 데이터에 맞추게 된다. 즉 D3는 데이터 값의 크기에 맞게 rect너비 크기를 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 처럼 D3는 각각의 데이터 포인트를 SVG elemnet와 결합하고 시각적인 형태와 위치를 조절하고 SVG로 만들어서 확대/축소를 해도 해상도 픽셀이 흐려지거나 깨지지 않는 장점이 있다. 단점은 분석 툴이 아니기 때문에 Tableau나 Excel처럼 버튼 몇 번으로 쉽고 빠르게 시각화를 만들어낼 순 없다. D3는 자바스크립트 기반 데이터 시각화 라이브러리이기 때문에 직접 하나 하나 구현해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;7. SVG 기본 태그들을 확인해 보자&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674731427446&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot; /&amp;gt;
    &amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&amp;gt;
    &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&amp;gt;
    &amp;lt;title&amp;gt;Data visualization&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;p&amp;gt;SVG로 도형 그리자&amp;lt;/p&amp;gt;

    &amp;lt;svg width=&quot;500px&quot; height=&quot;500px&quot;&amp;gt;
      &amp;lt;!-- 원 --&amp;gt;
      &amp;lt;circle cx=&quot;100&quot; cy=&quot;50&quot; r=&quot;20&quot; /&amp;gt;

      &amp;lt;!-- 타원 --&amp;gt;
      &amp;lt;ellipse cx=&quot;50&quot; cy=&quot;25&quot; rx=&quot;40&quot; ry=&quot;20&quot; /&amp;gt;

      &amp;lt;!-- 직사각형 --&amp;gt;
      &amp;lt;rect x=&quot;0&quot; y=&quot;70&quot; width=&quot;100&quot; height=&quot;20&quot; /&amp;gt;

      &amp;lt;!-- 모서리가 둥근 직사각형 --&amp;gt;
      &amp;lt;rect x=&quot;0&quot; y=&quot;100&quot; width=&quot;100&quot; height=&quot;20&quot; rx=&quot;10&quot; ry=&quot;10&quot; /&amp;gt;

      &amp;lt;!-- 다각형 --&amp;gt;
      &amp;lt;polygon points=&quot;300,300 150,450 300,450&quot; /&amp;gt;

      &amp;lt;!-- 선 --&amp;gt;
      &amp;lt;line x1=&quot;0&quot; y1=&quot;300&quot; x2=&quot;200&quot; y2=&quot;400&quot; stroke=&quot;black&quot; /&amp;gt;

      &amp;lt;!-- Path --&amp;gt;
      &amp;lt;path d=&quot;M 0 200 q 100 -100 100 200 l 100 200&quot; /&amp;gt;

      &amp;lt;!-- 문자 --&amp;gt;
      &amp;lt;text x=&quot;10&quot; y=&quot;150&quot; font-size=&quot;20&quot;&amp;gt;SVG 문자&amp;lt;/text&amp;gt;
    &amp;lt;/svg&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;8. SVG태그 그룹화 및 transform&lt;br /&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1674732192969&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot; /&amp;gt;
    &amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&amp;gt;
    &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&amp;gt;
    &amp;lt;style&amp;gt;
      .blue-group {
        fill: blue;
        stroke-width: 3;
      }
      .red-group {
        fill: red;
        stroke-width: 4;
        font-weight: bold;
      }
      .green-group {
        fill: green;
        stroke-width: 2;
        fill-opacity: 0.5;
      }
    &amp;lt;/style&amp;gt;
    &amp;lt;title&amp;gt;Data visualization&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;p&amp;gt;코드 작성&amp;lt;/p&amp;gt;
    &amp;lt;svg width=&quot;600px&quot; height=&quot;500px&quot;&amp;gt;
      &amp;lt;!-- g 태그 활용하기 --&amp;gt;
      &amp;lt;!-- &amp;lt;g&amp;gt; 태그를 통해 요소를 구룹화 할 수 있습니다. --&amp;gt;
      &amp;lt;g class=&quot;blue-group&quot; transform=&quot;scale(1.2)&quot;&amp;gt;
        &amp;lt;text x=&quot;0&quot; y=&quot;20&quot;&amp;gt;Blue group&amp;lt;/text&amp;gt;
        &amp;lt;rect x=&quot;0&quot; y=&quot;40&quot; width=&quot;50&quot; height=&quot;50&quot; rx=&quot;10&quot; ry=&quot;10&quot; /&amp;gt;
        &amp;lt;polygon points=&quot;80,30 70,70 130,50&quot; /&amp;gt;
        &amp;lt;line x1=&quot;60&quot; y1=&quot;75&quot; x2=&quot;120&quot; y2=&quot;90&quot; stroke=&quot;blue&quot; /&amp;gt;
      &amp;lt;/g&amp;gt;
      &amp;lt;g class=&quot;red-group&quot; transform=&quot;translate(200)&quot;&amp;gt;
        &amp;lt;text x=&quot;0&quot; y=&quot;20&quot;&amp;gt;Red group&amp;lt;/text&amp;gt;
        &amp;lt;rect x=&quot;0&quot; y=&quot;40&quot; width=&quot;50&quot; height=&quot;50&quot; rx=&quot;10&quot; ry=&quot;10&quot; /&amp;gt;
        &amp;lt;polygon points=&quot;80,30 70,70 130,50&quot; /&amp;gt;
        &amp;lt;line x1=&quot;60&quot; y1=&quot;75&quot; x2=&quot;120&quot; y2=&quot;90&quot; stroke=&quot;red&quot; /&amp;gt;
      &amp;lt;/g&amp;gt;
      &amp;lt;g class=&quot;green-group&quot; transform=&quot;translate(200, 120)&quot;&amp;gt;
        &amp;lt;text x=&quot;0&quot; y=&quot;20&quot;&amp;gt;Green group&amp;lt;/text&amp;gt;
        &amp;lt;rect x=&quot;0&quot; y=&quot;40&quot; width=&quot;50&quot; height=&quot;50&quot; rx=&quot;10&quot; ry=&quot;10&quot; /&amp;gt;
        &amp;lt;polygon points=&quot;80,30 70,70 130,50&quot; /&amp;gt;
        &amp;lt;line x1=&quot;60&quot; y1=&quot;75&quot; x2=&quot;120&quot; y2=&quot;90&quot; stroke=&quot;green&quot; /&amp;gt;
      &amp;lt;/g&amp;gt;
      &amp;lt;!-- transform 속성으로 SVG 요소를 변형시키고, 움직이거나 회전시킬 수도 있습니다. --&amp;gt;
      &amp;lt;!-- transform=&quot;translate(200)&quot; --&amp;gt;

      &amp;lt;!-- transform=&quot;scale(1.2)&quot; 그룹의 크기를 키움--&amp;gt;
      &amp;lt;!-- transform=&quot;translate(200,120)&quot; 그룹의 위치를 이동--&amp;gt;
    &amp;lt;/svg&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-01-26 오후 8.24.46.png&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/darLO7/btrXfNX2ZvL/4QOUpbF12QU76cHnJTYZ41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/darLO7/btrXfNX2ZvL/4QOUpbF12QU76cHnJTYZ41/img.png&quot; data-alt=&quot;SVG를 활용하여 데이터 시각화 기본 연습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/darLO7/btrXfNX2ZvL/4QOUpbF12QU76cHnJTYZ41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdarLO7%2FbtrXfNX2ZvL%2F4QOUpbF12QU76cHnJTYZ41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;328&quot; data-filename=&quot;스크린샷 2023-01-26 오후 8.24.46.png&quot; data-origin-width=&quot;942&quot; data-origin-height=&quot;772&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SVG를 활용하여 데이터 시각화 기본 연습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;데이터 시각화&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 오늘은 D3를 배우기 전에 전체적인 데이터 시각화가 무엇이고, 또 어떤 것이 좋은 데이터 시각화인지 알아보는 시간과 SVG의 태그들을 알아보는 공부를 했다. 공부를 하면서 솔직하게 느낀 심정은 아무래도 귀에 걸면 귀걸이 코에 걸면 코걸이? 느낌이 약간 들었던 것 같다. 똑같은 도표도 누군가에게는 좋을수도 있고 누군가에게는 아닐 수도 있기 때문이다. 다만 한 가지 장점이 있다면 기존의 Excel을 활용해서 도표를 만들거나 하는 것보다 SVG나 D3를 통해서 데이터를 시각화 한다면 조금 더 구체적이고 원하는 의도대로 데이터를 시각화 할 수 있겠다는 장점이 있었고, 아직 D3 라이브러리를 제대로 배우기 전의 생각이긴 하지만 SVG의 경우 하나 하나 위치 너비 크기를 조절하여 시각화를 해야 하는데 그렇게 효율적이라는 생각이 들지는 않았다. (아 물론 g태그로 그룹화하여 처리하는 것도 있겠지만,, 그래도 글쎄?.. 아직은 잘 모르겠다. 앞으로 배워보면서 알아가야겠다)&lt;/p&gt;</description>
      <category>✏️ 2022. TIL/December (데브코스)</category>
      <author>Daehyunii</author>
      <guid isPermaLink="true">https://pinetree93.tistory.com/339</guid>
      <comments>https://pinetree93.tistory.com/339#entry339comment</comments>
      <pubDate>Thu, 26 Jan 2023 20:27:12 +0900</pubDate>
    </item>
    <item>
      <title>[데브코스] TIL-133 React, Redux</title>
      <link>https://pinetree93.tistory.com/330</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Redux&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; Redux는 &lt;b&gt;Prop Drilling&lt;/b&gt; 문제를 해결하기 위해 등장했다. 그렇다면 Context API와 무엇이 다를까? Context API는 React의 내장 API여서 따로 설치없이 사용이 가능한 반면, Redux는 Third Party 라이브러리로 설치가 필요하다. 그리고 개발 편의를 위한 미들웨어 기능과 성능 최적화를 쉽게 해주는 기능을 제공한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 동작 방식&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;리덕스.jpeg&quot; data-origin-width=&quot;1369&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DpUwD/btr6CfRcvMV/oYRRMYNVgvoAaBwkSr5aFK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DpUwD/btr6CfRcvMV/oYRRMYNVgvoAaBwkSr5aFK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DpUwD/btr6CfRcvMV/oYRRMYNVgvoAaBwkSr5aFK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDpUwD%2Fbtr6CfRcvMV%2FoYRRMYNVgvoAaBwkSr5aFK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;154&quot; data-filename=&quot;리덕스.jpeg&quot; data-origin-width=&quot;1369&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; Redux는 Action이 발생하면 Reducer를 호출하고 Reducer를 통해 store에 상태를 저장한다. store가 변경되면 다시 view를 리렌더링한다. Context API에 useReducer를 사용한 것과 유사하다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 3가지 원칙&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;진실은 하나의 근원으로부터&lt;/li&gt;
&lt;li&gt;애플리케이션의 모든 상태는 하나의 저장소 안에 하나의 객체 트리 구조로 저장된다. Context API는 변경이 발생하면 모든 Consumer를 리렌더링 하지만, Redux의 경우에는 사용한 부분만 리렌더링 되도록 최적화하고 있다.&lt;/li&gt;
&lt;li&gt;상태는 읽기 전용&lt;/li&gt;
&lt;li&gt;개발자가 직접 상태에 접근하여 변경할 수 없고, 반드시 Action을 통해 Reducer를 실행하고 Reducer가 상태를 변화하도록 만들어야 한다.&lt;/li&gt;
&lt;li&gt;함수는 순수 함수로 작성&lt;/li&gt;
&lt;li&gt;Reducer 안에 네트워크 로직이 들어가서는 안된다. Reducer를 재사용 가능하게 만드는 원칙 중 하나라고 볼 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오늘을 마무리 하며&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 오늘은 전역 상태 관리 라이브러리인 Redux에 대해서 공부를 하게 되었다. 근데 공부를 하면서 느낀점은 그냥 &lt;i&gt;&lt;u&gt;&lt;b&gt;뭐가 너무 복잡하다&lt;/b&gt;&lt;/u&gt;&lt;/i&gt;는 생각이 들었다. 전역 상태로 관리하는 값들은 최소화해야 하는데 최소화한 값을 전역 상태로 관리하기 위해서 라이브러리를 설치하고 또 복잡한 문법들을 사용해서 관리해야 한다는 것이 뭔가 어색한 느낌이 들었다. 아직 Recoil에 대해서는 구체적으로 보지는 못했지만, 앞으로 프로젝트를 진행할 때 전역으로 상태를 관리하는 상황이 올 텐데, 그 전에 &lt;b&gt;contextAPI&lt;/b&gt; vs &lt;b&gt;Redux&lt;/b&gt; vs &lt;b&gt;Recoil&lt;/b&gt;을 잘 비교해보고 선택해서 적용해보는 연습을 해볼 예정이다!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;</description>
      <category>✏️ 2022. TIL/December (데브코스)</category>
      <author>Daehyunii</author>
      <guid isPermaLink="true">https://pinetree93.tistory.com/330</guid>
      <comments>https://pinetree93.tistory.com/330#entry330comment</comments>
      <pubDate>Wed, 28 Dec 2022 20:54:07 +0900</pubDate>
    </item>
    <item>
      <title>[데브코스] TIL-132 React, 컴포넌트심화</title>
      <link>https://pinetree93.tistory.com/328</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;컴포넌트 심화&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 아키텍처&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 아키텍처는 우리가 일을 잘 하기 위한 방법이다. 그러기 위해서는 모듈의 구현과 나누는 방법을 잘 정하는 것이 필요하다. 모듈에서 중요한 것은 응집도와 결합도다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 응집도&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;i&gt;&lt;b&gt;모듈 내에 포함된 요소들이 서로 연관되어 있는 정도&lt;/b&gt;&lt;/i&gt;를 뜻한다. 즉, 모듈 내 기능들이 하나의 책임으로 잘 뭉쳐 있는지를 나타낸다. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;응집도가 높을 수록 좋은 설계&lt;/b&gt;&lt;/span&gt;라고 할 수 있는데, 하나의 책임에 집중하고 독립성을 높이며 우리가 수정하기 위한 요소를 빠르게 찾을 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;높은 응집도.jpeg&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;994&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GQI9O/btr6BfqBUV8/WffeKSnmmS5TftzhtfRCak/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GQI9O/btr6BfqBUV8/WffeKSnmmS5TftzhtfRCak/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GQI9O/btr6BfqBUV8/WffeKSnmmS5TftzhtfRCak/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGQI9O%2Fbtr6BfqBUV8%2FWffeKSnmmS5TftzhtfRCak%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;240&quot; data-filename=&quot;높은 응집도.jpeg&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;994&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공통 폐쇄 원칙&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;같은 이유로 동일한 시점에 변경되는 기능을 하나의 모듈로 묶어야 한다는 원칙&lt;/li&gt;
&lt;li&gt;객체지향의 원칙인 &lt;b&gt;단일 책임 원칙&lt;/b&gt;을 컴포넌트 관점으로 바라본 것&lt;/li&gt;
&lt;li&gt;과하게 적용하면 재사용성이 줄어들 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공통 재사용 원칙&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모듈 내의 기능들은 &lt;b&gt;함께 재사용&lt;/b&gt;될 수 있어야 한다는 원칙&lt;/li&gt;
&lt;li&gt;&lt;b&gt;함께 재사용&lt;/b&gt;될 수 없다면 분리해야함&lt;/li&gt;
&lt;li&gt;과하게 적용하면 개발 용이성이 줄어들 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;공통 폐쇄 원칙.jpeg&quot; data-origin-width=&quot;1365&quot; data-origin-height=&quot;419&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bevunk/btr6EVLrfjw/uytCedQFosgxEOboT4kPik/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bevunk/btr6EVLrfjw/uytCedQFosgxEOboT4kPik/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bevunk/btr6EVLrfjw/uytCedQFosgxEOboT4kPik/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbevunk%2Fbtr6EVLrfjw%2FuytCedQFosgxEOboT4kPik%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;123&quot; data-filename=&quot;공통 폐쇄 원칙.jpeg&quot; data-origin-width=&quot;1365&quot; data-origin-height=&quot;419&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&amp;nbsp; 두 원칙을 하나만 골라서 사용해야 하는 것은 아니다. 상황에 따라 이 사이를 적절하게 조절하는 것이 필요하고, 그것이 개발자의 능력이라고 볼 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 결합도&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;i&gt;&lt;b&gt;다른 모듈과의 의존성에 대한 정도&lt;/b&gt;&lt;/i&gt;를 뜻한다. 모듈과 모듈 사이의 관계가 어느 정도인지를 나타낸다. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;낮은 결합도일 수록 좋은 설계&lt;/b&gt;&lt;/span&gt;며, 안정성이 증가한다. 결합도가 높으면 수정에 대해 많은 영향을 줄 수 있고, 어디서 버그가 터질지 모른다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;낮은 결합도.jpeg&quot; data-origin-width=&quot;1631&quot; data-origin-height=&quot;985&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRPzne/btr6ybbevJO/Wo0XBRBmERvxH03cuotxvk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRPzne/btr6ybbevJO/Wo0XBRBmERvxH03cuotxvk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRPzne/btr6ybbevJO/Wo0XBRBmERvxH03cuotxvk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRPzne%2Fbtr6ybbevJO%2FWo0XBRBmERvxH03cuotxvk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;242&quot; data-filename=&quot;낮은 결합도.jpeg&quot; data-origin-width=&quot;1631&quot; data-origin-height=&quot;985&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;안정된 의존성 원칙&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;더 안정된 모듈을 의존하자는 원칙&lt;/li&gt;
&lt;li&gt;의존하는 모듈이 적고 의존되는 모듈이 많을수록 안정적인 모듈임&lt;/li&gt;
&lt;li&gt;안정성 지표는 Fan-out / (Fan-in + Fan-out)으로 계산 가능
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Fan-out은 의존되는 것&lt;/li&gt;
&lt;li&gt;Fan-in은 의존하는 것&lt;/li&gt;
&lt;li&gt;0에 가까울수록 안정되고 1에 가까울수록 불안정한 컴포넌트&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;당연하지만 변화에 무겁도록 만들어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;안정된 추상화 원칙&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴포넌트는 안정된 만큼 추상적이어야 한다는 원칙&lt;/li&gt;
&lt;li&gt;추상성은 추상 클래스 수 / 클래스 수로 계산 가능
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;React 컴포넌트는 UI 요소가 포함되어 있어 이렇게 계산 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;레이어를 잘 나눠야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오늘을 마무리 하며&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 오늘은 그 동안 코드를 작성해 오던 나의 모습들을 돌이켜보는 시간을 보낸것 같다. 그 동안에는 사실 정상적으로 동작하게 하는데 급급했고, 그 와중에 컴포넌트를 어떻게 분리하면 좋을지에 대한 생각을 짧게 짧게 했던 것 같다. 그런데 오늘 강의를 듣고 난 다음에 생각을 해보니 명확한 기준 없이 대~충 컴포넌트를 분리하면서 코드를 작성해 왔다는 생각이 들었다. 여기서 모든 원칙들에 대해 외우는것은 불필요한 일이라고 생각한다. 하지만 한 가지 명확하게 기억해 놓으면 좋다고 생각한 것은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;응집도는 높을수록 결합도는 낮을수록 좋은 설계&lt;/b&gt;&lt;/span&gt;라는 것이다. &lt;b&gt;이 점을 기억하면 코드를 작성할 때 일정한 나만의 기준을 만들고 적용할 수 있을 것 같다&lt;/b&gt;!!!! 그리고 작업을 진행하기 전에 충분한 고민을 통해 컴포넌트들을 어떻게 구성하면 좋을지 고민하는 시간을 더 가져가야겠다. 오늘은 뭔가 기준을 세울 수 있는 포인트들을 배운 것 같아 기분이 좋다! 누가봐도 깔끔하고 멋진 설계를 할 수 있는 그날까지 화이팅이다!!!!!&lt;/p&gt;</description>
      <category>✏️ 2022. TIL/December (데브코스)</category>
      <author>Daehyunii</author>
      <guid isPermaLink="true">https://pinetree93.tistory.com/328</guid>
      <comments>https://pinetree93.tistory.com/328#entry328comment</comments>
      <pubDate>Tue, 27 Dec 2022 18:04:15 +0900</pubDate>
    </item>
    <item>
      <title>[데브코스] TIL-131 React, 웹 보안 공격, SPA 역사</title>
      <link>https://pinetree93.tistory.com/325</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&amp;nbsp;웹 보안&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 웹 사이트의 취약점을 공격하는 기술적 위협으로, 웹 페이지를 통해 권한이 없는 시스템에 접근하거나 데이터 유출 및 파괴와 같은 행위를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;웹 보안 공격 기법&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. SQL Injection&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 서버에서 실행되는 SQL을 악의적으로 이용하는 공격이다. 기존 SQL에 악의적인 SQL을 삽입한다. 그렇기 때문에 데이터 탈취나 삭제 등이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방어 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SQL에서 특별한 의미를 가지는 문자를 이스케이프한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;\\n, \\t, |, /, &amp;amp;, # &amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;준비된 선언을 사용한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;placeholder를 담은 SQL을 먼저 DB에 보낸 후 placeholder에 해당하는 입력 값을 DB에 보내는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;라이브러리, 프레임워크에서 거의 100% 막아준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;심화 공격&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Error based SQL ****************Injection&lt;/li&gt;
&lt;li&gt;일부러 SQL 에러를 발생시켜 원하는 정보를 취득한다. 쿼리문 추측, DB명, 테이블명 등을 취득할 수 있다.&lt;/li&gt;
&lt;li&gt;Blind SQL Injection&lt;/li&gt;
&lt;li&gt;쿼리 결과의 참/거짓을 보고 원하는 정보가 존재하는지 알 수 있다. DB명, Table명을 알 수 있다. SQLMap이라는 자동화된 툴을 이용하기도 한다.&lt;/li&gt;
&lt;li&gt;Union SQL Injection&lt;/li&gt;
&lt;li&gt;Union 명령을 이용하여 정보를 취득한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. XSS&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;b&gt;Cross-Site Scripting&lt;/b&gt;이며, 웹 페이지에 악성 스크립트를 삽입하는 공격이다. 사이트 이용자의 정보를 탈취할 수 있기 때문에 주의해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방어 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTML 필터링을 한 후 DB에 저장한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;lt;, &amp;gt;, script, html, head, meta&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;만약을 위해 프론트엔드에서도 태그와 관련된 것들을 필터링한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;심화 공격&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Reflected XSS&lt;/li&gt;
&lt;li&gt;검색어 등을 보여주는 곳에 스크립트를 심는 공격이다. URL을 사용자에게 누르게 만들면 공격이 성공하게 된다.&lt;/li&gt;
&lt;li&gt;DOM Based XSS&lt;/li&gt;
&lt;li&gt;DOM에 악의적인 스크립트를 심는 공격이다. 이는 브라우저가 스크립트를 해석하는 단계에서 발생된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. CSRF Attack&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;b&gt;Cross-Site Request Forgery&lt;/b&gt;이며, 공격자가 사용자를 이용하여 웹 사이트에 요청을 보내는 공격이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방어 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Referrer Check
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;허용한 도메인만 요청을 허락하도록 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CSRF Token
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 요청에 토큰을 발급하여 서버에서 검증한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CAPTCHA
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사람이 요청한 것이 맞는지 검증한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. Command Injection&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 애플리케이션에 사용 되는 시스템 명령에 악의적인 명령어를 삽입하는 공격이다. 이는 웹을 통해서 해당 시스템의 Shell에 접근할 수 있기 때문에 &lt;b&gt;WebShell Attack&lt;/b&gt;이라고도 부른다. 서버의 root 권한을 취득할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방어 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가급적 시스템 함수를 사용하지 않는다.&lt;/li&gt;
&lt;li&gt;민감한 문자를 필터링한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;|, &amp;amp;, ;, &amp;gt;, &amp;lt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. File Upload Attack&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 악성 스크립트 파일을 업로드하는 공격이다. 업로드 후 파일 위치를 찾아 실행시키면 공격이 성공하게 된다. 보통 &lt;b&gt;php&lt;/b&gt;, &lt;b&gt;jsp&lt;/b&gt;를 사용하는 곳에서 공격 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방어 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;확장자나 파일 타입을 검사한다.&lt;/li&gt;
&lt;li&gt;업로드 파일을 난수화하여 저장한다.&lt;/li&gt;
&lt;li&gt;특수 문자가 포함된 경우 업로드를 금지시킨다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. JavaScript Injection&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;b&gt;Client-Side에서 JavaScript를 삽입&lt;/b&gt;시키는 공격이다. 크롬 콘솔 등을 통해 조작이 가능하며, Client-Side에 민감한 데이터를 넣을 경우 탈취가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방어 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Client-Side에는 민감한 정보를 절대 넣지 않는다.&lt;/li&gt;
&lt;li&gt;데이터 유효성 검사가 필요한 경우에는 서버와 통신한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중요한 데이터를 Client에서만 검사하면 안된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7. DDoS&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;b&gt;Distributed Denial of Service&lt;/b&gt;이며, 서버에 비정상적으로 많은 트래픽을 보내는 공격이다. 서비스가 마비되고 많은 비용이 소모된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방어 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;제일 단순한 방법인데 제일 막기 어렵다.&lt;/li&gt;
&lt;li&gt;확장 가능한 서비스 구조를 설계한다.&lt;/li&gt;
&lt;li&gt;IP 필터링을 하거나 Rate Limit을 걸어 둔다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ex) 3초에 10개만 요청을 받겠다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DDoS를 탐지해서 바로 차단시켜주는 솔루션을 구매한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;8. Dictionary Attack&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 미리 사전에 등록해놓은 문자열을 암호로 대입하는 공격이다. &lt;b&gt;Brute Force&lt;/b&gt;의 일종이라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방어 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;의미가 있는 문자열은 암호로 등록하지 못하도록 설정한다.&lt;/li&gt;
&lt;li&gt;특정 횟수이상 비밀번호를 틀렸을 때 계정을 잠그는 Account Lockout Policy를 적용한다.&lt;/li&gt;
&lt;li&gt;OTP 같은 2-factor 인증을 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;9. Rainbow Table&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 해시 함수를 이용한 평문을 모두 저장시켜 놓은 표를 의미한다. 이는 이미 해킹이 되었을 때를 가정하는데, 계정 탈취 후 암호 원문을 알아내기 위해 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방어 방법&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Salt&lt;/li&gt;
&lt;li&gt;Key Stretching&lt;/li&gt;
&lt;li&gt;PBKDF2, Bcrypt 등의 암호화 알고리즘을 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;보안 정책&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. CORS&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;b&gt;Cross-Origin Resource Sharing&lt;/b&gt;이며, 개발자가 지정한 프로토콜, 도메인, 포트가 아니라면 리소스를 가져올 수 없게 하는 것이다. 브라우저가 Response header를 보고 허용 여부를 결정하기 때문에 브라우저마다 구현이 다를 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. CSP&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;b&gt;Content-Security-Pocliy&lt;/b&gt;이며, 실행 가능한 리소스에 대한 Whitelist를 정하는 정책이다. 웹 사이트가 허용되지 않은 리스소를 요청하지 못하도록 막는다. 따라서 XSS 방지에 도움이 된다. 기본적으로는 inline script가 실행을 막는다. 메타 태그나 HTTP header로 설정이 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1679997402231&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;meta http-equiv=&quot;Content-Security-Pocliy&quot;
    content=&quot;default-src 'self'; connect-src 'self'; script-src 'none';
    style-src 'self'; img-src https://cdn.cobalt.run&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. HTTPS&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &lt;b&gt;HTTP 프로토콜의 암호화된 버전&lt;/b&gt;이다. SSL 인증서를 이용하여 소켓 통신에 암호화된 데이터를 전송한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;HTTPS.jpeg&quot; data-origin-width=&quot;1706&quot; data-origin-height=&quot;832&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EdVCF/btr6BTgerG3/EKm7M3MDn9vXkKIoTyM6w0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EdVCF/btr6BTgerG3/EKm7M3MDn9vXkKIoTyM6w0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EdVCF/btr6BTgerG3/EKm7M3MDn9vXkKIoTyM6w0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEdVCF%2Fbtr6BTgerG3%2FEKm7M3MDn9vXkKIoTyM6w0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;293&quot; data-filename=&quot;HTTPS.jpeg&quot; data-origin-width=&quot;1706&quot; data-origin-height=&quot;832&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;SPA의 역사&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 태초에 Muti Page Application(MPA)이 있었다. 이는 먼저 사용자가 브라우저를 통해 특정 페이지를 요청하고, 서버는 요청을 받아 데이터를 그에 끼워넣은 후 HTML String을 만들어 낸다. 이를 사용하여 HTML을 반환하면 브라우저가 렌더링하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때는 자바스크립트의 역할이 크지 않았다. 그러나 점점 화려한 애니메이션, 멀티미디어 재생, 동적인 데이터 전송 등 브라우저에 요구사항이 많아졌다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Ajax&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 그래서 이를 해결하기 위해 &lt;b&gt;Ajax&lt;/b&gt;가 등장했다. 구글이 적극적으로 사용하면서 유행하기 시작한 기술이며, 페이지 이동이 없이 통신이 가능했다. 즉, 동적으로 데이터를 가져올 수 있었다. 그렇다면 페이지 이동 없이 페이지를 가져올 수는 없을까라는 의문이 등장했다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Hashbang&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이 때 URI Fragment를 이용한 Hashbang이라는 개념이 등장했다. URI Fragment는 URI에 #이 붙은 부분을 뜻한다. URI Fragment를 읽은 후 해당 경로에 해당하는 페이지를 Ajax로 불러오는 방식이다. 그래서 화면 깜빡임 없이 전환이 가능하고 사용자에게 로딩도 보여줄 수 있어 사용성이 향상되나, 검색 엔진 최적화의 문제가 있었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. History API&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이 문제는 HTML5 History API가 등장하며 사라진다. pushState(), replaceState()와 같은 기능이 생기면서 페이지 이동 없이 브라우저의 주소를 변경할 수 있게 되었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. pjax&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; pushState를 적극적으로 사용하면서 pushState와 Ajax를 합친 pjax라는 용어도 등장했다. 이는 Hashbang의 단점을 모두 보완한다. pjax로 MPA와 1:1 대응이 가능해졌다. 첫 페이지 접속은 서버에서 내려주는 HTML을 렌더링하고, 이후에는 ajax로 HTML을 불러와 교체하는 방식이다. 어떻게 보면 이것은 &lt;b&gt;SSR&lt;/b&gt;의 시작이라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오늘을 마무리 하며&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 오늘은 뭔가 신기한 내용들에 대해서 공부를 많이 한 것 같다. 이전에 뉴스에서만 보았던 DDos 공격이 어떤 공격인지에 대해서도 알 수 있었고 생각보다 많은 부분에서 공격을 받을 수 있다는 점도 알 수 있었다. 그리고 웹 개발을 할 때 대부분의 웹 페이지는 개인 정보를 수집하게 되는데 이런 개인 정보와 관련된 데이터를 보호하기 위해서도 신경을 써야 한다는 점을 알 수 있었다. 역시 개발의 세계는 정말 넓다는 느낀 강의가 아니었나 생각이 든다.&amp;nbsp;&lt;/p&gt;</description>
      <category>✏️ 2022. TIL/December (데브코스)</category>
      <author>Daehyunii</author>
      <guid isPermaLink="true">https://pinetree93.tistory.com/325</guid>
      <comments>https://pinetree93.tistory.com/325#entry325comment</comments>
      <pubDate>Tue, 27 Dec 2022 02:59:13 +0900</pubDate>
    </item>
    <item>
      <title>[데브코스] TIL-130 React, Context API</title>
      <link>https://pinetree93.tistory.com/324</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Context API&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 컴포넌트는 트리 구조로 이루어져 있다. 만약 최상위 컴포넌트에서 가장 하위 컴포넌트로 prop을 넘기고 싶다면 어떻게 해야할까? 하위 컴포넌트를 찾을 때 까지 계속 넘겨주어야 할 것이다. 이런 경우를 Prop Drilling이라고 한다. Context API는 이를 해결해줄 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 구성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; Context API는 데이터를 제공해줄 Context Provider와 데이터를 받을 Context Consumer가 있다. 데이터는 Context Provider가 관리하고, Context Consumer는 데이터를 받아서 처리만 해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;컨텍스트API.jpeg&quot; data-origin-width=&quot;1666&quot; data-origin-height=&quot;1064&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beb6bl/btr6BgW59MQ/JKGGcHmSLmM5zZaK9ijr3K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beb6bl/btr6BgW59MQ/JKGGcHmSLmM5zZaK9ijr3K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beb6bl/btr6BgW59MQ/JKGGcHmSLmM5zZaK9ijr3K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbeb6bl%2Fbtr6BgW59MQ%2FJKGGcHmSLmM5zZaK9ijr3K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;287&quot; data-filename=&quot;컨텍스트API.jpeg&quot; data-origin-width=&quot;1666&quot; data-origin-height=&quot;1064&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오늘을 마무리 하며&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 오늘은 전역 상태 관리를 할 수 있는 &lt;b&gt;ContextAPI&lt;/b&gt;에 대해서 공부를 하였다. 바닐라 자바스크립트를 공부할 때 항상 문제가 발생했던 부분이 있다면 바로 이 부분이었다. 동일한 코드들을 계속해서 부모에서 자식으로 또 그 자식으로 또 그 자식으로 넘겨줄 때마다 똑같은 코드를 수없이 많이 반복하고 있는 내 자신을 볼 때마다 약간의 &lt;b&gt;현타&lt;/b&gt;가 .. 오는 그런 상황들을 많이 접했었고, 불행 중 다행인지 모든 개발자들이 겪는 문제인지 &lt;b&gt;전역으로 상태 관리&lt;/b&gt;를 통해 이를 해결할 수 있는 방법인 것이다. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;한 가지 주의해야할 점이 있다면 전역으로 상태 관리를 남용해서는 안될 것이라는 점이다.&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;예를들어 &lt;i&gt;&lt;b&gt;토큰&lt;/b&gt;&lt;/i&gt;을 관리한다던지, 정말 많은 자식 컴포넌트에서 필요한 값이라던지, 이러한 필요해 의해서만 사용되어야 할 것이다. 그래서 아직 그 기준을 명확하게 세우지는 못한 상태이다. 그리고 전역 상태 관리와 관련하여 &lt;b&gt;Redux&lt;/b&gt;, &lt;b&gt;recoil&lt;/b&gt;과 같은 상태 관리 라이브러리들이 많이 존재하는데 어떤 장/단점이 존재하는지 명확하게 비교하는 공부도 필요할 것이다. 곧 Redux에 대해서 공부하게 되는데 이때 Redux를 먼저 이해하고 비교를 해보아야 겠다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>✏️ 2022. TIL/December (데브코스)</category>
      <author>Daehyunii</author>
      <guid isPermaLink="true">https://pinetree93.tistory.com/324</guid>
      <comments>https://pinetree93.tistory.com/324#entry324comment</comments>
      <pubDate>Mon, 26 Dec 2022 19:11:47 +0900</pubDate>
    </item>
    <item>
      <title>MVC</title>
      <link>https://pinetree93.tistory.com/321</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;MVC&lt;/b&gt;란? (Model - View - Controller)&lt;br /&gt;MVC는 &lt;b&gt;소프트웨어 디자인 패턴&lt;/b&gt;입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 우선 소프트웨어 디자인 패턴이란 &lt;b&gt;개발 방식을 공식화한 방법론&lt;/b&gt;을 말합니다. 과거부터 지금까지 개발하는 과정에서 발생한 &lt;i&gt;&lt;b&gt;공통적인 문제들을 해결하는 방식&lt;/b&gt;&lt;/i&gt;이라고 쉽게 생각할 수 있습니다. 이러한 디자인 패턴을 잘 활용하면 &lt;u&gt;가독성, 간결성 그리고 확장과 유지 보수가 용이&lt;/u&gt;하여 효율적인 소스 코드를 작성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디자인패턴의 종류는 매우 다양합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-23 오후 2.18.54.png&quot; data-origin-width=&quot;2132&quot; data-origin-height=&quot;1234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdFOxK/btrUsqJEJN0/KfunBNKJ0GnaqXT2gMExX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdFOxK/btrUsqJEJN0/KfunBNKJ0GnaqXT2gMExX0/img.png&quot; data-alt=&quot;디자인 패턴&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdFOxK/btrUsqJEJN0/KfunBNKJ0GnaqXT2gMExX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdFOxK%2FbtrUsqJEJN0%2FKfunBNKJ0GnaqXT2gMExX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2132&quot; height=&quot;1234&quot; data-filename=&quot;스크린샷 2022-12-23 오후 2.18.54.png&quot; data-origin-width=&quot;2132&quot; data-origin-height=&quot;1234&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;디자인 패턴&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 &lt;i&gt;&lt;b&gt;MVC에서 정한 개발 방식을 공식화한 방법&lt;/b&gt;&lt;/i&gt;은 무엇일까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱 개발을 세 개의 영역으로 나누고 각 요소에 고유한 역할을 부여하는 방식을 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;M&lt;/b&gt;odel : Controller에게 받은 요청에 따라 데이터를 관리합니다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;해당 데이터는 다시 Controller에게 전달합니다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;C&lt;/b&gt;ontroller : User로부터 요청을 받아 데이터를 가져와야 한다면 Model에게 데이터를 요청합니다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Model에게 받은 데이터는 View에게 전달합니다.&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;V&lt;/b&gt;iew: Controller로부터 받은 데이터를 Client로 전송해 화면에 결과를 나타냅니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-23 오후 3.18.33.png&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;834&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G9oAB/btrUs2Wlhlt/gXi2zCPl2Yxkq7trvsn4CK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G9oAB/btrUs2Wlhlt/gXi2zCPl2Yxkq7trvsn4CK/img.png&quot; data-alt=&quot;MVC&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G9oAB/btrUs2Wlhlt/gXi2zCPl2Yxkq7trvsn4CK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG9oAB%2FbtrUs2Wlhlt%2FgXi2zCPl2Yxkq7trvsn4CK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;834&quot; data-filename=&quot;스크린샷 2022-12-23 오후 3.18.33.png&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;834&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MVC&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 간단한 예시를 들어보겠습니다. 인터넷 쇼핑몰을 통해 우리는 장바구니 기능을 이용해 본 경험이 있을 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 우리가 원하는 물품을 장바구니에 담게 되는데 장바구니에 들어감과 동시에 &lt;b&gt;예상 결제 금액&lt;/b&gt;이 같이 변동하는 것을 확인할 수 있습니다. 이렇게 장바구니에 물품이 추가됨에 따라 예상 결제 금액이 수정되는 로직을 '&lt;b&gt;비즈니스 로직&lt;/b&gt;'이라고 하고, MVC에서는 &lt;b&gt;C영역에서 &lt;/b&gt;처리하게 됩니다. 그리고 단순히 예상 결제 금액을 보여주는 영역을 &lt;b&gt;V영역에서&lt;/b&gt; 처리하게 됩니다. 프로그램의 핵심을 담당하는 영역이 C영역입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;MVC&lt;/b&gt;패턴의 한계&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; MVC의 가장 큰 특징은 구성요소를 독립시킴으로써 개발 효율성을 높인다는 점입니다. 하지만 &lt;span&gt;MVC에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;컨트롤러&lt;/b&gt;는 상황에 따라 여러 개의 모델, 뷰와 연결될 수 있는데 다수의 모델과 뷰가 하나의 컨트롤러에서 수행되기 때문에 모델과 뷰는 실질적으로 완전히 분리되기가 쉽지 않고, 특히 프로그램 구조가 커질수록 모델과 뷰가 복잡하게 연결되는 상황이 발생하게 됩니다. 그리고 이러한 의존성 문제를 보완하기 위해 MVC에서 파생된 패턴이 생겼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;MVP&lt;/b&gt;(Model-View-Presenter)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;MVP의 특징은 뷰와 모델이 프레젠터를 통해서만 동작하도록 설계된다는 것입니다. MVC에서는 모델이 뷰로 데이터를 직접 전달하거나 뷰가 모델에서 데이터를 가져오는 것도 가능합니다. 하지만 MVP에서는 뷰와 모델은 &lt;i&gt;&lt;b&gt;프레젠터를 통해서만&lt;/b&gt;&lt;/i&gt; 데이터를 교환할 수 있게 설계하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-23 오후 4.28.58.png&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PVHNx/btrUqVSxlP3/Jr9wbTkNHdKzgk5KO4KxOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PVHNx/btrUqVSxlP3/Jr9wbTkNHdKzgk5KO4KxOk/img.png&quot; data-alt=&quot;MVP&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PVHNx/btrUqVSxlP3/Jr9wbTkNHdKzgk5KO4KxOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPVHNx%2FbtrUqVSxlP3%2FJr9wbTkNHdKzgk5KO4KxOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;920&quot; data-filename=&quot;스크린샷 2022-12-23 오후 4.28.58.png&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;920&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MVP&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;MVVM&lt;/b&gt;(Model-View-View Model)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; MVVM모델은 뷰모델이 모델과 뷰 사이에 위치하게 됩니다. 구조적으로 MVP와 동일하게 보일 수 있지만, 뷰모델은 &lt;b&gt;뷰에서 보일 데이터&lt;/b&gt;와 &lt;b&gt;비즈니스 로직&lt;/b&gt;을 가지고 있습니다. MVC에서는 Model이 데이터를 전체적으로 관리하는 영역이었다면 MVVM 모델에서는 View Model이 View에서 보일 데이터를 View Model이 가지고 있고, View Model의 데이터가 변경되면 View에서 보이는 데이터 값도 변경되게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  Language &amp;amp; CS knowledge/IT  용어</category>
      <author>Daehyunii</author>
      <guid isPermaLink="true">https://pinetree93.tistory.com/321</guid>
      <comments>https://pinetree93.tistory.com/321#entry321comment</comments>
      <pubDate>Fri, 23 Dec 2022 15:49:45 +0900</pubDate>
    </item>
    <item>
      <title>[리액트를 다루는 기술] TIL-129</title>
      <link>https://pinetree93.tistory.com/320</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 오늘은 리액트 반복문과 리액트 라이프사이클 메서드들에 대해서 공부했다. 데브코스를 통해서 기본적으로 컴포넌트를 만드는 것들을 배우고는 있지만 기본적인 내용을 알고 사용하는게 굉장히 중요하다고 생각하기 때문에 &lt;s&gt;별도로 공부를 하니 생각보다 시간이 부족ㅎ&lt;/s&gt;하지만 ㅠㅠㅠ 그래도 절대 빠져서는 안되는 과정이라고 생각한다. 기본적인 개념들에 대해서는 정리를 해보았다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pinetree93.tistory.com/318&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2022.12.23 - [  Language &amp;amp; CS knowledge/React] - 컴포넌트 반복&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671731322691&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;컴포넌트 반복&quot; data-og-description=&quot;map( ) 함수의 활용 map 함수는 파라미터로 전달된 함수를 사용해서 배열 내 각 요소를 원하는 규칙에 따라 변환한 후 그 결과로 새로운 배열을 생성해 반환한다. map( ) 함수의 문법은 다음과 같다. &quot; data-og-host=&quot;pinetree93.tistory.com&quot; data-og-source-url=&quot;https://pinetree93.tistory.com/318&quot; data-og-url=&quot;https://pinetree93.tistory.com/318&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dI0IVU/hyQYOasaAY/XeHWFvkxXMKL020cZqwL00/img.png?width=323&amp;amp;height=320&amp;amp;face=0_0_323_320,https://scrap.kakaocdn.net/dn/ckE3tE/hyQZRKcP3V/P1adV2W5KubWUxVq6SAqKk/img.png?width=323&amp;amp;height=320&amp;amp;face=0_0_323_320,https://scrap.kakaocdn.net/dn/bkYafX/hyQZNVjX9V/gIm9YMSwo7BnRijbnnzCFk/img.jpg?width=664&amp;amp;height=836&amp;amp;face=47_262_517_732&quot;&gt;&lt;a href=&quot;https://pinetree93.tistory.com/318&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pinetree93.tistory.com/318&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dI0IVU/hyQYOasaAY/XeHWFvkxXMKL020cZqwL00/img.png?width=323&amp;amp;height=320&amp;amp;face=0_0_323_320,https://scrap.kakaocdn.net/dn/ckE3tE/hyQZRKcP3V/P1adV2W5KubWUxVq6SAqKk/img.png?width=323&amp;amp;height=320&amp;amp;face=0_0_323_320,https://scrap.kakaocdn.net/dn/bkYafX/hyQZNVjX9V/gIm9YMSwo7BnRijbnnzCFk/img.jpg?width=664&amp;amp;height=836&amp;amp;face=47_262_517_732');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;컴포넌트 반복&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;map( ) 함수의 활용 map 함수는 파라미터로 전달된 함수를 사용해서 배열 내 각 요소를 원하는 규칙에 따라 변환한 후 그 결과로 새로운 배열을 생성해 반환한다. map( ) 함수의 문법은 다음과 같다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pinetree93.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pinetree93.tistory.com/319&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2022.12.23 - [  Language &amp;amp; CS knowledge/React] - 컴포넌트의 라이프사이클 메서드&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671731331085&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;컴포넌트의 라이프사이클 메서드&quot; data-og-description=&quot;리액트 라이프사이클? 리액트 컴포넌트의 수명 주기이다. 쉽게 말해, 컴포넌트가 생성되고 소멸되는 이련의 과정을 라이프 사이클이라고 한다. 참고로 라이프사이클 메서드는 클래스형 컴포넌&quot; data-og-host=&quot;pinetree93.tistory.com&quot; data-og-source-url=&quot;https://pinetree93.tistory.com/319&quot; data-og-url=&quot;https://pinetree93.tistory.com/319&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bZNadl/hyQZCGgvSF/Ltrx6pKN0M7KJaWK0dqddK/img.png?width=800&amp;amp;height=658&amp;amp;face=0_0_800_658,https://scrap.kakaocdn.net/dn/b1TVJ9/hyQZDLWxZd/GKqMo9YWXMOdYYvruHhn7k/img.png?width=800&amp;amp;height=658&amp;amp;face=0_0_800_658,https://scrap.kakaocdn.net/dn/bx2LA5/hyQZH1Spyh/B8fCAldXkokI79KhQiQtF0/img.png?width=1500&amp;amp;height=1234&amp;amp;face=0_0_1500_1234&quot;&gt;&lt;a href=&quot;https://pinetree93.tistory.com/319&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pinetree93.tistory.com/319&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bZNadl/hyQZCGgvSF/Ltrx6pKN0M7KJaWK0dqddK/img.png?width=800&amp;amp;height=658&amp;amp;face=0_0_800_658,https://scrap.kakaocdn.net/dn/b1TVJ9/hyQZDLWxZd/GKqMo9YWXMOdYYvruHhn7k/img.png?width=800&amp;amp;height=658&amp;amp;face=0_0_800_658,https://scrap.kakaocdn.net/dn/bx2LA5/hyQZH1Spyh/B8fCAldXkokI79KhQiQtF0/img.png?width=1500&amp;amp;height=1234&amp;amp;face=0_0_1500_1234');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;컴포넌트의 라이프사이클 메서드&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;리액트 라이프사이클? 리액트 컴포넌트의 수명 주기이다. 쉽게 말해, 컴포넌트가 생성되고 소멸되는 이련의 과정을 라이프 사이클이라고 한다. 참고로 라이프사이클 메서드는 클래스형 컴포넌&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pinetree93.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 반복과 관련해서는 리다기를 읽기 전 인프런 강의와 데브코스 강의를 통해서 익숙하게 사용해 왔던것 같다. 하지만 그 이유에 대해서는 정확하게 알고 사용한것은 아니었다. 그런데 이제는 이해가 되기 시작하는것 같다. &lt;i&gt;&lt;b&gt;기본적으로 JSX 문법에서 { } 내부에는 표현식을 사용해야 한다&lt;/b&gt;.&lt;/i&gt; &lt;u&gt;즉 값으로 평가될 수 있는 문을 사용하거나 값을 전달해야 하기 때문에 여러문으로 이루어진 for문과 같은 반복문은 활용이 불가능하다&lt;/u&gt;. 또 리액트에서는 &lt;i&gt;&lt;b&gt;불변성을 유지&lt;/b&gt;&lt;/i&gt;하는것이 상당히 중요하다는것을 알게 되었다. 흔히 리액트, 가상돔은 리액트에 대해서 공부를 시작하면 가장 먼저 듣게되는 말이다. 이 가상돔을 통해서 업데이트되기 이전의 돔과 비교를 통해서 리렌더링 횟수를 최소한으로 줄이기 위해 리액트는 동작한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 여기서 비교가 이뤄진다는 점이 중요한데 불변성을 유지해서 데이터를 업데이트할 때는 항상 새로운, new 값을 넣어주어야 비교를 통해 최적화를 할 수 있게 되는것이라는 생각이 들었다. 그런 의미에서 &lt;b&gt;map()&lt;/b&gt; 메서드는 반복을 통해 &lt;b&gt;새로운&amp;nbsp;배열&lt;/b&gt;을 만들어 내기 때문에 &lt;i&gt;&lt;b&gt;불변성을 유지&lt;/b&gt;&lt;/i&gt;시킬 수 있는 고차 함수이다. 또 &lt;b&gt;filter()&lt;/b&gt;와 같은 메서들도 데이터를 업데이트할 때 리액트를 사용할 때 매우 유용하고 편리하게 코드를 작성할 수 있게 도와주는 고차 함수들이다. 이를 &lt;i&gt;&lt;b&gt;자유자재로 활용하는 것이 매우 중요할 것 같다.&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 그리고 두 번째로 &lt;b&gt;라이프사이클&lt;/b&gt;에 대해서 배웠다. 사실 라이프사이클이라는 개념은 데브코스를 통해 짧게나마 Vue에 대해서 공부한적이 있는데 이때 처음 알게 된 개념이었다. 물론,,, 그 당시에는 처음 듣기도 했고 너무 짧은 기간에 많은것들을 배웠기 때문에 대충 이해하고 넘어갔던것 같다. 하지만 리액트에서도 동일한 개념이 있었고 책을 통해서 라이프사이클이 무엇인지 알 수 있었다. 말 그대로 &lt;i&gt;&lt;b&gt;컴포넌트의 생명 주기&lt;/b&gt;&lt;/i&gt;이고 각 시기별로 사용할 수 있는 함수들이 존재하는 것이었다. &lt;i&gt;&lt;b&gt;리액트의 경우에는 class 컴포넌트에만 라이프사이클 메서드가 총 9개 존재하고 함수 컴포넌트의 경우에는 라이프사이클 메서드가 별도로 존재하지 않는다.&lt;/b&gt;&lt;/i&gt; 하지만 Hooks를 통해 비슷하게 구현할 수 있는 것으로 알고있다. 대표적으로 useEffect로 알고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 현재는 구체적으로&amp;nbsp;&lt;b&gt;componentDidMount&lt;/b&gt;, &lt;b&gt;componentDidUpdate&lt;/b&gt;, &lt;b&gt;componentWillIUnmount&lt;/b&gt;, 그리고 &lt;b&gt;shouldComponentUpdate &lt;/b&gt;정도만 언제 활용하면 좋은지 대략적으로 알게 되었다. 지금은 컴포넌트를 만들때 함수형으로 많이 연습하고 있어서 class 컴포넌트 자체가 엄청 익숙한 상태는 아니지만 &lt;u&gt;&lt;b&gt;class 컴포넌트를 통해 알게된 것들을 함수 컴포넌트와 비교해보면서 동일하거나 비슷한것들을 확인한다면 훨씬 효과적으로 공부할 수 있는것 같다.&lt;/b&gt;&lt;/u&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;오늘을 마무리하며... 너무 졸린 관계로 한 문장으로 정리해보겠다 '갈 길이 멀다'...&lt;/span&gt;&lt;/blockquote&gt;</description>
      <category>✏️ 2022. TIL/December (데브코스)</category>
      <author>Daehyunii</author>
      <guid isPermaLink="true">https://pinetree93.tistory.com/320</guid>
      <comments>https://pinetree93.tistory.com/320#entry320comment</comments>
      <pubDate>Fri, 23 Dec 2022 03:07:17 +0900</pubDate>
    </item>
    <item>
      <title>컴포넌트의 라이프사이클 메서드</title>
      <link>https://pinetree93.tistory.com/319</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;리액트 라이프사이클?&lt;br /&gt;리액트 컴포넌트의 수명 주기이다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 쉽게 말해, 컴포넌트가 생성되고 소멸되는 이련의 과정을 라이프 사이클이라고 한다. &lt;i&gt;&lt;b&gt;참고로 라이프사이클 메서드는 클래스형 컴포넌트에서만 사용할 수 있다.&lt;/b&gt;&lt;/i&gt; 함수 컴포넌트에서는 Hooks 기능을 사용하여 비슷한 작업을 처리할 수는 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 일반적으로 리액트를 작성할 때 함수형 컴포넌트를 많이 사용하므로 &lt;i&gt;&lt;b&gt;'이런 것들이 있구나'&lt;/b&gt;&lt;/i&gt;하고 느끼고 &lt;b&gt;함수 컴포넌트에서는 이를 어떻게 비슷하게 Hooks로 만들었는지 비교해보면 좋을 것 같다.&lt;/b&gt; 오늘은 class형 컴포넌트 라이프사이클 메서드들에 대해서만 다뤄보도록 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;우선 라이프사이클은 총 세 가지 기준으로 나눠볼 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;1. 마운트&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; DOM이 생성되고 웹 브라우저상에 나타날 때를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;2. 업데이트&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 데이터가 변경되는 경우를 의미한다. 업데이트가 이뤄지는 리액트에서 4가지 경우가 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;props가 바뀔 때&lt;/li&gt;
&lt;li&gt;state가 바뀔 때&lt;/li&gt;
&lt;li&gt;부모 컴포넌트가 리렌더링 될 때&lt;/li&gt;
&lt;li&gt;this.forceUpdate로 강제로 렌더링을 트리거할 때&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 4가지 경우에 업데이트가 이뤄진다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;3. 언마운트&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 컴포넌트를 DOM에서 제거하는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 각각의 행위가 일어나는 시기를 기준으로 호출할 수 있는 메서드들이 존재한다. 우선 큰 그림을 통해 전체적인 흐림을 알아보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-12-23 오전 2.30.31.png&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;1234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GAjfj/btrUlHNsGnx/Jmwzt8QvGIp7wKCmpUJ1w1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GAjfj/btrUlHNsGnx/Jmwzt8QvGIp7wKCmpUJ1w1/img.png&quot; data-alt=&quot;리액트 class 라이프사이클&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GAjfj/btrUlHNsGnx/Jmwzt8QvGIp7wKCmpUJ1w1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGAjfj%2FbtrUlHNsGnx%2FJmwzt8QvGIp7wKCmpUJ1w1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1500&quot; height=&quot;1234&quot; data-filename=&quot;스크린샷 2022-12-23 오전 2.30.31.png&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;1234&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;리액트 class 라이프사이클&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 라이프사이클 메서드를 호출하면 위의 흐름에 해당하는 시기에 해당 메서드가 호출되게 된다. 많은 라이프사이클 메서드들이 존재하지만 그 중에서도 많이 사용하고 중요한 메서드들이라고 생각되는 몇 가지 라이프사이클 메서드를 정리해보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(render 메서드, constructor 메서드는 생략하도록 하겠다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. componentDidMount 메서드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이것은 컴포넌트를 만들고 첫 렌더링을 다 마친 후 실행된다. 이 안에서는 다른 자바스크립트 라이브러리나 프레임워크 혹은 함수를 호출하거나 이벤트 등록, setTimeout, setInterval, 네트워크 요청과 같은 비동기 작업을 처리하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. componentDidUpadate(prevProps, prevState, snapshot) 메서드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이것은 렌더링을 완료한 후 실행한다. 인수로는 prevProps, prevState, snapshot을 인수로 받으면 단어의 의미대로 이전 props와 이전 state를 가지고 있으며 이를 통해 이전에 가졌던 데이터에 접근할 수 있다. snapshot은 getSnapshotBeforeUpdate에서 반환한 값이 있다면 여기서 snapshot 값을 전달받을 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. componentWillUnmount 메서드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이것은 컴포넌트를 DOm에서 제거되기 직전에 실행된다. 이때 등록한 이벤트, 타이머가 있다면 여기서 제거 작업을 해야 메모리 누수를 방지할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. shouldComponentUpdate(nextProps, nextState) 메서드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이것은 props 또는 state를 변경했을 때, 리렌더링을 시작할지 여부를 지정하는 메서드로 메서드는 true 또는 false값을 반환해야 한다. 만약 따로 설정하지 않는다면 기본적으로 언제나 true 값을 반환한다. 메서드를 설정하여 false값을 반환하면 업데이트 과정을 중지한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인수로 전달되는 nextProps나 nextState를 통해 현재 상태의 값과 비교하여 변화가 있는 경우에는 true를 아닌 경우에는 false를 반환하게 해주면 리렌더링을 방지하게 된다. 이를 통해 최적화를 할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 대표적으로 많이 사용되고 있는 class 컴포넌트의 라이프사이클 메서드들에 대해서 알아보았다. 내용을 세세하게 알고 외우는 느낌보다는 이런게 있다 정도로 알아두면 도움이 될 것 같다.(지금 외워도 어차피,,,까먹는다... )&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>  Language &amp;amp; CS knowledge/React</category>
      <author>Daehyunii</author>
      <guid isPermaLink="true">https://pinetree93.tistory.com/319</guid>
      <comments>https://pinetree93.tistory.com/319#entry319comment</comments>
      <pubDate>Fri, 23 Dec 2022 02:44:23 +0900</pubDate>
    </item>
    <item>
      <title>컴포넌트 반복</title>
      <link>https://pinetree93.tistory.com/318</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;map( ) 함수의 활용&lt;br /&gt;map 함수는 파라미터로 전달된 함수를 사용해서 배열 내 각 요소를 원하는 규칙에 따라 변환한 후 그 결과로 새로운 배열을 생성해 반환한다.&amp;nbsp;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;map( ) 함수의 문법은 다음과 같다.&amp;nbsp;&lt;br /&gt;첫 번째 인수는 콜백 함수를 받는다.&lt;br /&gt;&lt;br /&gt;콜백 함수의 인자로는 (value, index, array) 세 가지를 받는다.&amp;nbsp;&lt;br /&gt;-value: 현재 반복되고 있는 array요소 값&lt;br /&gt;-index: 현재 반복되고 있는 array요소의 index값&lt;br /&gt;-array: 현재 반복되고 있는 배열 그 자체&lt;br /&gt;&lt;br /&gt;ex) array.map((value,index,array) =&amp;gt; { })&lt;br /&gt;두 번째 인수는 callback 함수 내부에서 사용할 this 레퍼런스를 받는다.&lt;/blockquote&gt;
&lt;pre id=&quot;code_1671727594521&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const numbers = [1, 2, 3, 4, 5];

const doubleNumbers = numbers.map((v) =&amp;gt; {
	return v * 2;
});

console.log(doubleNumbers); // [2, 4, 6, 8, 10];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이러한 방법을 이용해서 컴포넌트로 구성된 배열을 생성할 수도 있다. 설명보다는 예시를 보는것이 더 직관적으로 이해하기 쉬울 것 같다. 다음 코드를 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1671727985039&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const names = ['woo', 'park', 'kim', 'lee']
{names.map((name, index) =&amp;gt; &amp;lt;li key={index}&amp;gt;{name}&amp;lt;/li&amp;gt;};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 이러한 방법으로 반복을 통해서 해당 데이터를 JSX 코드로 된 배열을 새로 생성할 수 있다. 이를 통해 컴포넌트에 렌더링을 하면 매우 간단하게 코드를 작성할 수 있다. 그리고 &lt;i&gt;&lt;b&gt;가장 중요한 점은 map() 메서드는 새로운 배열을 생성해서 반환한다는 점이다.&lt;/b&gt;&lt;/i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;push메서드의 경우에는 원본 배열을 변경하게 된다. &lt;u&gt;이 둘의 차이점은 새로운 배열이 생성되느냐 원본 배열의 상태를 변경하느냐인데,&lt;/u&gt; 리액트에서는 이 점이 매우 중요하다. 그리고 리액트에서 데이터를 업데이트 해줄 때는 항상 새로운(New) 데이터로 업데이트를 해주어야 한다. 이를 &lt;i&gt;&lt;b&gt;불변성 유지&lt;/b&gt;&lt;/i&gt;라고 하는데 불변성을 유지해 주어야 나중에 리액트 컴포넌트의 성능을 최적화할 수 있기 때문이다. 즉, 기존 DOM과의 비교를 보다 쉽게 하기 위해서라고 나는 이해했다. 그래서 &lt;b&gt;map( )메서드는 리액트에서 매우 유용&lt;/b&gt;하다고 생각한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 여기서 또 주의해야할 점이 한 가지 있다! &lt;i&gt;&lt;b&gt;바로 map( )을 통해 생성되는 컴포넌트 배열은 prop으로 key를 설정해 주어야 한다. 이 key는 고유한 값이어야 한다.&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;&amp;nbsp; key를 왜 설정해야할까? key가 없는 경우에는 리액트 Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지한다. 하지만 key가 있다면 이 값을 사용하여 어떤 변화가 일어났는지 더욱 빠르게 알아낼 수 있기 때문이다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; key를 설정하는 방법은 자유롭게 설정하는것이 좋지만 고유한 값으로 설정해야 하며, index번호는 피하는것이 좋다. 배열이 변경되는 경우에 효율적으로 리렌더링하지 못하기 때문이다. &lt;i&gt;&lt;b&gt;별도로 id 데이터를 만들어 사용해도 좋고, uidd 라이브러리를 사용해 id를 활용하는 방법도 있다.&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 리액트 컴포넌트 반복에 대해서 알아보았다 &lt;/p&gt;</description>
      <category>  Language &amp;amp; CS knowledge/React</category>
      <author>Daehyunii</author>
      <guid isPermaLink="true">https://pinetree93.tistory.com/318</guid>
      <comments>https://pinetree93.tistory.com/318#entry318comment</comments>
      <pubDate>Fri, 23 Dec 2022 02:09:04 +0900</pubDate>
    </item>
  </channel>
</rss>