<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>가치투자자</title>
    <link>https://valueengine.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 8 Jul 2026 23:59:41 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>미주민</managingEditor>
    <image>
      <title>가치투자자</title>
      <url>https://tistory1.daumcdn.net/tistory/6172576/attach/65bae679cc7b4577b73330f1815cbf44</url>
      <link>https://valueengine.tistory.com</link>
    </image>
    <item>
      <title>D3 라이브러리</title>
      <link>https://valueengine.tistory.com/82</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;D3.js&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. svg로 가지치기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img1.png&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H5OML/btsrErXkgwT/iFSwj1h6OyR2TLkNjeYVjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H5OML/btsrErXkgwT/iFSwj1h6OyR2TLkNjeYVjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H5OML/btsrErXkgwT/iFSwj1h6OyR2TLkNjeYVjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH5OML%2FbtsrErXkgwT%2FiFSwj1h6OyR2TLkNjeYVjk%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;500&quot; height=&quot;269&quot; data-filename=&quot;img1.png&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1692434414382&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from &quot;react&quot;;

const App = () =&amp;gt; {
  const width = 400;
  const height = 200;

  const line1 = [{ x: 50, y: 100 }, { x: 150, y: 50 }];
  const line2 = [{ x: 250, y: 100 }, { x: 350, y: 150 }];

  const renderLine = (points) =&amp;gt; (
    &amp;lt;line
      x1={points[0].x}
      y1={points[0].y}
      x2={points[1].x}
      y2={points[1].y}
      stroke=&quot;black&quot;
    /&amp;gt;
  );

  const renderDottedLine = (point) =&amp;gt; (
    &amp;lt;line
      x1={point.x}
      y1={point.y + 10}
      x2={point.x}
      y2={height - 10}
      stroke=&quot;black&quot;  /* 점선 색깔 */
      strokeDasharray=&quot;5,5&quot; /* 점선 길이, 점선 간격 */ 
    /&amp;gt;
  );

  return (
    &amp;lt;svg width={width} height={height}&amp;gt;
      {/* 그래프 선 그리기 */}
      {renderLine(line1)}
      {renderLine(line2)}

      {/* 각 꼭지점에서의 점선 (범주 가지치기) */}
      {line1.map(renderDottedLine)}
      {line2.map(renderDottedLine)}
    &amp;lt;/svg&amp;gt;
  );
};

export default App;&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2. D3.js&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1) 기본 문법&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;d3.select(&quot;태그&quot;)&lt;/b&gt; : 태그 하나 선택&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;d3.selectAll(&quot;태그&quot;)&lt;/b&gt; : 태그 전체 선택&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;.attr()&lt;/b&gt; : 속성값을 지정하거나 가져온다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;.style&lt;/b&gt; : css 스타일 프로퍼티를 지정하거나 가겨온다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;.data&lt;/b&gt; : 데이터를 요소에 가져온다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;.append(&quot;태그&quot;)&lt;/b&gt; : 새로운 태그 추가&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;.enter&lt;/b&gt; : 태그가 데이터보다 적을 경우, 데이터 수만큼 태그 생성&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;.exit&lt;/b&gt; : 태드가 데이터보다 많을 경우, 태그 속성 지정을 종료하고 remove로 나머지 태그 제거&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;remove&lt;/b&gt; : 선택된 태그 제거&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;예시 1) D3로 가지치기&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img2.png&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ed8PW/btsrEA7OTRO/VYXcsLvckEH36RzaDuUMK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ed8PW/btsrEA7OTRO/VYXcsLvckEH36RzaDuUMK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ed8PW/btsrEA7OTRO/VYXcsLvckEH36RzaDuUMK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEd8PW%2FbtsrEA7OTRO%2FVYXcsLvckEH36RzaDuUMK1%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;500&quot; height=&quot;269&quot; data-filename=&quot;img2.png&quot; data-origin-width=&quot;770&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1692440387679&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect, useRef } from &quot;react&quot;;
import * as d3 from &quot;d3&quot;;

const App = () =&amp;gt; {
  const svgRef = useRef(null);

  useEffect(() =&amp;gt; {
    const svg = d3.select(svgRef.current);

    const WIDTH = 400;
    const HEIGHT = 200;

    const line1 = [{ x: 50, y: 100 }, { x: 150, y: 50 }];
    const line2 = [{ x: 250, y: 100 }, { x: 350, y: 150 }];

    // 그래프 선 생성함수
    const lineGenerator = d3.line()
      .x(d =&amp;gt; d.x)
      .y(d =&amp;gt; d.y);

    // 선 추가
    svg
      .append(&quot;path&quot;)
      .attr(&quot;d&quot;, lineGenerator(line1))
      .attr(&quot;stroke&quot;, &quot;black&quot;)
      .attr(&quot;fill&quot;, &quot;none&quot;);

    svg
      .append(&quot;path&quot;)
      .attr(&quot;d&quot;, lineGenerator(line2))
      .attr(&quot;stroke&quot;, &quot;black&quot;)
      .attr(&quot;fill&quot;, &quot;none&quot;);

    // 점선 추가
    const addDottedLines = (points) =&amp;gt; {
      points.forEach(point =&amp;gt; {
        svg
          .append(&quot;line&quot;)
          .attr(&quot;x1&quot;, point.x)
          .attr(&quot;y1&quot;, point.y + 10)
          .attr(&quot;x2&quot;, point.x)
          .attr(&quot;y2&quot;, HEIGHT - 10)
          .attr(&quot;stroke&quot;, &quot;black&quot;)
          .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);
      });
    };

    addDottedLines(line1);
    addDottedLines(line2);
  }, []);

  return (
    &amp;lt;svg ref={svgRef} width={400} height={200}&amp;gt;&amp;lt;/svg&amp;gt;
  );
};

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;예시 2-1) D3로 범주 선 그래스 생성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img3.png&quot; data-origin-width=&quot;1848&quot; data-origin-height=&quot;816&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDj34B/btsrxOz4rXT/KOJJr3K0QlCdW6TRiRDzNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDj34B/btsrxOz4rXT/KOJJr3K0QlCdW6TRiRDzNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDj34B/btsrxOz4rXT/KOJJr3K0QlCdW6TRiRDzNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDj34B%2FbtsrxOz4rXT%2FKOJJr3K0QlCdW6TRiRDzNK%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;700&quot; height=&quot;309&quot; data-filename=&quot;img3.png&quot; data-origin-width=&quot;1848&quot; data-origin-height=&quot;816&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1692472635192&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect, useRef } from &quot;react&quot;;
import * as d3 from &quot;d3&quot;;

const App = () =&amp;gt; {
  const svgRef = useRef(null);

  useEffect(() =&amp;gt; {
    const svg = d3.select(svgRef.current);

    const width = 800;
    const height = 400;

    const lines = [
      { 
        points: [{ x: 50, y: 350 }, { x: 150, y: 250 }, { x: 250, y: 150 }, { x: 350, y: 250 }, { x: 450, y: 350 }, { x: 550, y: 250 }, { x: 650, y: 150 }, { x: 750, y: 250 }],
        category: &quot;Category 1&quot;
      },
      {
        points: [{ x: 50, y: 150 }, { x: 150, y: 350 }, { x: 250, y: 250 }, { x: 350, y: 150 }, { x: 450, y: 350 }, { x: 550, y: 150 }, { x: 650, y: 250 }, { x: 750, y: 350 }],
        category: &quot;Category 2&quot;
      }
    ];

    // 그래프 선 생성함수
    const lineGenerator = d3.line()
      .x(d =&amp;gt; d.x)
      .y(d =&amp;gt; d.y);

    // 그래프 축
    const xScale = d3.scaleLinear().domain([0, width]).range([0, width]);     /* [최소값, 최대값] */
    const yScale = d3.scaleLinear().domain([0, height]).range([height, 0]);   /* 기존 간격(입력범위, domain)을 새로운 간격(출력범위, range)으로 변환 */
    const xAxis = d3.axisBottom(xScale);  /* x축 생성 */
    const yAxis = d3.axisLeft(yScale);    /* y축 생성 */
    svg.append(&quot;g&quot;).call(xAxis).attr(&quot;transform&quot;, `translate(0, ${height})`);  /* x축을 아래쪽으로 height만큼 이동 */
    svg.append(&quot;g&quot;).call(yAxis);  /* call : 축 그리기 */

    // 선 추가
    lines.forEach((line, idx) =&amp;gt; {
      svg
        .append(&quot;path&quot;)
        .attr(&quot;d&quot;, lineGenerator(line.points))
        .attr(&quot;stroke&quot;, idx === 0 ? &quot;blue&quot; : &quot;red&quot;)
        .attr(&quot;fill&quot;, &quot;none&quot;);

      // x축 끝에 점선 추가
      svg
        .append(&quot;line&quot;)
        .attr(&quot;x1&quot;, width)
        .attr(&quot;y1&quot;, line.points[line.points.length - 1].y)  /* 그래프 선 끝 y축 높이 */
        .attr(&quot;x2&quot;, width + 30)
        .attr(&quot;y2&quot;, line.points[line.points.length - 1].y)
        .attr(&quot;stroke&quot;, idx === 0 ? &quot;blue&quot; : &quot;red&quot;)
        .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);

      // 범주명 추가
      svg
        .append(&quot;text&quot;)
        .attr(&quot;x&quot;, width + 35)
        .attr(&quot;y&quot;, line.points[line.points.length - 1].y + 5)
        .attr(&quot;fill&quot;, idx === 0 ? &quot;blue&quot; : &quot;red&quot;)
        .text(line.category);
    });

  }, []);

  return (
    &amp;lt;svg ref={svgRef} width={900} height={400}&amp;gt;&amp;lt;/svg&amp;gt;
  );
};

export default App;&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;예시 2-2) 꺾이는 범주의 점선&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img4.png&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;286&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bE85hQ/btsrDFBBvH0/fcFfq2TMstKFVpFuRueg2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bE85hQ/btsrDFBBvH0/fcFfq2TMstKFVpFuRueg2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bE85hQ/btsrDFBBvH0/fcFfq2TMstKFVpFuRueg2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbE85hQ%2FbtsrDFBBvH0%2FfcFfq2TMstKFVpFuRueg2k%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;700&quot; height=&quot;225&quot; data-filename=&quot;img4.png&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;286&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1692475206833&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect, useRef } from &quot;react&quot;;
import * as d3 from &quot;d3&quot;;

const lines = [
  {
    points: [{ x: 52, y: 340 }, { x: 145, y: 242 }, { x: 243, y: 158 }, { x: 359, y: 236 }, { x: 456, y: 333 }, { x: 541, y: 227 }, { x: 644, y: 148 }, { x: 731, y: 239 }],
    category: &quot;범주 1&quot;,
  },
  {
    points: [{ x: 57, y: 124 }, { x: 149, y: 321 }, { x: 252, y: 213 }, { x: 355, y: 137 }, { x: 444, y: 321 }, { x: 548, y: 129 }, { x: 643, y: 212 }, { x: 742, y: 323 }],
    category: &quot;범주 2&quot;,
  },
  {
    points: [{ x: 49, y: 189 }, { x: 143, y: 279 }, { x: 249, y: 198 }, { x: 357, y: 287 }, { x: 442, y: 195 }, { x: 539, y: 278 }, { x: 649, y: 199 }, { x: 737, y: 292 }],
    category: &quot;범주 3&quot;,
  },
  {
    points: [{ x: 59, y: 295 }, { x: 141, y: 192 }, { x: 255, y: 295 }, { x: 349, y: 188 }, { x: 457, y: 296 }, { x: 544, y: 182 }, { x: 652, y: 292 }, { x: 739, y: 179 }],
    category: &quot;범주 4&quot;,
  },
  {
    points: [{ x: 54, y: 264 }, { x: 146, y: 169 }, { x: 253, y: 266 }, { x: 351, y: 157 }, { x: 456, y: 263 }, { x: 539, y: 154 }, { x: 641, y: 265 }, { x: 746, y: 166 }],
    category: &quot;범주 5&quot;,
  },
  {
    points: [{ x: 56, y: 310 }, { x: 147, y: 218 }, { x: 248, y: 308 }, { x: 358, y: 209 }, { x: 453, y: 312 }, { x: 540, y: 210 }, { x: 639, y: 311 }, { x: 734, y: 216 }],
    category: &quot;범주 6&quot;,
  },
  {
    points: [ { x: 58, y: 234 }, { x: 142, y: 144 }, { x: 250, y: 234 }, { x: 353, y: 137 }, { x: 454, y: 232 }, { x: 547, y: 136 }, { x: 640, y: 238 }, { x: 748, y: 129 }],
    category: &quot;범주 7&quot;,
  },
];

const App = () =&amp;gt; {
  const svgRef = useRef(null);

  // 각 범주의 위치를 저장하는 배열
  let categoriesY = [];

  useEffect(() =&amp;gt; {
    const svg = d3.select(svgRef.current);

    categoriesY = [];   // 초기화

    const width = 800;
    const height = 400;

    // 그래프 선 생성함수
    const lineGenerator = d3.line()
      .x(d =&amp;gt; d.x)
      .y(d =&amp;gt; d.y);

    // 그래프 축
    const xScale = d3.scaleLinear().domain([0, width]).range([0, width]);     /* [최소값, 최대값] */
    const yScale = d3.scaleLinear().domain([0, height]).range([height, 0]);   /* 기존 간격(입력범위, domain)을 새로운 간격(출력범위, range)으로 변환 */
    const xAxis = d3.axisBottom(xScale);  /* x축 생성 */
    const yAxis = d3.axisLeft(yScale);    /* y축 생성 */
    svg.append(&quot;g&quot;).call(xAxis).attr(&quot;transform&quot;, `translate(0, ${height})`);  /* x축을 아래쪽으로 height만큼 이동 */
    svg.append(&quot;g&quot;).call(yAxis);  /* call : 축 그리기 */

    // 선 추가
    lines.forEach((line, idx) =&amp;gt; {
      let lineEndY = line.points[line.points.length - 1].y;
      let labelY = lineEndY;

      // 범주의 위치가 다른 범주와 겹치는지 확인
      let overlaps = true;
      while (overlaps) {
        overlaps = false;
        for (let y of categoriesY) {
          if (Math.abs(y - labelY) &amp;lt; 20) { // 20은 글자 크기에 따라 조정 가능
            labelY -= 20; // 위로 20만큼 이동
            overlaps = true; // 겹치는 것을 발견하면 overlaps를 true로 설정
            break;
          }
        }
      }
      categoriesY.push(labelY);

      svg.append(&quot;path&quot;)
         .attr(&quot;d&quot;, lineGenerator(line.points))
         .attr(&quot;stroke&quot;, idx % 2 === 0 ? &quot;blue&quot; : &quot;red&quot;)
         .attr(&quot;fill&quot;, &quot;none&quot;);

      // x축 끝에 점선 추가
      svg.append(&quot;line&quot;)
         .attr(&quot;x1&quot;, width)
         .attr(&quot;y1&quot;, lineEndY)  /* 그래프 선 끝 y축 높이 */
         .attr(&quot;x2&quot;, width + (lineEndY !== labelY ? 15 : 30))  // 꺾는 선이 있는 경우에는 좌표를 조정
         .attr(&quot;y2&quot;, lineEndY)
         .attr(&quot;stroke&quot;, idx % 2 === 0 ? &quot;blue&quot; : &quot;red&quot;)
         .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);

      if (lineEndY !== labelY) {  // 꺾는 선이 필요한 경우
        svg.append(&quot;line&quot;)
           .attr(&quot;x1&quot;, width + 15)
           .attr(&quot;y1&quot;, lineEndY)
           .attr(&quot;x2&quot;, width + 15)
           .attr(&quot;y2&quot;, labelY)
           .attr(&quot;stroke&quot;, idx % 2 === 0 ? &quot;blue&quot; : &quot;red&quot;)
           .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);

        svg.append(&quot;line&quot;)
           .attr(&quot;x1&quot;, width + 15)
           .attr(&quot;y1&quot;, labelY)
           .attr(&quot;x2&quot;, width + 30)
           .attr(&quot;y2&quot;, labelY)
           .attr(&quot;stroke&quot;, idx % 2 === 0 ? &quot;blue&quot; : &quot;red&quot;)
           .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);
      }

      // 범주명 추가
      svg.append(&quot;text&quot;)
         .attr(&quot;x&quot;, width + 35)
         .attr(&quot;y&quot;, labelY + 5)
         .attr(&quot;fill&quot;, idx % 2 === 0 ? &quot;blue&quot; : &quot;red&quot;)
         .text(line.category);
    });

  }, []);

  return (
    &amp;lt;svg ref={svgRef} width={900} height={400}&amp;gt;&amp;lt;/svg&amp;gt;
  );
};

export default App;&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;예시 2-3) 차트 색상 구별 및 차트와 점선 연결&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img5.png&quot; data-origin-width=&quot;1776&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wabjI/btsryswRR5E/xQ0xATSNOjsA93UXM72aI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wabjI/btsryswRR5E/xQ0xATSNOjsA93UXM72aI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wabjI/btsryswRR5E/xQ0xATSNOjsA93UXM72aI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwabjI%2FbtsryswRR5E%2FxQ0xATSNOjsA93UXM72aI1%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;700&quot; height=&quot;263&quot; data-filename=&quot;img5.png&quot; data-origin-width=&quot;1776&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1692480001584&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect, useRef } from &quot;react&quot;;
import * as d3 from &quot;d3&quot;;

const lines = [
  {
    points: [{ x: 52, y: 340 }, { x: 145, y: 242 }, { x: 243, y: 158 }, { x: 359, y: 236 }, { x: 456, y: 333 }, { x: 541, y: 227 }, { x: 644, y: 148 }, { x: 731, y: 239 }],
    category: &quot;범주 1&quot;,
  },
  {
    points: [{ x: 57, y: 124 }, { x: 149, y: 321 }, { x: 252, y: 213 }, { x: 355, y: 137 }, { x: 444, y: 321 }, { x: 548, y: 129 }, { x: 643, y: 212 }, { x: 742, y: 323 }],
    category: &quot;범주 2&quot;,
  },
  {
    points: [{ x: 49, y: 189 }, { x: 143, y: 279 }, { x: 249, y: 198 }, { x: 357, y: 287 }, { x: 442, y: 195 }, { x: 539, y: 278 }, { x: 649, y: 199 }, { x: 737, y: 292 }],
    category: &quot;범주 3&quot;,
  },
  {
    points: [{ x: 59, y: 295 }, { x: 141, y: 192 }, { x: 255, y: 295 }, { x: 349, y: 188 }, { x: 457, y: 296 }, { x: 544, y: 182 }, { x: 652, y: 292 }, { x: 739, y: 179 }],
    category: &quot;범주 4&quot;,
  },
  {
    points: [{ x: 54, y: 264 }, { x: 146, y: 169 }, { x: 253, y: 266 }, { x: 351, y: 157 }, { x: 456, y: 263 }, { x: 539, y: 154 }, { x: 641, y: 265 }, { x: 746, y: 166 }],
    category: &quot;범주 5&quot;,
  },
  {
    points: [{ x: 56, y: 310 }, { x: 147, y: 218 }, { x: 248, y: 308 }, { x: 358, y: 209 }, { x: 453, y: 312 }, { x: 540, y: 210 }, { x: 639, y: 311 }, { x: 734, y: 216 }],
    category: &quot;범주 6&quot;,
  },
  {
    points: [ { x: 58, y: 234 }, { x: 142, y: 144 }, { x: 250, y: 234 }, { x: 353, y: 137 }, { x: 454, y: 232 }, { x: 547, y: 136 }, { x: 640, y: 238 }, { x: 748, y: 129 }],
    category: &quot;범주 7&quot;,
  },
];

const App = () =&amp;gt; {
  const svgRef = useRef(null);  // React ref를 사용하여 SVG 엘리먼트를 참조합니다.

  // 각 범주의 Y 위치를 저장하는 배열
  let categoriesY = [];

  useEffect(() =&amp;gt; {
    const svg = d3.select(svgRef.current);  // D3로 SVG 엘리먼트를 선택합니다.

    categoriesY = [];   // 범주의 Y 위치 배열을 초기화

    const width = 800;
    const height = 400;

    // 그래프 선 생성함수
    const lineGenerator = d3.line()
      .x(d =&amp;gt; d.x)
      .y(d =&amp;gt; d.y);

    // 그래프 축
    const xScale = d3.scaleLinear().domain([0, width]).range([0, width]);     /* [최소값, 최대값] */
    const yScale = d3.scaleLinear().domain([0, height]).range([height, 0]);   /* 기존 간격(입력범위, domain)을 새로운 간격(출력범위, range)으로 변환 */
    const xAxis = d3.axisBottom(xScale);  /* x축 생성 */
    const yAxis = d3.axisLeft(yScale);    /* y축 생성 */
    svg.append(&quot;g&quot;).call(xAxis).attr(&quot;transform&quot;, `translate(0, ${height})`);  /* x축을 아래쪽으로 height만큼 이동 */
    svg.append(&quot;g&quot;).call(yAxis);  /* call : 축 그리기 */

    // 색상 스케일을 정의
    const colorScale = d3.scaleOrdinal(d3.schemeCategory10); // D3의 기본 10가지 카테고리 컬러를 사용

    // 선 추가 : 각 선 데이터를 순회하면서 그래프 생성
    lines.forEach((line, idx) =&amp;gt; {
      const lineColor = colorScale(idx); // idx를 기반으로 색상을 지정
      let lineEndX = line.points[line.points.length - 1].x;  /* 마지막 x 좌표 */
      let lineEndY = line.points[line.points.length - 1].y;  /* 마지막 y 좌표 */
      let labelY = lineEndY;

      // 범주의 위치가 다른 범주와 겹치는지 확인
      let overlaps = true;
      while (overlaps) {
        overlaps = false;
        for (let y of categoriesY) {
          if (Math.abs(y - labelY) &amp;lt; 20) { // 20은 글자 크기에 따라 조정 가능
            labelY -= 20; // 위로 20만큼 이동
            overlaps = true; // 겹치는 것을 발견하면 overlaps를 true로 설정
            break;
          }
        }
      }
      categoriesY.push(labelY);  // 조정된 Y 위치를 배열에 추가

      // 선 추가
      svg.append(&quot;path&quot;)
         .attr(&quot;d&quot;, lineGenerator(line.points))
         .attr(&quot;stroke&quot;, lineColor)
         .attr(&quot;fill&quot;, &quot;none&quot;);

      // x축 끝에 점선 추가
      svg.append(&quot;line&quot;)
         .attr(&quot;x1&quot;, lineEndX)
         .attr(&quot;y1&quot;, lineEndY)  /* 그래프 선 끝 y축 높이 */
         .attr(&quot;x2&quot;, lineEndY !== labelY ? width + 15 : width + 27)  // 꺾는 선이 있는 경우에는 좌표를 조정
         .attr(&quot;y2&quot;, lineEndY)
         .attr(&quot;stroke&quot;, lineColor)
         .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);

      // 꺾는 선이 필요한 경우
      if (lineEndY !== labelY) {
        svg
          .append(&quot;line&quot;)
          .attr(&quot;x1&quot;, width + 15)
          .attr(&quot;y1&quot;, lineEndY)
          .attr(&quot;x2&quot;, width + 15)
          .attr(&quot;y2&quot;, labelY)
          .attr(&quot;stroke&quot;, lineColor)
          .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);

        svg.append(&quot;line&quot;)
           .attr(&quot;x1&quot;, width + 15)
           .attr(&quot;y1&quot;, labelY)
           .attr(&quot;x2&quot;, width + 30)
           .attr(&quot;y2&quot;, labelY)
           .attr(&quot;stroke&quot;, lineColor)
           .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);
      }

      // 범주명 추가
      svg.append(&quot;text&quot;)
         .attr(&quot;x&quot;, width + 35)
         .attr(&quot;y&quot;, labelY + 5)
         .attr(&quot;fill&quot;, lineColor)
         .text(line.category);
    });

  }, []);

  return (
    &amp;lt;svg ref={svgRef} width={900} height={400}&amp;gt;&amp;lt;/svg&amp;gt;
  );
};

export default App;&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;예시 2-4) 툴팁 기능 추가&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;img6.png&quot; data-origin-width=&quot;1776&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cF0M2T/btsrNzUX2qk/rMKsBB1oML2o0pIcYbZKY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cF0M2T/btsrNzUX2qk/rMKsBB1oML2o0pIcYbZKY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cF0M2T/btsrNzUX2qk/rMKsBB1oML2o0pIcYbZKY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcF0M2T%2FbtsrNzUX2qk%2FrMKsBB1oML2o0pIcYbZKY0%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;700&quot; height=&quot;263&quot; data-filename=&quot;img6.png&quot; data-origin-width=&quot;1776&quot; data-origin-height=&quot;668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1692521541661&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect, useRef } from &quot;react&quot;;
import * as d3 from &quot;d3&quot;;

const lines = [
  {
    points: [{ x: 52, y: 340 }, { x: 145, y: 242 }, { x: 243, y: 158 }, { x: 359, y: 236 }, { x: 456, y: 333 }, { x: 541, y: 227 }, { x: 644, y: 148 }, { x: 731, y: 239 }],
    category: &quot;범주 1&quot;,
  },
  {
    points: [{ x: 57, y: 124 }, { x: 149, y: 321 }, { x: 252, y: 213 }, { x: 355, y: 137 }, { x: 444, y: 321 }, { x: 548, y: 129 }, { x: 643, y: 212 }, { x: 742, y: 323 }],
    category: &quot;범주 2&quot;,
  },
  {
    points: [{ x: 49, y: 189 }, { x: 143, y: 279 }, { x: 249, y: 198 }, { x: 357, y: 287 }, { x: 442, y: 195 }, { x: 539, y: 278 }, { x: 649, y: 199 }, { x: 737, y: 292 }],
    category: &quot;범주 3&quot;,
  },
  {
    points: [{ x: 59, y: 295 }, { x: 141, y: 192 }, { x: 255, y: 295 }, { x: 349, y: 188 }, { x: 457, y: 296 }, { x: 544, y: 182 }, { x: 652, y: 292 }, { x: 739, y: 179 }],
    category: &quot;범주 4&quot;,
  },
  {
    points: [{ x: 54, y: 264 }, { x: 146, y: 169 }, { x: 253, y: 266 }, { x: 351, y: 157 }, { x: 456, y: 263 }, { x: 539, y: 154 }, { x: 641, y: 265 }, { x: 746, y: 166 }],
    category: &quot;범주 5&quot;,
  },
  {
    points: [{ x: 56, y: 310 }, { x: 147, y: 218 }, { x: 248, y: 308 }, { x: 358, y: 209 }, { x: 453, y: 312 }, { x: 540, y: 210 }, { x: 639, y: 311 }, { x: 734, y: 216 }],
    category: &quot;범주 6&quot;,
  },
  {
    points: [ { x: 58, y: 234 }, { x: 142, y: 144 }, { x: 250, y: 234 }, { x: 353, y: 137 }, { x: 454, y: 232 }, { x: 547, y: 136 }, { x: 640, y: 238 }, { x: 748, y: 129 }],
    category: &quot;범주 7&quot;,
  },
];

const App = () =&amp;gt; {
  const svgRef = useRef(null);  // React ref를 사용하여 SVG 엘리먼트를 참조합니다.
  const tooltipRef = useRef(null);  // 툴팁을 위한 ref
  let categoriesY = [];  // 각 범주의 Y 위치를 저장하는 배열

  useEffect(() =&amp;gt; {
    const svg = d3.select(svgRef.current);  // D3로 SVG 엘리먼트를 선택합니다.
    const tooltip = d3.select(tooltipRef.current);

    categoriesY = [];  // 범주의 Y 위치 배열을 초기화

    const width = 800;
    const height = 400;

    // 그래프 선 생성함수
    const lineGenerator = d3.line()
      .x(d =&amp;gt; d.x)
      .y(d =&amp;gt; d.y);

    // 그래프 축
    const xScale = d3.scaleLinear().domain([0, width]).range([0, width]);    /* [최소값, 최대값] */
    const yScale = d3.scaleLinear().domain([0, height]).range([height, 0]);  /* 기존 간격(입력범위, domain)을 새로운 간격(출력범위, range)으로 변환 */
    const xAxis = d3.axisBottom(xScale);  /* x축 생성 */
    const yAxis = d3.axisLeft(yScale);    /* y축 생성 */
    svg.append(&quot;g&quot;).call(xAxis).attr(&quot;transform&quot;, `translate(0, ${height})`);  /* x축을 아래쪽으로 height만큼 이동 */
    svg.append(&quot;g&quot;).call(yAxis);  /* call : 축 그리기 */

    // 색상 스케일을 정의
    const colorScale = d3.scaleOrdinal(d3.schemeCategory10);  // D3의 기본 10가지 카테고리 컬러를 사용

    // 선 추가 : 각 선 데이터를 순회하면서 그래프 생성
    lines.forEach((line, idx) =&amp;gt; {
      const lineColor = colorScale(idx);  // idx를 기반으로 색상을 지정
      let lineEndX = line.points[line.points.length - 1].x;  /* 마지막 x 좌표 */
      let lineEndY = line.points[line.points.length - 1].y;  /* 마지막 y 좌표 */
      let labelY = lineEndY;

      // 범주의 위치가 다른 범주와 겹치는지 확인
      let overlaps = true;
      while (overlaps) {
        overlaps = false;
        for (let y of categoriesY) {
          if (Math.abs(y - labelY) &amp;lt; 20) {  // 20은 글자 크기에 따라 조정 가능
            labelY -= 20;     // 위로 20만큼 이동
            overlaps = true;  // 겹치는 것을 발견하면 overlaps를 true로 설정
            break;
          }
        }
      }
      categoriesY.push(labelY);  // 조정된 Y 위치를 배열에 추가

      // x축 끝에 점선 추가
      svg
        .append(&quot;line&quot;)
        .attr(&quot;x1&quot;, lineEndX)
        .attr(&quot;y1&quot;, lineEndY)  /* 그래프 선 끝 y축 높이 */
        .attr(&quot;x2&quot;, lineEndY !== labelY ? width + 15 : width + 27)  // 꺾는 선이 있는 경우에는 좌표를 조정
        .attr(&quot;y2&quot;, lineEndY)
        .attr(&quot;stroke&quot;, lineColor)
        .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);
      
      // 꺾는 선이 필요한 경우
      if (lineEndY !== labelY) {
        svg
          .append(&quot;line&quot;)
          .attr(&quot;x1&quot;, width + 15)
          .attr(&quot;y1&quot;, lineEndY)
          .attr(&quot;x2&quot;, width + 15)
          .attr(&quot;y2&quot;, labelY)
          .attr(&quot;stroke&quot;, lineColor)
          .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);
        
        svg
          .append(&quot;line&quot;)
          .attr(&quot;x1&quot;, width + 15)
          .attr(&quot;y1&quot;, labelY)
          .attr(&quot;x2&quot;, width + 30)
          .attr(&quot;y2&quot;, labelY)
          .attr(&quot;stroke&quot;, lineColor)
          .attr(&quot;stroke-dasharray&quot;, &quot;5,5&quot;);
      }
      
      // 범주명 추가
      svg
        .append(&quot;text&quot;)
        .attr(&quot;x&quot;, width + 35)
        .attr(&quot;y&quot;, labelY + 5)
        .attr(&quot;fill&quot;, lineColor)
        .text(line.category);

      // 선 추가
      const path = svg
        .append(&quot;path&quot;)
        .attr(&quot;d&quot;, lineGenerator(line.points))
        .attr(&quot;stroke&quot;, lineColor)
        .attr(&quot;fill&quot;, &quot;none&quot;);
      
      // 툴팁 이벤트 추가
      path
        .on(&quot;mouseover&quot;, (event, d) =&amp;gt; {
          tooltip
            .style(&quot;left&quot;, `${event.pageX + 10}px`)
            .style(&quot;top&quot;, `${event.pageY - 10}px`)
            .style(&quot;display&quot;, &quot;inline-block&quot;)
            .html(`${line.category}`);
        })
        .on(&quot;mouseout&quot;, () =&amp;gt; {
          tooltip.style(&quot;display&quot;, &quot;none&quot;);
        });
    });
  }, []);
  
  return (
    &amp;lt;&amp;gt;
      &amp;lt;svg ref={svgRef} width={900} height={400}&amp;gt;&amp;lt;/svg&amp;gt;
      &amp;lt;div
        ref={tooltipRef}
        style={{
          position: &quot;absolute&quot;,
          display: &quot;none&quot;,
          background: &quot;#f9f9f9&quot;,
          border: &quot;1px solid #ccc&quot;,
          padding: &quot;10px&quot;,
          borderRadius: &quot;10px&quot;,
          pointerEvents: &quot;none&quot;
        }}
      &amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;/&amp;gt;
  );
};

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/JavaScript</category>
      <author>미주민</author>
      <guid isPermaLink="true">https://valueengine.tistory.com/82</guid>
      <comments>https://valueengine.tistory.com/82#entry82comment</comments>
      <pubDate>Sat, 19 Aug 2023 17:45:37 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 주차 요금 계산</title>
      <link>https://valueengine.tistory.com/80</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Programmers : 주차 요금 계산&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;programmers.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o7MLd/btsnn6RXNk1/8iyb5yzAeVlPU5QKgfayX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o7MLd/btsnn6RXNk1/8iyb5yzAeVlPU5QKgfayX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o7MLd/btsnn6RXNk1/8iyb5yzAeVlPU5QKgfayX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo7MLd%2Fbtsnn6RXNk1%2F8iyb5yzAeVlPU5QKgfayX0%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;604&quot; height=&quot;128&quot; data-filename=&quot;programmers.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot; data-token-index=&quot;0&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;문제 링크&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92341&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/92341&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1689193803608&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;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92341&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/buQqXA/hyTiv6FCiQ/TEKiZWq0kI1v6cjWDq2ii0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/HnKyQ/hyTisB85WN/LVVVKTGrlTRJV10qnkIeRk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92341&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92341&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/buQqXA/hyTiv6FCiQ/TEKiZWq0kI1v6cjWDq2ii0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/HnKyQ/hyTisB85WN/LVVVKTGrlTRJV10qnkIeRk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;span style=&quot;background-color: #000000; color: #ffffff; text-align: start;&quot;&gt;&lt;b&gt;&amp;lt;/&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이 글은 코딩테스트 대비와 알고리즘 공부를 위해 문제를 풀고&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;학습한 내용을 기록한 것입니다. 틀린 부분이나 추가해야 할 부분이 있다면 언제든 댓글로 남겨주세요&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;❗️&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 문제는&amp;nbsp;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt; 객체&lt;/b&gt; &lt;/span&gt;를 활용해 차량번호와 시간, 차량번호와 요금을 연결지으면 되는 구현 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고려해줘야 할 것이 많지만, 객체에 대해 이해하고 있다면 충분히 풀 수 있는 문제였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;주차장의 입/출차 내역과 요금표가 주어졌을 때, 차량별 주차 요금을 계산하려고 한다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;요금 (정수 배열 fees)&lt;br /&gt;&lt;br /&gt;- [기본 시간, 기본 요금, 단위 시간, 단위 요금]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;기본 시간&lt;/b&gt; 이하일 때, &lt;b&gt;기본 요금&lt;/b&gt;이 청구된다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;b&gt;기본 시간 초과분&lt;/b&gt;에 대해서는 &lt;b&gt;단위 시간&lt;/b&gt;마다 &lt;b&gt;단위 요금&lt;/b&gt;이 청구된다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 단위 시간으로 나누어 떨어지지 않으면 &lt;b&gt;올림&lt;/b&gt;한다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;입/출차 내역 (문자열 배열 records)&lt;br /&gt;&lt;br /&gt;- &quot;시각 차량번호 내역&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 입차 후 출차된 내역이 없다면, &lt;b&gt;23:59&lt;/b&gt;에 출차된 것으로 간주한다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 차량번호는 숫자 4개 번호&lt;br /&gt;&lt;br /&gt;- 내역은 IN 또는 OUT&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차량 번호가 작은 순으로 주차 요금을 정수 배열에 담아 출력해주면 된다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;659&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNIrh3/btsnoDhBeOh/U18NnuHwgBaDQ85tJ9x8Yk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNIrh3/btsnoDhBeOh/U18NnuHwgBaDQ85tJ9x8Yk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNIrh3/btsnoDhBeOh/U18NnuHwgBaDQ85tJ9x8Yk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNIrh3%2FbtsnoDhBeOh%2FU18NnuHwgBaDQ85tJ9x8Yk%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;729&quot; height=&quot;659&quot; data-filename=&quot;problem1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;659&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem2.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;583&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDHYE7/btsnoIQz9Kd/HNCKRSQKTlSUVgetyjhEn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDHYE7/btsnoIQz9Kd/HNCKRSQKTlSUVgetyjhEn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDHYE7/btsnoIQz9Kd/HNCKRSQKTlSUVgetyjhEn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDHYE7%2FbtsnoIQz9Kd%2FHNCKRSQKTlSUVgetyjhEn1%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;729&quot; height=&quot;583&quot; data-filename=&quot;problem2.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;583&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem3.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WUYX4/btsnoHD9TKk/S7IkCnC7ByZMDjyPFCDslK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WUYX4/btsnoHD9TKk/S7IkCnC7ByZMDjyPFCDslK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WUYX4/btsnoHD9TKk/S7IkCnC7ByZMDjyPFCDslK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWUYX4%2FbtsnoHD9TKk%2FS7IkCnC7ByZMDjyPFCDslK%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;729&quot; height=&quot;341&quot; data-filename=&quot;problem3.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;341&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem4.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/swhOU/btsnojctk0s/qjUh3MQdrg7ChZkJtD7ixK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/swhOU/btsnojctk0s/qjUh3MQdrg7ChZkJtD7ixK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/swhOU/btsnojctk0s/qjUh3MQdrg7ChZkJtD7ixK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FswhOU%2Fbtsnojctk0s%2FqjUh3MQdrg7ChZkJtD7ixK%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;729&quot; height=&quot;544&quot; data-filename=&quot;problem4.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;544&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;입출력 예시&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2번째 예시를 정리하면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차량 3961 = 16시 입차 - 18시 출차, 23시 58분 입차 / 차량 0202 = 16시 입차 - 18시 출차&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;차량 0202는 120분, 차량 3961은 121분 주차했으므로, 0202는 기본 요금으로 0원이고 3961은 1분 더 주차했으므로 올림해서 총 요금은 591원이다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;3번째 예시에서 차량 1234는 0시 0분에 들어왔지만, 나간 시각이 없기에 23시 59분에 나간 것으로 간주되어 요금은 (1439분 - 1분) / 1분 * 10원 = 14841원이다.&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;input1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z9IuD/btsnn8vuCgK/zIxkStltzXbpGw1nVYHlx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z9IuD/btsnn8vuCgK/zIxkStltzXbpGw1nVYHlx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z9IuD/btsnn8vuCgK/zIxkStltzXbpGw1nVYHlx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ9IuD%2Fbtsnn8vuCgK%2FzIxkStltzXbpGw1nVYHlx1%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;729&quot; height=&quot;357&quot; data-filename=&quot;input1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;input2.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;803&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RgPTe/btsno6cMQEY/0T6MqFv9XbidYgY9cijkV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RgPTe/btsno6cMQEY/0T6MqFv9XbidYgY9cijkV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RgPTe/btsno6cMQEY/0T6MqFv9XbidYgY9cijkV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRgPTe%2Fbtsno6cMQEY%2F0T6MqFv9XbidYgY9cijkV0%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;729&quot; height=&quot;803&quot; data-filename=&quot;input2.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;803&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;input3.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;521&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMhdtN/btsnnTr3f5P/AsWEnb7ymuGXnD3XuKOvP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMhdtN/btsnnTr3f5P/AsWEnb7ymuGXnD3XuKOvP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMhdtN/btsnnTr3f5P/AsWEnb7ymuGXnD3XuKOvP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMhdtN%2FbtsnnTr3f5P%2FAsWEnb7ymuGXnD3XuKOvP0%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;729&quot; height=&quot;521&quot; data-filename=&quot;input3.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;521&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;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8165051221932976&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;풀이1 : 객체&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;요금표를 baseT(기본 시간), baseF(기본 요금), unitT(단위 시간), unitF(단위 요금)으로 구조분해할당 해준다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;records를 clock(시각), num(차량 번호), record(내역)으로 할당해준다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 시각(clock)도 분해하여 분(min) 단위로 변환해준다(time)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;입/출차 내역&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 차량이 들어왔으면, carIn에 num과 time을 쌍으로 넣어준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 차량이 나왔을 때, 이전에 누적된 시간이 carOut에 있다면 거기에다가 더해준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 차량이 나왔을 때, 이전에 누적된 시간이 없다면 주차한 시간을 carOut에 넣어주고, carIn에서는 제거해준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;주차는 했지만 출차하지 않은 차량&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 23시 59분에 출차한 것으로 간주해 주차 시간을 carOut에 추가해준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[차량번호, 주차 시간] 형식으로 이차원 배열로 바꾼 뒤, 차량 번호를 기준으로 오름차순으로 정렬해준다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;요금 계산&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 기본 시간보다 짧게 주차했으면 기본 요금을, 그것보다 길게 주차했으면 초과분을 계산해 주차 요금을 정산해준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 기본 시간으로 나눴을 때, 나머지는 올림해준다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1689200456860&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(fees, records) {
    const answer = [];
    const carIn = {};
    let carOut = {};
    const [baseT, baseF, unitT, unitF] = fees;
    
    // 시간 계산
    records.map((item) =&amp;gt; {
        const [clock, num, record] = item.split(' ');
        const [hour, min] = clock.split(':');
        const time = parseInt(hour) * 60 + parseInt(min);
        
        if (record === 'IN') {
            carIn[num] = time;
        } else {
            carOut.hasOwnProperty(num)
                ? carOut[num] = carOut[num] + time - carIn[num]
                : carOut[num] = time - carIn[num];
            delete carIn[num];
        }
    });
    // 오늘 출차하지 않은 차량
    for (const [num, time] of Object.entries(carIn)) {
        carOut.hasOwnProperty(num)
            ? carOut[num] = carOut[num] + 1439 - time
            : carOut[num] = 1439 - time;
        delete carIn[num];
    }
    // 차량번호 오름차순 정렬
    carOut = Object.entries(carOut).sort((a,b) =&amp;gt; a[0] - b[0]);
    
    // 요금 계산
    carOut.map((item) =&amp;gt; {
        const time = item[1];
        answer.push(
            time &amp;lt;= baseT
                ? baseF
                : baseF + Math.ceil((time - baseT) / unitT) * unitF
        );
    })
    return answer;
}&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;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&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;test1.png&quot; data-origin-width=&quot;937&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/M0iLL/btsnrtdRiW3/Qd39vuNnGQkxi6Vt5FVSjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/M0iLL/btsnrtdRiW3/Qd39vuNnGQkxi6Vt5FVSjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/M0iLL/btsnrtdRiW3/Qd39vuNnGQkxi6Vt5FVSjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FM0iLL%2FbtsnrtdRiW3%2FQd39vuNnGQkxi6Vt5FVSjK%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;937&quot; height=&quot;439&quot; data-filename=&quot;test1.png&quot; data-origin-width=&quot;937&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;result1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;549&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5bca5/btsnnUxJCpX/iLUC5kHH7KcyLrrCI7ftz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5bca5/btsnnUxJCpX/iLUC5kHH7KcyLrrCI7ftz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5bca5/btsnnUxJCpX/iLUC5kHH7KcyLrrCI7ftz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5bca5%2FbtsnnUxJCpX%2FiLUC5kHH7KcyLrrCI7ftz0%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;729&quot; height=&quot;549&quot; data-filename=&quot;result1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;549&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;</description>
      <category>Problem Solving/Programmers</category>
      <category>entries</category>
      <category>hasOwnProperty</category>
      <category>JS</category>
      <category>node.js</category>
      <category>object</category>
      <category>객체</category>
      <category>자바스크립트</category>
      <category>주차 요금 계산</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>미주민</author>
      <guid isPermaLink="true">https://valueengine.tistory.com/80</guid>
      <comments>https://valueengine.tistory.com/80#entry80comment</comments>
      <pubDate>Thu, 13 Jul 2023 06:01:33 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 오픈채팅방</title>
      <link>https://valueengine.tistory.com/79</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Programmers : 오픈채팅방&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;programmers.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oLLVQ/btsnpGdOXNV/qhIu7jGKJuNhTqRPaiALGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oLLVQ/btsnpGdOXNV/qhIu7jGKJuNhTqRPaiALGk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oLLVQ/btsnpGdOXNV/qhIu7jGKJuNhTqRPaiALGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoLLVQ%2FbtsnpGdOXNV%2FqhIu7jGKJuNhTqRPaiALGk%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;604&quot; height=&quot;128&quot; data-filename=&quot;programmers.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot; data-token-index=&quot;0&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;문제 링크&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42888&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42888&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1689178022575&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;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42888&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hdMQN/hyTizHXwFF/O5h9LfDX7IiMrFAKm1Dg70/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bA6Op5/hyTix4tmSD/kRYkVv8IiGdN1QZIAfU2C1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42888&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42888&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hdMQN/hyTizHXwFF/O5h9LfDX7IiMrFAKm1Dg70/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bA6Op5/hyTix4tmSD/kRYkVv8IiGdN1QZIAfU2C1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;span style=&quot;background-color: #000000; color: #ffffff; text-align: start;&quot;&gt;&lt;b&gt;&amp;lt;/&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이 글은 코딩테스트 대비와 알고리즘 공부를 위해 문제를 풀고&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;학습한 내용을 기록한 것입니다. 틀린 부분이나 추가해야 할 부분이 있다면 언제든 댓글로 남겨주세요&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;❗️&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;유저 아이디와 닉네임이 서로 한 쌍이고, 유저 아이디를 활용해 닉네임을 변경할 수 있다는 것만 파악하면 쉽게 풀 수 있는 문제였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;오픈채팅방에서 닉네임을 바꾸는 방법은 2가지다. 닉네임을 변경하면 기존 메시지의 닉네임도 변경된다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 채팅방을 나간 후, 새로운 닉네임으로 다시 들어온다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 채팅방에서 닉네임을 변경한다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;중복된 닉네임을 사용할 수 있다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 그렇기에 모든 유저는 [유저 아이디]로 구분한다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;입장, 퇴장, 변경에 대한 기록 record 메시지는 다음과 같이 주어진다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 입장 : &quot;Enter [유저 아이디] [닉네임]&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 퇴장 : &quot;Leave [유저 아이디]&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 변경 : &quot;Change [유저 아이디] [닉네임]&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;입장, 퇴장시 다음과 같은 메시지가 출력되며, 최종적으로 보게 될 메시지를 배열 형태로 출력해주면 된다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 입장 : &quot;[닉네임]님이 들어왔습니다.&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 퇴장 : &quot;[닉네임]님이 나갔습니다.&quot;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3HZ5n/btsnqTDKAzb/Krn7HFaYs69L7G4tAf02sK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3HZ5n/btsnqTDKAzb/Krn7HFaYs69L7G4tAf02sK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3HZ5n/btsnqTDKAzb/Krn7HFaYs69L7G4tAf02sK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3HZ5n%2FbtsnqTDKAzb%2FKrn7HFaYs69L7G4tAf02sK%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;729&quot; height=&quot;724&quot; data-filename=&quot;problem1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem2.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;502&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs35ZK/btsnqe9bJU7/xev6bombRwKb1OWPeXWYk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs35ZK/btsnqe9bJU7/xev6bombRwKb1OWPeXWYk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs35ZK/btsnqe9bJU7/xev6bombRwKb1OWPeXWYk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs35ZK%2Fbtsnqe9bJU7%2Fxev6bombRwKb1OWPeXWYk1%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;729&quot; height=&quot;502&quot; data-filename=&quot;problem2.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;502&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem3.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Akx6F/btsnkL8CYHr/vgnKKNr0U1rkC3PXg0HmF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Akx6F/btsnkL8CYHr/vgnKKNr0U1rkC3PXg0HmF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Akx6F/btsnkL8CYHr/vgnKKNr0U1rkC3PXg0HmF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAkx6F%2FbtsnkL8CYHr%2FvgnKKNr0U1rkC3PXg0HmF0%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;729&quot; height=&quot;439&quot; data-filename=&quot;problem3.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;439&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;입출력 예시&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처음에는 Muzi(uid1234)가 들어왔고, 그 다음으로 Prodo(uid4567)가 들어왔다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 Muzi(uid1234)가 퇴장하고, Prodo라는 닉네임으로 바꿔서 uid1234가 들어왔다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;마지막으로, uid4567이 닉네임을 Ryan으로 변경했다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최종적으로, uid1234의 닉네임은 Prodo이고, uid4567의 닉네임은 Ryan이다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&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;input.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eeAFBc/btsnoIQyIX2/cJZMzLjnuL2CTvpok3klR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eeAFBc/btsnoIQyIX2/cJZMzLjnuL2CTvpok3klR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eeAFBc/btsnoIQyIX2/cJZMzLjnuL2CTvpok3klR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeeAFBc%2FbtsnoIQyIX2%2FcJZMzLjnuL2CTvpok3klR1%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;729&quot; height=&quot;274&quot; data-filename=&quot;input.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;274&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;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8165051221932976&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;풀이1 : 객체&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;유저의 닉네임을 변경하기 위해 객체를 활용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;유저 아이디를 객체의 key값으로, 닉네임을 value값으로 설정했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;유저 정보를 받아와 명령어(command), 유저 아이디(uid), 닉네임(nickname)으로 구조분해할당을 해준다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;명령어&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1) 입장(Enter) : 유저정보(userInfo)에 uid와 nickname을 key와 value로 넣어준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp; - 입장 메시지 &quot;uid님이 들어왔습니다&quot;를 배열 ans에 넣어준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2) 변경(Change) : 해당 uid의 value값을 새로운 닉네임으로 바꿔준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3) 퇴장(Leave) : &quot;uid님이 나갔습니다&quot;를 배열 ans에 넣어준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;현재까지는 아이디로 입장/퇴장 메시지가 저장된 상태이다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 각 유저 아이디를 최종 닉네임으로 변경해주고, 최종 메세지 배열을 출력해준다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1689182279582&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(record) {
    const userInfo = {};
    const ans = [];
    
    // 유저 정보
    record.map((item) =&amp;gt; {
        const [command, uid, nickname] = item.split(' ');
        
        if (command === 'Enter') {
            userInfo[uid] = nickname;
            ans.push(`${uid}님이 들어왔습니다.`);
        } else if (command === 'Change') {
            userInfo[uid] = nickname;
        } else if (command === 'Leave') {
            ans.push(`${uid}님이 나갔습니다.`);
        }
    });
    // 입장, 퇴장 기록
    for (let i=0; i &amp;lt; ans.length; i++) {
        let uid = ans[i].split('님')[0];
        ans[i] = ans[i].replace(uid, userInfo[uid]);
    }
    return ans;
}&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;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&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;test1.png&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bobWTN/btsno552gql/sqxXiH8dWrmdzAWa6MsVc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bobWTN/btsno552gql/sqxXiH8dWrmdzAWa6MsVc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bobWTN/btsno552gql/sqxXiH8dWrmdzAWa6MsVc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbobWTN%2Fbtsno552gql%2FsqxXiH8dWrmdzAWa6MsVc0%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;1084&quot; height=&quot;274&quot; data-filename=&quot;test1.png&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;274&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;result1_1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwcNtg/btsnqftvnHQ/kBp3hsOf9Gp8RXublUouUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwcNtg/btsnqftvnHQ/kBp3hsOf9Gp8RXublUouUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwcNtg/btsnqftvnHQ/kBp3hsOf9Gp8RXublUouUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwcNtg%2FbtsnqftvnHQ%2FkBp3hsOf9Gp8RXublUouUk%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;729&quot; height=&quot;726&quot; data-filename=&quot;result1_1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;result1_2.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IALvy/btsnru4RZHj/oPnzHhR0gMUB68Yx8TUtUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IALvy/btsnru4RZHj/oPnzHhR0gMUB68Yx8TUtUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IALvy/btsnru4RZHj/oPnzHhR0gMUB68Yx8TUtUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIALvy%2Fbtsnru4RZHj%2FoPnzHhR0gMUB68Yx8TUtUK%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;729&quot; height=&quot;195&quot; data-filename=&quot;result1_2.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;195&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;</description>
      <category>Problem Solving/Programmers</category>
      <category>JS</category>
      <category>map</category>
      <category>node.js</category>
      <category>Replace</category>
      <category>객체</category>
      <category>알고리즘</category>
      <category>오픈채팅방</category>
      <category>자바스크립트</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>미주민</author>
      <guid isPermaLink="true">https://valueengine.tistory.com/79</guid>
      <comments>https://valueengine.tistory.com/79#entry79comment</comments>
      <pubDate>Thu, 13 Jul 2023 01:07:57 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] n진수 게임</title>
      <link>https://valueengine.tistory.com/78</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Programmers : n진수 게임&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;programmers.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lSqLk/btsnoJIdT10/kKuukIsjlR8nEMm4FKLV8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lSqLk/btsnoJIdT10/kKuukIsjlR8nEMm4FKLV8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lSqLk/btsnoJIdT10/kKuukIsjlR8nEMm4FKLV8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlSqLk%2FbtsnoJIdT10%2FkKuukIsjlR8nEMm4FKLV8k%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;604&quot; height=&quot;128&quot; data-filename=&quot;programmers.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot; data-token-index=&quot;0&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;문제 링크&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17687&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/17687&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1689150863825&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;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17687&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fL2u3/hyTiCjZ9iX/VO0kGkX5CkqkgXcec6mHP0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/PNJMS/hyTitAzIKk/HQM3UFzSKs164m23s8lXnk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17687&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17687&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fL2u3/hyTiCjZ9iX/VO0kGkX5CkqkgXcec6mHP0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/PNJMS/hyTitAzIKk/HQM3UFzSKs164m23s8lXnk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;span style=&quot;background-color: #000000; color: #ffffff; text-align: start;&quot;&gt;&lt;b&gt;&amp;lt;/&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt; 이 글은 코딩테스트 대비와 알고리즘 공부를 위해 문제를 풀고&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt; 학습한 내용을 기록한 것입니다. 틀린 부분이나 추가해야 할 부분이 있다면 언제든 댓글로 남겨주세요&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;❗️&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처음 문제를 읽었을 때, &quot;미리 구할 숫자의 개수 t&quot;가 무엇을 의미하는지 이해하기 어려웠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;출력 형식의 설명을 보면, m명이 돌아가면서 각자 1개씩 숫자를 말하는데, 튜브가 말해야 하는 총 숫자 개수가 t를 의미한다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;이 문제는&amp;nbsp;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt; 진법 변환&lt;/b&gt; &lt;/span&gt;과&amp;nbsp;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt; 반복문&lt;/b&gt; &lt;/span&gt;에 대해 이해하고 있다면 충분히 풀 수 있는 문제였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;문제 설명&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;m명&lt;/b&gt;이 0부터 숫자를 하나씩 말하는 게임을 하고 있다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 두 자리 이상의 숫자는 하나씩 끊어서 말한다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 예를 들어, 10은 11번째 사람이 1을 말하고, 12번째 사람이 0을 말한다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;숫자는 2진법에서 16진법까지 &lt;b&gt;n진법&lt;/b&gt;으로 주어진다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 11~16진법에서 10~15는 알파벳으로 출력되는데, 대문자 알파벳으로 출력해준다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;m명 중 튜브의 순서는 &lt;b&gt;p번째&lt;/b&gt;이며, 튜브는 총 &lt;b&gt;t개&lt;/b&gt;의 숫자를 말해야 한다.&lt;br /&gt;&lt;br /&gt;- 튜브가 말해야 하는 숫자들을 하나의 문자열로 출력해야 한다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZfxJ5/btsnqeAQaE7/dkrj8fckCHRtHQ1ljC7BE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZfxJ5/btsnqeAQaE7/dkrj8fckCHRtHQ1ljC7BE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZfxJ5/btsnqeAQaE7/dkrj8fckCHRtHQ1ljC7BE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZfxJ5%2FbtsnqeAQaE7%2Fdkrj8fckCHRtHQ1ljC7BE0%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;729&quot; height=&quot;590&quot; data-filename=&quot;problem.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem2.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vw1xU/btsnoDVSDNv/YpW50eHEjxs0nrFlwhk6Q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vw1xU/btsnoDVSDNv/YpW50eHEjxs0nrFlwhk6Q1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vw1xU/btsnoDVSDNv/YpW50eHEjxs0nrFlwhk6Q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvw1xU%2FbtsnoDVSDNv%2FYpW50eHEjxs0nrFlwhk6Q1%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;729&quot; height=&quot;354&quot; data-filename=&quot;problem2.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;354&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;입출력 예시&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;첫 번째 예시를 살펴보면, 총 2명이서 2진법의 숫자에서 숫자 하나씩 말한다. 이때 튜브의 순서는 1번째이며, 튜브가 총 4개의 숫자를 말해야 하므로, 2명이서 4번 말하면 8개 이상의 숫자가 주어져야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;0, 1, 10, 11, 100까지 말하면 8개 이상의 숫자가 충족된다. 숫자 하나씩 말하므로 &lt;b&gt;0&lt;/b&gt;, 1, &lt;b&gt;1&lt;/b&gt;, 0, &lt;b&gt;1&lt;/b&gt;, 1, &lt;b&gt;1&lt;/b&gt;, 0, 0 순으로 말하게 된다. 여기서 튜브가 언급하는 4개의 숫자는 0, 1, 1, 1이므로, &quot;0111&quot;을 출력해줘야 한다.&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;input.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwrjrn/btsnkLAvREH/KHl0OEDOOPKAdPSVZHsy5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwrjrn/btsnkLAvREH/KHl0OEDOOPKAdPSVZHsy5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwrjrn/btsnkLAvREH/KHl0OEDOOPKAdPSVZHsy5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdwrjrn%2FbtsnkLAvREH%2FKHl0OEDOOPKAdPSVZHsy5k%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;729&quot; height=&quot;187&quot; data-filename=&quot;input.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;187&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;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8165051221932976&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;풀이1&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;n진법 n, 튜브가 말해야 하는 숫자 개수 t, 총 인원 m, 튜브의 순서 p가 주어진다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;튜브가 t번 숫자를 언급해야 하므로, m명이 t번 언급해줘야 한다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 따라서 숫자 게임에서 말해야 할 수들 num의 길이는 m x t보다 작아야 한다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 11진법 이상에서 10~15에 해당하는 수들은 알파벳으로 나오므로, 대문자로 바꾸어준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;num를 배열로 바꾸고, p번째 말하는 수를 찾아준다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- m명 중 p번째로 말하므로, 인덱스를 m으로 나눴을 때 나머지가 p인 경우가 튜브의 차례이다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 다만, 인덱스는 0번째부터 시작하므로 p-1로 해준다&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;총 t개의 숫자만 찾아줘야 하므로, ans의 길이가 t보다 작은 경우에만 그 수를 ans에 더해준다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1689176685246&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(n, t, m, p) {
    let num = '';
    let ans = '';

    for (let i = 0; num.length &amp;lt; m * t; i++) {
        num += i.toString(n).toUpperCase();
    }
    num.split('').map((item, idx) =&amp;gt; {
        if (idx % m  === (p-1)) {
            if (ans.length &amp;lt; t) {
                ans += item;
            }
        }
    });
    return ans;
}&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;&lt;span style=&quot;color: #000000;&quot;&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;test1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VVUrJ/btsnsdWfTiP/Dak8Cc78LDYNzSwv5FeOm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VVUrJ/btsnsdWfTiP/Dak8Cc78LDYNzSwv5FeOm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VVUrJ/btsnsdWfTiP/Dak8Cc78LDYNzSwv5FeOm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVVUrJ%2FbtsnsdWfTiP%2FDak8Cc78LDYNzSwv5FeOm1%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;729&quot; height=&quot;396&quot; data-filename=&quot;test1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;result1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;706&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dYNFVT/btsnqvXeIs7/DgRckKqP5KYkxjDiYlMrk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dYNFVT/btsnqvXeIs7/DgRckKqP5KYkxjDiYlMrk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dYNFVT/btsnqvXeIs7/DgRckKqP5KYkxjDiYlMrk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdYNFVT%2FbtsnqvXeIs7%2FDgRckKqP5KYkxjDiYlMrk0%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;729&quot; height=&quot;706&quot; data-filename=&quot;result1.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;706&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;</description>
      <category>Problem Solving/Programmers</category>
      <category>JS</category>
      <category>node.js</category>
      <category>n진수 게임</category>
      <category>programmers</category>
      <category>알고리즘</category>
      <category>자바스크립트</category>
      <category>진법변환</category>
      <category>코딩테스트</category>
      <category>코테</category>
      <category>프로그래머스</category>
      <author>미주민</author>
      <guid isPermaLink="true">https://valueengine.tistory.com/78</guid>
      <comments>https://valueengine.tistory.com/78#entry78comment</comments>
      <pubDate>Wed, 12 Jul 2023 17:34:59 +0900</pubDate>
    </item>
    <item>
      <title>[React/기술면접] Hook (2)</title>
      <link>https://valueengine.tistory.com/77</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;React Hooks&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;React.jpeg&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;665&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by2fED/btsmRsulku1/GKm5l1WmKg1cMTfvDBep11/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by2fED/btsmRsulku1/GKm5l1WmKg1cMTfvDBep11/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by2fED/btsmRsulku1/GKm5l1WmKg1cMTfvDBep11/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby2fED%2FbtsmRsulku1%2FGKm5l1WmKg1cMTfvDBep11%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;500&quot; height=&quot;277&quot; data-filename=&quot;React.jpeg&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;665&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: #000000;&quot;&gt;이제 더 다양한 Hook에 대해 살펴볼 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아직 Hook에 대해 익숙하지 않다면 아래 글을 먼저 읽고 오길 바란다.&lt;/span&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;a href=&quot;https://valueengine.tistory.com/76&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://valueengine.tistory.com/76&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1688937708856&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;[React/기술면접] Hook (1)&quot; data-og-description=&quot;React Hooks * 기술면접 질문은 맨 아래에 적혀 있습니다 1. Hook의 등장 배경 컴포넌트에는 클래스형 컴포넌트와 함수형 컴포넌트가 있다. 클래스형 컴포넌트에서는 constructor(생성자)에서 state를 정&quot; data-og-host=&quot;valueengine.tistory.com&quot; data-og-source-url=&quot;https://valueengine.tistory.com/76&quot; data-og-url=&quot;https://valueengine.tistory.com/76&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gQJWq/hyTfH0RNcy/GWw53Ov9FCsqsqmpOlUKAk/img.jpg?width=800&amp;amp;height=443&amp;amp;face=178_263_254_339,https://scrap.kakaocdn.net/dn/pH62K/hyTgTFC57L/lgkDUFDyXL5r63PkhfwOy0/img.jpg?width=800&amp;amp;height=443&amp;amp;face=178_263_254_339,https://scrap.kakaocdn.net/dn/bUFRyk/hyTfoAyU0I/oKBRBFWwaAMxKysG3SSAQk/img.jpg?width=1200&amp;amp;height=665&amp;amp;face=0_0_1200_665&quot;&gt;&lt;a href=&quot;https://valueengine.tistory.com/76&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://valueengine.tistory.com/76&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gQJWq/hyTfH0RNcy/GWw53Ov9FCsqsqmpOlUKAk/img.jpg?width=800&amp;amp;height=443&amp;amp;face=178_263_254_339,https://scrap.kakaocdn.net/dn/pH62K/hyTgTFC57L/lgkDUFDyXL5r63PkhfwOy0/img.jpg?width=800&amp;amp;height=443&amp;amp;face=178_263_254_339,https://scrap.kakaocdn.net/dn/bUFRyk/hyTfoAyU0I/oKBRBFWwaAMxKysG3SSAQk/img.jpg?width=1200&amp;amp;height=665&amp;amp;face=0_0_1200_665');&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;[React/기술면접] Hook (1)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;React Hooks * 기술면접 질문은 맨 아래에 적혀 있습니다 1. Hook의 등장 배경 컴포넌트에는 클래스형 컴포넌트와 함수형 컴포넌트가 있다. 클래스형 컴포넌트에서는 constructor(생성자)에서 state를 정&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;valueengine.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;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;4. useReducer&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;useReducer&lt;/b&gt;는&amp;nbsp;여러 개의 하위 값을 포함하는 복잡한 state를 다뤄야 할 때 useState 대신 사용하는 Hook이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;여기서 알아둬야 할 개념에는 Reducer, Dispatch, Action이 있다. 만약 은행의 거래 내역이 state일 때, 출금(action)을 은행(reducer)에 요구(dispatch)하면 은행은 거래 내역 state를 업데이트 해준다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #ffc9af;&quot;&gt;&lt;b&gt;&amp;nbsp;4-1. useReducer의 구성&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;이것을 컴포넌트의 관점에서 정리하면 다음과 같다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1) useReducer 함수&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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;useReducer 함수는 reducer 함수가 반환한 값으로 state를 갱신하는 역할을 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dispatch : 컴포넌트 내에서 state의 업데이트를 발생시키기 위한 함수&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;reducer : 컴포넌트 외부에서 state를 업데이트하는 로직을 담당하는 함수&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;initialState : 초기 state&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;init : 초기 함수&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1688940411890&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useReducer } from 'react';

const [state, dispatch 함수] = useReducer(reducer 함수, initialState, init)&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;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2) action&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;action은 업데이트를 위한 정보를 가지고 있는 것을 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dispatch의 인자가 되며, reducer 함수의 두 번째 인자에 할당된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;action의 형태는 따로 정해져 있지 않으나, 아래의 코드처럼 주로 type이라는 값을 지닌 객체 형태로 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688939384239&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dispatch({ type: &quot;document&quot; })&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;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3) dispatch 함수&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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;dispatch 함수는 reducer 함수를 실행시킨다. 이때 dispatch의 인자인 action이 reducer 함수의 두 번째 인자에 할당되며, 컴포넌트 내에서 state의 업데이트를 발생시키기 위해 사용된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688939748942&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Counter() {
  const [number, dispatch] = useReducer(reducer, { count: 0 });

  return (
    &amp;lt;&amp;gt;
      {/* 현재 카운트 값은 state인 number 객체의 count로부터 읽어옴 */}
      &amp;lt;h1&amp;gt;Count: {number.count}&amp;lt;/h1&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; dispatch({ type: &quot;decrement&quot; })}&amp;gt;-&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; dispatch({ type: &quot;increment&quot; })}&amp;gt;+&amp;lt;/button&amp;gt;
    &amp;lt;/&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;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;4) reducer 함수&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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;reducer 함수는 컴포넌트 외부에서 state를 업데이트 하는 로직을 담당한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;reducer 함수는 현재의 state와 action을 인자로 받으며, action의 값에 근거하여 기존의 state를 대체할 새로운 state를 반환해준다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기서 핵심은 &lt;b&gt;기존의 state를 새로운 state로 대체(replace)한다는 것&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688941439990&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function reducer(state, action) {
  switch (action.type) {
    // action의 type이 &quot;decrement&quot;일 때, 현재 state에서 1을 뺀 값을 반환함
    case &quot;decrement&quot;:
      return state - 1;
    // action의 type이 &quot;increment&quot;일 때, 현재 state에서 1을 더한 값을 반환함
    case &quot;increment&quot;:
      return state + 1;
    // 정의되지 않은 action type이 넘어왔을 때는 에러를 발생시킴
    default:
      throw new Error(&quot;Unsupported action type:&quot;, action.type);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #ffc9af;&quot;&gt;&lt;b&gt;&amp;nbsp;4-2. useReducer의 장점&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;useReducer는 한 컴포넌트 내에서 &quot;state를 업데이트 하는 로직&quot;을 그 컴포넌트로부터 분리시키는 것을 가능하게 해준다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;useState를 사용하면 아래처럼 컴포넌트 내부에서 state를 업데이트 해준다.&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;useState.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;647&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWQEUk/btsmQfbauYx/DOwTVwhSQxuuNFSANviJgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWQEUk/btsmQfbauYx/DOwTVwhSQxuuNFSANviJgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWQEUk/btsmQfbauYx/DOwTVwhSQxuuNFSANviJgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWQEUk%2FbtsmQfbauYx%2FDOwTVwhSQxuuNFSANviJgk%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;700&quot; height=&quot;453&quot; data-filename=&quot;useState.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;647&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;&lt;span style=&quot;color: #000000;&quot;&gt;그러나 useReducer는 state를 업데이트 하는 로직을 외부로 분리시키는 것이 가능하기에, 이 로직을 별도의 파일에서 작성해 가져오는 것도 가능하다. 이로 인해 컴포넌트의 최적화를 이룰 수 있다.&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;useReducer.png&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;685&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bG5qS7/btsmYMejuOd/c7hKoZiHtKuOw4nya6cFjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bG5qS7/btsmYMejuOd/c7hKoZiHtKuOw4nya6cFjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bG5qS7/btsmYMejuOd/c7hKoZiHtKuOw4nya6cFjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbG5qS7%2FbtsmYMejuOd%2Fc7hKoZiHtKuOw4nya6cFjK%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;700&quot; height=&quot;413&quot; data-filename=&quot;useReducer.png&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;685&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;5. useMemo&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;useMemo&lt;/b&gt;는 컴포넌트의 성능을 최적화하는 Hooks 중 하나로, 함수 컴포넌트 내부에서 발생하는 연산을 최적화할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기서 Memo는 &lt;b&gt;메모이제이션(Memoization)&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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;useMemo는 첫 번째 인자로 &lt;b&gt;콜백 함수&lt;/b&gt;를 받으며,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;이때 콜백 함수는 메모이제이션 해야 할 값을 리턴해주는 함수다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;두 번째 인자로&amp;nbsp;&lt;/span&gt;&lt;b&gt;의존성 배열(dependency array)&lt;/b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;을 받으며, 배열의 요소 값이 업데이트 될 때만 콜백 함수를 호출해 memoization 된 값을 업데이트해서 다시 memoization 해준다. 만약 빈 배열을 넘겨주면 맨 처음 컴포넌트가 마운트되었을 때만 값을 계산하고, 이후에는 항상 메모이제이션 된 값을 꺼내와서 사용한다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1688944042268&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useMemo } from 'react';

const value = useMemo(() =&amp;gt; {
  return calculate();
}, [item]);&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;&lt;span style=&quot;color: #000000;&quot;&gt;이렇게 좋아보이는 useMemo 역시 무분별하게 사용해서는 안 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;useMemo는 &lt;b&gt;값을 재활용하기 위해 따로 메모리를 소비해서 저장&lt;/b&gt;해둔다. 따라서 불필요한 값까지 모두 memoization 해버리면 오히려 성능이 악화될 수 있기 때문에 꼭 필요할 때만 적절히 사용해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;6. useCallback&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;useCallback&lt;/b&gt;는 함수를 메모이제이션 하기 위해 사용되는 Hook이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;첫 번째 인자로 메모이제이션 할 함수를 받으며, 두 번째 인자로 의존성 배열을 받는다. 이 배열 내에는 어떤 값이 바뀌었을 때 함수를 새로 생성해줘야 하는지 명시해줘야 한다.&amp;nbsp;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;만약 빈 배열을 넣어주면 컴포넌트가 렌더링될 때 만들어진 함수를 계속해서 재사용하게 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688952671098&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useCallback } from 'react';

const memoizedCallback = useCallback(함수, 배열);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;7. useRef&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;useRef&lt;/b&gt;는 저장공간(변수 관리), DOM 요소에 접근을 위해 사용되는 Hook이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1) 저장공간&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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;대표적인 저장공간인 State는 State가 변경될 때마다 리렌더링되면서 컴포넌트 내부 변수들이 모두 초기화된다. 그러나 Ref 내의 값은 아무리 바뀌어도 컴포넌트가 리렌더링되지 않는다. 즉, Ref를 사용하면 불필요한 렌더링을 막을 수 있으며, 컴포넌트가 아무리 렌더링되더라도 Ref 안에 저장된 값은 그대로 유지된다. 그래서 렌더링을 원치 않는 값을 다룰 때 유용하다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;State의 변화 -&amp;gt; 렌더링 -&amp;gt; 컴포넌트 내부 변수들 초기화&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Ref의 변화 -&amp;gt; No 렌더링 -&amp;gt; 변수들의 값이 유지됨&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;State의 변화 -&amp;gt; 렌더링 -&amp;gt; 그래도 Ref의 값은 유지됨&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;2) DOM 요소에 접근&lt;/span&gt;&lt;/span&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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;ref를 통해 DOM 요소에 직접 접근하는 것이 가능하다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;예를 들어, 클릭을 하지 않아도 로그인 input 창이 포커스되어 있어서 바로 id를 입력할 수 있도록 해주는 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;함수 컴포넌트에서 useRef를 부르면 ref object를 반환해준다. ref object는 { current: 초기값 }으로 이루어져 있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688973121931&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useRef } from 'react';

const ref = useRef(초기값);&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;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;ref에 대해 더 자세한 설명은 아래 링크를 참조하길 바란다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;&lt;a href=&quot;https://valueengine.tistory.com/71&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://valueengine.tistory.com/71&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1688972413957&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;[React/기술면접] ref란?&quot; data-og-description=&quot;ref란? * 기술면접 질문은 맨 아래에 적혀 있습니다 일반적으로 DOM 요소에 이름을 달 때 id를 사용한다. 리액트의 public/index.html 파일에서도 div 요소의 id로 root를 설정해 리액트 컴포넌트를 렌더링 &quot; data-og-host=&quot;valueengine.tistory.com&quot; data-og-source-url=&quot;https://valueengine.tistory.com/71&quot; data-og-url=&quot;https://valueengine.tistory.com/71&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/k7p7g/hyTgMNBya8/Z9WvEqL0QiFyeRbKJDV92K/img.jpg?width=800&amp;amp;height=443&amp;amp;face=178_263_254_339,https://scrap.kakaocdn.net/dn/Nde2M/hyTfDR4sM4/bkgvoKpQRhqkISv8pEMakk/img.jpg?width=800&amp;amp;height=443&amp;amp;face=178_263_254_339,https://scrap.kakaocdn.net/dn/MF3FY/hyTfGusi9u/aml3rLPSf0BdwxS8wqMoik/img.jpg?width=1200&amp;amp;height=665&amp;amp;face=0_0_1200_665&quot;&gt;&lt;a href=&quot;https://valueengine.tistory.com/71&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://valueengine.tistory.com/71&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/k7p7g/hyTgMNBya8/Z9WvEqL0QiFyeRbKJDV92K/img.jpg?width=800&amp;amp;height=443&amp;amp;face=178_263_254_339,https://scrap.kakaocdn.net/dn/Nde2M/hyTfDR4sM4/bkgvoKpQRhqkISv8pEMakk/img.jpg?width=800&amp;amp;height=443&amp;amp;face=178_263_254_339,https://scrap.kakaocdn.net/dn/MF3FY/hyTfGusi9u/aml3rLPSf0BdwxS8wqMoik/img.jpg?width=1200&amp;amp;height=665&amp;amp;face=0_0_1200_665');&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;[React/기술면접] ref란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;ref란? * 기술면접 질문은 맨 아래에 적혀 있습니다 일반적으로 DOM 요소에 이름을 달 때 id를 사용한다. 리액트의 public/index.html 파일에서도 div 요소의 id로 root를 설정해 리액트 컴포넌트를 렌더링&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;valueengine.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;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8165051221932976&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;b&gt;&amp;lt;/&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;끊임없이 성장하기 위해 공부한 내용을 글로 작성하고 있습니다. 틀린 부분이나 추가해야 할 부분이 있다면 언제든 댓글로 남겨주세요&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;❗️&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도서 &amp;lt;리액트를 다루는 기술&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;https://ko.legacy.reactjs.org/docs/hooks-reference.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.legacy.reactjs.org/docs/hooks-reference.html&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=G3qglTF-fFI&amp;amp;list=PLZ5oZ2KmQEYjwhSxjB_74PoU6pmFzgVMO&quot;&gt;https://www.youtube.com/watch?v=G3qglTF-fFI&amp;amp;list=PLZ5oZ2KmQEYjwhSxjB_74PoU6pmFzgVMO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://velog.io/@iamhayoung/React-Hooks-useReducer%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@iamhayoung/React-Hooks-useReducer%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://itprogramming119.tistory.com/entry/React-useRef-%EC%82%AC%EC%9A%A9%EB%B2%95-%EB%B0%8F-%EC%98%88%EC%A0%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://itprogramming119.tistory.com/entry/React-useRef-%EC%82%AC%EC%9A%A9%EB%B2%95-%EB%B0%8F-%EC%98%88%EC%A0%9C&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/React</category>
      <category>Hook</category>
      <category>react</category>
      <category>state</category>
      <category>useCallback</category>
      <category>useMemo</category>
      <category>useReducer</category>
      <category>useRef</category>
      <category>useState</category>
      <category>리액트</category>
      <category>면접</category>
      <author>미주민</author>
      <guid isPermaLink="true">https://valueengine.tistory.com/77</guid>
      <comments>https://valueengine.tistory.com/77#entry77comment</comments>
      <pubDate>Mon, 10 Jul 2023 05:07:58 +0900</pubDate>
    </item>
    <item>
      <title>[React/기술면접] Hook (1)</title>
      <link>https://valueengine.tistory.com/76</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #9feec3; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;React Hooks&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;React.jpeg&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;665&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Bn61U/btsmQgnmou2/fz3FW8IccZj39ZFmDtgwLK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bn61U/btsmQgnmou2/fz3FW8IccZj39ZFmDtgwLK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bn61U/btsmQgnmou2/fz3FW8IccZj39ZFmDtgwLK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBn61U%2FbtsmQgnmou2%2Ffz3FW8IccZj39ZFmDtgwLK%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;500&quot; height=&quot;277&quot; data-filename=&quot;React.jpeg&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;665&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;* 기술면접 질문은 맨 아래에 적혀 있습니다&lt;/span&gt;&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;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;1. Hook의 등장 배경&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컴포넌트에는 클래스형 컴포넌트와 함수형 컴포넌트가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;클래스형 컴포넌트에서는 constructor(생성자)에서 state를 정의하고 setState() 함수를 통해 state를 업데이트 해줄 수 있다.&amp;nbsp;거기다가 생명주기 함수들까지 명확하게 정의되어 있기 때문에 편리하게 가져다 쓰면 된다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;반면, 함수형 컴포넌트에서는 별도로 state를 정의하거나 생명주기에 따른 기능 구현이 불가능했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;함수가 state를 가지지 못하는 이유는 &lt;b&gt;리렌더링될 때 함수 내에 작성된 모든 코드들이 다시 실행&lt;/b&gt;되기 때문이다. 이로 인해 기존에 가지고 있던 state를 전혀 관리(기억)할 수 없기에 함수형 컴포넌트에서는 state를 사용할 수 없었다.&lt;/span&gt;&lt;/span&gt;&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;그러나 클래스형 컴포넌트 역시 다음과 같은 단점을 가지고 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수형 컴포넌트에 비해 코드가 복잡하고, 재사용성도 떨어진다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;상태 관리 및 생명주기 함수를 사용하기 위한 추가적인 학습이 필요하다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;this가 가리키는 값이 변경되면 문제를 발생시킬 수 있다.&lt;br /&gt;&lt;br /&gt;ex&amp;gt; A를 팔로우하려고 했으나 팔로우 되기 이전 B 유저로 바꾸면서 컴포넌트가 리런데링되고,&amp;nbsp;this가 가리키는 값이 B로 변경되어 B가 팔로우됨&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이러한 점들 때문에 함수형 컴포넌트에서 부족했던 기능인 state와 생명주기 기능을 가능을 할 수 있게 해주는 것이 &lt;b&gt;hook&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 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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;2. Hook이란?&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Hook&lt;/b&gt;은 함수형 컴포넌트에서 React state와 생명주기 기능을 &quot;연동(hook into)&quot;할 수 있게 해주는 함수로, 리액트 16.8 버전부터 추가 되었다. 이름 그대로 React state와 생명주기 기능을 갈고리처럼 걸어 &lt;span style=&quot;text-align: start;&quot;&gt;원하는 시점에&amp;nbsp;정해진 함수가 실행될 수 있도록 해준다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;Hook을 사용한 함수형 컴포넌트가 state를 가질 수 있는 이유는 &lt;b&gt;Closure를 이용해 함수형 컴포넌트 바깥에 state를 저장&lt;/b&gt;하기 때문이다. 그래서 state가 업데이트 되어도 컴포넌트 바깥에 선언되어 있는 변수들이기 때문에 업데이트 한 이후에도 이 변수들에 접근할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2-1. Hook의 규칙&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Hook을 사용하기 위해선 다음과 같은 규칙을 지켜야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수(컴포넌트)의 최상위에서만 Hook을 호출&lt;br /&gt;&lt;br /&gt;- 그래야 컴포넌트가 렌더링될 때마다 항상 동일한 순서로 Hook이 호출되는 것이 보장된다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React 함수 내에서만 Hook을 호출&lt;br /&gt;&lt;br /&gt;- 일반적인 JavaScript 함수에서는 호출 X&lt;br /&gt;&lt;br /&gt;- Custom Hook에서는 Hook을 호출할 수 있다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;Hook의 이름이 use로 시작해야 한다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;2-2. Hook의 장점&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;이러한 Hook은 다음과 같은 장점을 가지고 있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;더 간결한 코드&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 클래스형 컴포넌트처럼 this 키워드나 생명주기 함수 등의 복잡한 문법을 사용하지 않아도 되므로, 코드 작성량이 줄어들고 가독성도 좋아진다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컴포넌트 로직의 재사용성&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 원하는 기능을 함수로 만들어 필요한 곳에 넣어주기만 하면 되기 때문에 로직을 재사용하기 더욱 쉬워진다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태 관리의 용이성&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 다양한 상태관리 hook을 활용해 컴포넌트 내에서 간단하게 상태(state)를 관리할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;3. Hook API&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Hook에는 각 기능에 따라 여러 Hook이 있으며, 이름 앞에는 &lt;b&gt;use&lt;/b&gt;로 시작한다. 개발자가 직접 커스텀 Hook을 만들 때에도 use로 시작해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;3-1. useState&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;useState&lt;/b&gt;는 함수형 컴포넌트에서 state를 사용하기 위한 Hook이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;useState를 사용하기 위해선 import해와야 하며, useState의 인자에는 state의 초기값이 들어간다. 이때 useState 함수 내에 선언되는 상태(state)들은 &lt;b&gt;&quot;배열&quot;&lt;/b&gt;의 형식으로 저장된다. 이 배열은 state로 선언된 &lt;b&gt;변수&lt;/b&gt;와 이 state값을 변경할 수 있는 &lt;b&gt;set 함수&lt;/b&gt;를 가지고 있기에 이를 구조분해할당해서 state와 set 함수를 사용한다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;set 함수의 이름은 카멜(camel) 형식으로 &quot;set + 변수명&quot;으로 사용하는 것이 좋다. 예를 들어, 변수명이 name이면, set 함수는 setName이 되면 된다. 그 이유는&amp;nbsp;&lt;b&gt;각 state마다 별개의 set 함수를 만들어줘야 하기 때문&lt;/b&gt;이다. 클래스형 컴포넌트에서는 setState 함수 하나로 모든 state값을 업데이트할 수 있었지만, 함수형 컴포넌트에서는 각 변수마다 별개의 set 함수를 만들어줘야 한다. 따라서 각 state에 대응하는 set함수가 어떤 것인지 파악하기 쉽도록 set + 변수명으로 이름을 지어주는 것을 권장한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이러한 &lt;span style=&quot;text-align: start;&quot;&gt;set 함수를 통해 state 값을 변경할 수 있는데, state가 변경되면 자동으로 리렌더링이 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688898328749&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useState } from 'react';

const [변수, set함수] = useState(초기값);&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;&lt;span style=&quot;color: #000000;&quot;&gt;아래의 예시를 보면, count의 초기값은 0이고, 각 버튼에 따라 setCount 함수가 count 값을 업데이트해준다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688898090617&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useState } from 'react';

const Counter = () {
  const [count, setCount] = useState(0);
  
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;현재 카운터 값은 {count}입니다.&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count +1)}&amp;gt;+1&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count -1)}&amp;gt;-1&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;3-2. useEffect&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;useEffect&lt;/b&gt;는 side effect를 수행하기 위한 Hook이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;여기서 side effect는 함수가 실행되면서 함수 외부에 존재하는 값이나 상태를 변경시키는 등의 행위를 말한다. 예를 들면, 서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 작업 등이 있을 수 있다. 이 행위를 effect라 부르는 이유는 이 행위가 다른 컴포넌트에 영향을 미칠 수 있고, 렌더링 중에는 작업이 완료될 수 없기 때문이다. 즉, &lt;b&gt;렌더링 이후에 실행되어야 하는 작업들&lt;/b&gt;이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1) useEffect 사용법&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;useEffect의 사용법은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기서 의존성 배열(dependency array)는 이 effect가 의존하고 있는 배열인데, 배열 내에 그 어떤 변수 하나라도 변경되게 되면 effect 함수가 실행된다. 기본적으로 effect 함수는 처음 컴포넌트가 렌더링된 이후와 업데이트로 인한 리렌더링 이후에 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688928642392&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect } from 'react';

// (콜백함수, dependency array)
useEffect(이펙트 함수, 의존성 배열);&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;아래와 같이 의존성 배열 내에 어떤 value 값이 들어가게 되면, 첫 렌더링 될 때와 value 값이 바뀔 때마다 effect 함수가 실행된다.&lt;/p&gt;
&lt;pre id=&quot;code_1688932067883&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  // 작업
}, [value]);&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;&lt;span style=&quot;color: #000000;&quot;&gt;만약 effect 함수가 mount와 unmount 시에 단 한 번씩만 실행되게 하고 싶다면&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;(업데이트될 때 실행되지 않게 하려면)&lt;/span&gt;, 의존성 배열 자리에 빈 배열을 넣어주면 된다. 이렇게 되면 해당 effect가 props나 state에 있는 어떤 값에도 의존하지 않게 되므로 여러 번 실행되지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688928831584&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;useEffect(() =&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;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 의존성 배열을 생략하게 되면 컴포넌트가 업데이트될 때마다 호출된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688928944169&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;useEffect(() =&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;&lt;span style=&quot;color: #000000;&quot;&gt;useEffect에서는 &lt;b&gt;정리(clean-up)&lt;/b&gt; 작업을 할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;만약 effect 함수에 타이머를 등록했거나 이벤트 리스너를 등록했다면, return 값으로 정리 작업을 넣어줄 수 있다. 이렇게 함수를 리턴해주면, 해당 컴포넌트가 언마운트될 때 혹은 다음 렌더링 시 useEffect가 실행되기 이전에 clean-up 함수가 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688932486174&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  // 구독 작업...
  
  return () =&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;&lt;span style=&quot;color: #000000;&quot;&gt;아래는 clean-up의 예시이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Toggle 버튼을 눌러 Timer 컴포넌트가 화면에 보일지 말지 결정할 수 있으며, Timer가 등장했을 때 1초마다 콘솔창이 찍힌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;만약 Timer 컴포넌트를 사라지게 한다면, clearInterval가 실행되어 타이머가 중단된다. 만약 이 clean-up이 없다면, Timer는 종료된 것이 아니므로, 화면상에서 Timer 컴포넌트가 보이지 않더라도 콘솔창에서 타이머는 계속해서 작동한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688937015957&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useEffect } from 'react';

const Timer = (props) =&amp;gt; {
  useEffect(() =&amp;gt; {
    const timer = setInterval(() =&amp;gt; {
      console.log('타이머 돌아가는 중...');
    }, 1000);

    return () =&amp;gt; {
      clearInterval(timer);  // 타이머 clean-up
    };
  }, []);
  
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;span&amp;gt;타이머를 시작합니다. 콘솔을 보세요!&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1688937244127&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useState, useEffect } from 'react';
import Timer from './component/Timer';

function App() {
  const [showTimer, setShowTimer] = useState(false);
  return (
    &amp;lt;div&amp;gt;
      {showTimer &amp;amp;&amp;amp; &amp;lt;Timer /&amp;gt;}
      &amp;lt;button onClick={() =&amp;gt; setShowTimer(!showTimer)}&amp;gt;Toggle&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2) 라이프사이클&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이러한 useEffect는 &lt;b&gt;Class의 라이프사이클 함수와 유사한 기능을 수행&lt;/b&gt;할 수 있다. 즉, useEffect는 componentDidMount와 componentDidUpdate, componentWillUnmount를 한번에 실행할 수 있다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;아래는 클래스형 컴포넌트에서의 생명주기 함수 코드이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688928174048&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Example extends Component {
  constructor() {
    super();
    this.state = {
      name: &quot;&quot;,
    };
  };
}
// componentDidMount 함수
componentDidMount() {
  console.log(&quot;mount&quot;);
}
// componentDidUpdate 함수
componentDidUpdate(prevProps, prevState) {
  if (this.state.name !== prevState.name) {
    console.log(`update ${this.state.name}`);
  }
}
// componentWillUnmount 함수
componentWillUnmount() {
  console.log(&quot;unmount&quot;);
}

render() {
  return &amp;lt;div&amp;gt;{this.state.name}&amp;lt;/div&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;&lt;span style=&quot;color: #000000;&quot;&gt;useEffect를 활용하면 아래처럼 간단한 코드로 바꿀 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688928375294&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const Example = () =&amp;gt; {
  const [name, setName] = useState(&quot;&quot;);
  
  // componentDidMount 함수
  useEffect(() =&amp;gt; {
    console.log(&quot;mount&quot;);
    // componentWillUnmount 함수
    return () =&amp;gt; {
      console.log(&quot;unmount&quot;);
    };
  }, []);
  
  // componentDidUpdate 함수
  useEffect(() =&amp;gt; {
    console.log(`update ${name}`);
  }, [name]);
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8165051221932976&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;  React 기술면접 질문&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. React Hook의 장점은 무엇인가요?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;더 간결한 코드&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 클래스형 컴포넌트처럼 this 키워드나 생명주기 함수 등의 복잡한 문법을 사용하지 않아도 되므로, 코드 작성량이 줄어들고 가독성도 좋아진다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컴포넌트 로직의 재사용성&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 원하는 기능을 함수로 만들어 필요한 곳에 넣어주기만 하면 되기 때문에 로직을 재사용하기 더욱 쉬워진다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;상태 관리의 용이성&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;: 다양한 상태관리 hook을 활용해 컴포넌트 내에서 간단하게 상태(state)를 관리할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;b&gt;&amp;lt;/&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;끊임없이 성장하기 위해 공부한 내용을 글로 작성하고 있습니다. 틀린 부분이나 추가해야 할 부분이 있다면 언제든 댓글로 남겨주세요&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;❗️&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도서 &amp;lt;리액트를 다루는 기술&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;https://youtu.be/_eq5h9JzN4U&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://youtu.be/_eq5h9JzN4U&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/qjEcsNYFWYg&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://youtu.be/qjEcsNYFWYg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/evJ_O-H-EJI&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://youtu.be/evJ_O-H-EJI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=G3qglTF-fFI&amp;amp;list=PLZ5oZ2KmQEYjwhSxjB_74PoU6pmFzgVMO&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.youtube.com/watch?v=G3qglTF-fFI&amp;amp;list=PLZ5oZ2KmQEYjwhSxjB_74PoU6pmFzgVMO&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/React</category>
      <category>clean up</category>
      <category>dependency array</category>
      <category>Hook</category>
      <category>Hooks</category>
      <category>react</category>
      <category>state</category>
      <category>useEffect</category>
      <category>useState</category>
      <category>리액트</category>
      <category>면접</category>
      <author>미주민</author>
      <guid isPermaLink="true">https://valueengine.tistory.com/76</guid>
      <comments>https://valueengine.tistory.com/76#entry76comment</comments>
      <pubDate>Sun, 9 Jul 2023 21:02:25 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 다트 게임</title>
      <link>https://valueengine.tistory.com/74</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Programmers : 다트 게임&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;programmers.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7Gpyh/btsmzIc7qSd/W6YnO4RnAR3TEl5qB5qPS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7Gpyh/btsmzIc7qSd/W6YnO4RnAR3TEl5qB5qPS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7Gpyh/btsmzIc7qSd/W6YnO4RnAR3TEl5qB5qPS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7Gpyh%2FbtsmzIc7qSd%2FW6YnO4RnAR3TEl5qB5qPS1%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;604&quot; height=&quot;128&quot; data-filename=&quot;programmers.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;128&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot; data-token-index=&quot;0&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;문제 링크&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17682&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/17682&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1688580996934&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;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17682&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9WbYw/hyTedyepwc/uwUXSJVSkAXYw7zz27Bwr1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/hUVjg/hyTd9bxazh/pK3avQZZnd1gioTFYlgoGK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17682&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/17682&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9WbYw/hyTedyepwc/uwUXSJVSkAXYw7zz27Bwr1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/hUVjg/hyTd9bxazh/pK3avQZZnd1gioTFYlgoGK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 문제는&amp;nbsp;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt; 문자열&lt;/b&gt; &lt;/span&gt;과&amp;nbsp;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt; 조건문&lt;/b&gt; &lt;/span&gt;에 대한 이해가 있다면 충분히 풀 수 있는 문제였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;총 3번 다트를 던질 수 있으며, 각 기회마다 0~10점을 얻을 수 있다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;S(1제곱), D(2제곱), T(3제곱) 영역이 존재하며, 각 영역 당첨시 해당 점수가 영역만큼 제곱이 된다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스타상(*) 영역&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 스타상 당첨시 바로 전에 얻은 점수와 현재 해당 점수가 2배가 된다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 첫 번째 기회에서 스타상 당첨시 해당 점수만 2배가 된다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 스타상의 효과는 다른 스타상의 효과와 중첩될 수 있으며, 중첩된 경우는 4배가 된다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아차상(#) 영역&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 아차상 당첨시 해당 점수는 마이너스가 된다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 스타상의 효과는 아차상의 효과와 중첩될 수 있으며, 이때 -2배가 된다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem1.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;807&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AvZjO/btsmyUZlmRt/VE4VFdwxyBX0Q8lKovKrqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AvZjO/btsmyUZlmRt/VE4VFdwxyBX0Q8lKovKrqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AvZjO/btsmyUZlmRt/VE4VFdwxyBX0Q8lKovKrqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAvZjO%2FbtsmyUZlmRt%2FVE4VFdwxyBX0Q8lKovKrqK%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;731&quot; height=&quot;807&quot; data-filename=&quot;problem1.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;807&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;problem2.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crEq5T/btsmDHcJBTy/A0LSd87xnXp92XJCeId21k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crEq5T/btsmDHcJBTy/A0LSd87xnXp92XJCeId21k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crEq5T/btsmDHcJBTy/A0LSd87xnXp92XJCeId21k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrEq5T%2FbtsmDHcJBTy%2FA0LSd87xnXp92XJCeId21k%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;731&quot; height=&quot;284&quot; data-filename=&quot;problem2.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;284&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;입출력 예시&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4번째 예제는 1S*2T*3S다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;먼저, 1의 1제곱이고 스타상이 적용되어 2배가 된다. 그리고 2의 3제곱에 스타상이 적용되고, 앞선 1에도 스타상이 중첩 적용된다. 마지막으로 3의 1제곱이 온다. 따라서 1*2*2 + (2의 3제곱)*2 + 3이므로, 4+16+3 = 23이다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;5번째 예시는 1D#2S*3S다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;먼저, 1의 제곱이고 아차상이 적용되어 -1이 곱해진다. 그리고 2의 1제곱에 스타상이 적용되며, 앞선 1에 스타상과 아차상이 중첩 적용된다. 마지막으로, 3의 1제곱이 온다. 따라서 (1의 제곱)*(-1)*2 + 2*2 + 3이므로, -2+4+3=5이다.&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;input.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eGKvZH/btsmA2WfGjv/BiGuk9LpUxbbI2Hbs5nrb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eGKvZH/btsmA2WfGjv/BiGuk9LpUxbbI2Hbs5nrb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eGKvZH/btsmA2WfGjv/BiGuk9LpUxbbI2Hbs5nrb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeGKvZH%2FbtsmA2WfGjv%2FBiGuk9LpUxbbI2Hbs5nrb1%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;731&quot; height=&quot;717&quot; data-filename=&quot;input.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;717&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;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8165051221932976&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;풀이1 : switch 조건문&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여러 if 조건문을 고려해야 하므로 switch문을 사용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문자열 dartResult의 문자 각각을 item에 할당해준다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 만약 item이 정수일 경우, tmp에 그 정수 값을 임시로 저장해둔다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 정수가 10일 수 있고, 이 경우에 tmp에 1이 저장된 상태이므로, 앞선 문자가 1일 경우 10으로 바꿔준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문자가 정수가 아니라면, 각 제곱 조건을 따져준다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 만약 S(1제곱)일 경우는 1배이므로 정수 tmp 그대로 answer에 넣어준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 만약 D(2제곱)일 경우, 정수 tmp를 제곱하여 answer에 넣어준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 만약 T(3제곱)일 경우, 정수 tmp를 3제곱하여 answer에 넣어준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스타상과 아차상 조건을 따져준다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 스타상은 이전 정수값과 현재 정수값을 2배로 해줘야 하므로, 기존 값을 2배로 재할당해준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 아차상은 현재 정수값에 -1을 곱해준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최종적으로, answer에 담긴 모든 값을 다 더해 출력해준다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1688584858930&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(dartResult) {
    const answer = [];
    let tmp;
    
    for (let i=0; i &amp;lt; dartResult.length; i++) {
        let item = dartResult[i];
        
        if (!isNaN(Number(item))) {  // 정수라면
            tmp = dartResult[i-1] == 1 ? 10 : Number(item);
        } else {
            switch (item) {
                case 'S': answer.push(tmp);
                    break;
                case 'D': answer.push(Math.pow(tmp, 2));
                    break;
                case 'T': answer.push(Math.pow(tmp, 3));
                    break;
                case '*':
                    answer[answer.length-2] = answer[answer.length-2] * 2;
                    answer[answer.length-1] = answer[answer.length-1] * 2;
                    break;
                case '#':
                    answer[answer.length-1] = answer[answer.length-1] * (-1);
                    break;
            }
        }
    }
    return answer.reduce((acc, cur) =&amp;gt; acc + cur, 0);
}&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;&lt;span style=&quot;color: #000000; text-align: start;&quot;&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;test1.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzXB5K/btsmCNjRxM3/uI1mHJP9g0rYYwhj9b75F0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzXB5K/btsmCNjRxM3/uI1mHJP9g0rYYwhj9b75F0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzXB5K/btsmCNjRxM3/uI1mHJP9g0rYYwhj9b75F0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzXB5K%2FbtsmCNjRxM3%2FuI1mHJP9g0rYYwhj9b75F0%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;731&quot; height=&quot;658&quot; data-filename=&quot;test1.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;658&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLo3Tc/btsmA29LqHg/pCz1uknZ4ljPHvJI5vazo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLo3Tc/btsmA29LqHg/pCz1uknZ4ljPHvJI5vazo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLo3Tc/btsmA29LqHg/pCz1uknZ4ljPHvJI5vazo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLo3Tc%2FbtsmA29LqHg%2FpCz1uknZ4ljPHvJI5vazo0%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;731&quot; height=&quot;342&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;result1.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;527&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B3QUv/btsmCaM1kzf/kWoMGJZAtQvy5vVMKF0qQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B3QUv/btsmCaM1kzf/kWoMGJZAtQvy5vVMKF0qQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B3QUv/btsmCaM1kzf/kWoMGJZAtQvy5vVMKF0qQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB3QUv%2FbtsmCaM1kzf%2FkWoMGJZAtQvy5vVMKF0qQ0%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;731&quot; height=&quot;527&quot; data-filename=&quot;result1.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;527&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;result2.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lz0aZ/btsmzIRCQND/6iehyOCkjGAVJRR9aLmHk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lz0aZ/btsmzIRCQND/6iehyOCkjGAVJRR9aLmHk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lz0aZ/btsmzIRCQND/6iehyOCkjGAVJRR9aLmHk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flz0aZ%2FbtsmzIRCQND%2F6iehyOCkjGAVJRR9aLmHk1%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;731&quot; height=&quot;397&quot; data-filename=&quot;result2.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;397&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;b&gt;&amp;lt;/&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;끊임없이 성장하기 위해 공부한 내용을 글로 작성하고 있습니다. 틀린 부분이나 추가해야 할 부분이 있다면 언제든 댓글로 남겨주세요&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;❗️&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>JS</category>
      <category>match</category>
      <category>switch</category>
      <category>다트 게임</category>
      <category>알고리즘</category>
      <category>자바스크립트</category>
      <category>정규표현식</category>
      <category>조건문</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>미주민</author>
      <guid isPermaLink="true">https://valueengine.tistory.com/74</guid>
      <comments>https://valueengine.tistory.com/74#entry74comment</comments>
      <pubDate>Thu, 6 Jul 2023 03:16:45 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] k진수에서 소수 개수 구하기</title>
      <link>https://valueengine.tistory.com/73</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Programmers : k진수에서 소수 개수 구하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;programmers.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcpu3T/btsmApji2cR/aIfye2M8ut12krearUEvHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcpu3T/btsmApji2cR/aIfye2M8ut12krearUEvHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcpu3T/btsmApji2cR/aIfye2M8ut12krearUEvHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdcpu3T%2FbtsmApji2cR%2FaIfye2M8ut12krearUEvHK%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;604&quot; height=&quot;128&quot; data-filename=&quot;programmers.png&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;128&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot; data-token-index=&quot;0&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;문제 링크&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92335&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/92335&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1688546567060&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;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92335&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/NlEkr/hyTd66uOTh/elXRe3IdJLYleqPeqQ9oS0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/xMhZd/hyTeddsvg3/1MrvoMQbAx9GRQgkH7K531/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92335&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/92335&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/NlEkr/hyTd66uOTh/elXRe3IdJLYleqPeqQ9oS0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/xMhZd/hyTeddsvg3/1MrvoMQbAx9GRQgkH7K531/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;programmers.co.kr&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;문제&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 문제는&amp;nbsp;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt; 진수변환&lt;/b&gt; &lt;/span&gt;과&amp;nbsp;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt; 소수(prime number)&lt;/b&gt; &lt;/span&gt;가 무엇인지 알고 있으면 풀 수 있는 문제며, 어떻게 푸느냐에 따라 효율성이 달라졌다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;1. 양의 정수 n을 k진수로 변환했을 때, 변환된 수 내에 아래의 조건에 맞는 소수가 몇 개가 있는지 찾아야 한다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;0소수0 : 소수 양쪽에 0이 있는 경우&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소수0 : 소수 오른쪽에만 0이 있는 경우&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;0소수 : 소수 왼쪽에만 0이 있는 경우&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소수 : 소수만 있는 경우&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 위 조건을 쉽게 해석해보면, 소수 양쪽에 0이 있을 수도 있고 없을 수도 있는 모든 경우다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;0이 기준이 되므로, 0을 기준으로 변환된 n을 잘랐을 때 소수가 몇 개가 있는지 파악하면 된다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소수 내에 0이 포함되어서는 안 되므로, 0을 제거해줘도 상관없다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;problem.png&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;737&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d2ffFA/btsmB9tLN5I/xwayPrEoBdF0tZMAQb2KdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d2ffFA/btsmB9tLN5I/xwayPrEoBdF0tZMAQb2KdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d2ffFA/btsmB9tLN5I/xwayPrEoBdF0tZMAQb2KdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd2ffFA%2FbtsmB9tLN5I%2FxwayPrEoBdF0tZMAQb2KdK%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;727&quot; height=&quot;737&quot; data-filename=&quot;problem.png&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;737&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;입출력 예시&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1번째 예시에서 437674를 3진법으로 변환하면 211020101011이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;0을 기준으로 잘라주면, [211, 2, 1, 1, 11]이 된다. 1은 소수가 아니므로 여기에서 소수는 211, 2, 11이다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;2번째 예시는 10진법이므로 그대로 110011이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;0을 기준으로 잘라주면, [11, 11]이 된다. 여기서 소수는 11, 11이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이때 주의할 점은 110011을 0을 기준으로 잘라주면 ['11', '', '11']로 &lt;span style=&quot;color: #ee2323;&quot;&gt;빈 문자열이 포함&lt;/span&gt;되며, &lt;span style=&quot;color: #ee2323;&quot;&gt;빈 문자열을 정수화하면 0으로 변환되므로 이 역시 고려&lt;/span&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;input.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q1rIL/btsmwX245lX/0BKupaWF83vuEhcFWeH03k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q1rIL/btsmwX245lX/0BKupaWF83vuEhcFWeH03k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q1rIL/btsmwX245lX/0BKupaWF83vuEhcFWeH03k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq1rIL%2FbtsmwX245lX%2F0BKupaWF83vuEhcFWeH03k%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;731&quot; height=&quot;406&quot; data-filename=&quot;input.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;406&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;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8165051221932976&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #5c5c5c; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &amp;nbsp;&lt;b&gt;풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;총 2가지 방식으로 풀어보았다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;풀이1 : Math.sqrt&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;정수 N이 소수인지 판별하기 위한 가장 일차원적인 방법은 &lt;b&gt;&quot;N보다 작은 모든 자연수로 N을 나눠보는 것&quot;&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러나 이 판별법은 N 미만의 모든 자연수로 나눈다는 점에서 비효율적이다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;이것보다 나은 방법은 &lt;b&gt;&quot;&lt;i&gt;&amp;radic;N&lt;/i&gt; 이하의 모든 자연수들로 N을 나눠보는 것&quot;&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;N이 16일 때, N은 아래처럼 두 수의 곱으로 이루어져있다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;1 X 16&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2 X 8&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4 X 4&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;8 X 2&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;16 X 1&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;1부터 15까지의 수로 16을 나눴을 때, 2로 16이 나눠진다는 것은 8로도 16이 나눠진다는 것을 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;따라서 &lt;b&gt;&lt;i&gt;&amp;radic;N&lt;/i&gt; 보다 큰 수로 중복 검사&lt;/b&gt;되는 것을 막기 위해 &lt;i&gt;&amp;radic;N&lt;/i&gt;까지만 검사하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt;  문제 풀이&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;n을 k진법으로 변환하고 0을 기준으로 잘라준다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 잘려진 수들을 돌면서 각 수 num을 소수 판별 함수 isPrime에 넣어준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- true를 반환할 경우에는 num이 소수라는 것이므로 count를 증가시켜준다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;isPrime 함수&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 소수가 아닌 0과 1은 false로 반환해준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 2부터 &lt;i&gt;&amp;radic;N&lt;/i&gt; 미만의 모든 자연수로 num을 나눴을 때, 약수가 있다면 소수가 아니므로 false를 반환해준다&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- &lt;i&gt;&amp;radic;N&lt;/i&gt;&lt;span style=&quot;text-align: left;&quot;&gt;&amp;nbsp;이하의 모든 자연수로 나눠도 약수가 없을 경우는 num이 소수이므로 true를 반환해준다&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1688576973999&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(n, k) {
    let count = 0;
    n.toString(k).split(&quot;0&quot;)
     .map((num) =&amp;gt; {
        if (isPrime(Number(num))) {
            count++;
        }
    });
    return count;
}

function isPrime(num) {
    if (num &amp;lt;= 1) {
        return false;
    }
    for (let i=2; i &amp;lt;= Math.sqrt(num); i++) {
        if (num % i === 0) {  // 약수가 있다면 소수가 아니다
            return false;
        }
    }
    return true;
}&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;&lt;span style=&quot;color: #000000; text-align: start;&quot;&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;test.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;349&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WwhV6/btsmyumrYNo/3BTqZ3mremug6AHIaLnwKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WwhV6/btsmyumrYNo/3BTqZ3mremug6AHIaLnwKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WwhV6/btsmyumrYNo/3BTqZ3mremug6AHIaLnwKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWwhV6%2FbtsmyumrYNo%2F3BTqZ3mremug6AHIaLnwKK%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;731&quot; height=&quot;349&quot; data-filename=&quot;test.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;349&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;result.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V2lZF/btsmDHqgImf/VXFX51HlKeC7PQaA1SohXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V2lZF/btsmDHqgImf/VXFX51HlKeC7PQaA1SohXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V2lZF/btsmDHqgImf/VXFX51HlKeC7PQaA1SohXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV2lZF%2FbtsmDHqgImf%2FVXFX51HlKeC7PQaA1SohXk%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;731&quot; height=&quot;524&quot; data-filename=&quot;result.png&quot; data-origin-width=&quot;731&quot; data-origin-height=&quot;524&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &amp;nbsp;&lt;/span&gt;풀이2 :&amp;nbsp;에라토스테네스의 체&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;소수를 찾는 대표적인 방법 중 하나인 &quot;에라토스테네스의 체&quot;로 풀어보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&quot;에라토스테네스의 체&quot;&lt;/b&gt;는 a의 배수들은 a를 약수로 가지고 있어 소수가 아니므로, a의 배수들을 모두 제외시키는 방법이다.&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;에라체.gif&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;369&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UCUMx/btsmHcdlMEt/smeyT1H166cueno512F7j1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UCUMx/btsmHcdlMEt/smeyT1H166cueno512F7j1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UCUMx/btsmHcdlMEt/smeyT1H166cueno512F7j1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/UCUMx/btsmHcdlMEt/smeyT1H166cueno512F7j1/img.gif&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;445&quot; height=&quot;369&quot; data-filename=&quot;에라체.gif&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;369&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;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: center;&quot;&gt;  문제 풀이&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;n을 k진법으로 변환하고 0을 기준으로 잘라주고, 정수화해준다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 에라토스테네스의 체로 소수가 아닌 수들을 가려내기 위해 정수들 중 가장 큰 수를 MAX로 뽑아준다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에라토스테네스의 체&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 0과 1은 소수가 아니므로 true로 noPrime에 넣어준다&lt;br /&gt;&lt;br /&gt;- 2부터 MAX의 제곱근 범위까지 돌면서 모든 소수가 아닌 모든 수를 true로 넣어준다&lt;br /&gt;&lt;br /&gt;- i의 배수들은 모두 true로 들어간다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;num 중에서 noPrime에 들어가 있지 않다면 소수이므로, count를 증가시켜준다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1688630718033&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(n, k) {
    let count = 0;
    const arr = n.toString(k).split(&quot;0&quot;).map(Number);
    const MAX = Math.max(...arr);
    
    // 에라토스테네스의 체
    const noPrime = { 0: true, 1: true };
    for (let i=2; i &amp;lt;= Math.sqrt(MAX); i++) {
        if (noPrime[i]) {
            continue;
        }
        for (let j = i * i; j &amp;lt;= MAX; j += i) {
            noPrime[j] = true;
        }
    }

    arr.map((num) =&amp;gt; {
        if (!noPrime[num]) {
            count++;
        }
    });
    return count;
}&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;&lt;span style=&quot;color: #000000;&quot;&gt;예시 케이스는 모두 정상적으로 통과했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그러나 몇몇 케이스에서는 런타임 에러가 발생했다. 1번째 테스트 케이스는 n은 885733, k는 3이다. 3진법으로 바꾸면 1122222222221이 된다. 이때&amp;nbsp;&lt;span style=&quot;text-align: start;&quot;&gt;MAX가 커지면서 noPrime에 들어갈 수 있는 수의 제한이 있어 런타임 에러가 발생했다.&lt;/span&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;rangeError.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;174&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rz5cc/btsmGiewXkq/v1XVQ7F1eoizHClXKsBZ30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rz5cc/btsmGiewXkq/v1XVQ7F1eoizHClXKsBZ30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rz5cc/btsmGiewXkq/v1XVQ7F1eoizHClXKsBZ30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRz5cc%2FbtsmGiewXkq%2Fv1XVQ7F1eoizHClXKsBZ30%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;586&quot; height=&quot;174&quot; data-filename=&quot;rangeError.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;174&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;&lt;span style=&quot;color: #000000;&quot;&gt;정수 N 이하의 모든 수 중에서 소수를 찾는 문제라면 Math.sqrt 보다는 에라토스테네스의 체가 좀 더 효율적일 수 있지만, 배열 길이가 너무 큰 경우에는 Math.sqrt를 쓰는 것이 낫다는 걸 배울 수 있었다.&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;test2.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwOmVo/btsmIgM9Fw5/BKp2Y7qTJpk4oZFI3CCYAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwOmVo/btsmIgM9Fw5/BKp2Y7qTJpk4oZFI3CCYAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwOmVo/btsmIgM9Fw5/BKp2Y7qTJpk4oZFI3CCYAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwOmVo%2FbtsmIgM9Fw5%2FBKp2Y7qTJpk4oZFI3CCYAK%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;732&quot; height=&quot;293&quot; data-filename=&quot;test2.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;result2.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;519&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXiZe5/btsmGAFUWqv/mmTBQ4YHMnCwgE83s5933K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXiZe5/btsmGAFUWqv/mmTBQ4YHMnCwgE83s5933K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXiZe5/btsmGAFUWqv/mmTBQ4YHMnCwgE83s5933K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXiZe5%2FbtsmGAFUWqv%2FmmTBQ4YHMnCwgE83s5933K%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;732&quot; height=&quot;519&quot; data-filename=&quot;result2.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;519&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;b&gt;&amp;lt;/&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;끊임없이 성장하기 위해 공부한 내용을 글로 작성하고 있습니다. 틀린 부분이나 추가해야 할 부분이 있다면 언제든 댓글로 남겨주세요&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;❗️&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://st-lab.tistory.com/81&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://st-lab.tistory.com/81&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/Programmers</category>
      <category>JS</category>
      <category>K진수에서 소수 개수 구하기</category>
      <category>sqrt</category>
      <category>소수</category>
      <category>알고리즘</category>
      <category>에라체</category>
      <category>에라토스테네스의 체</category>
      <category>자바스크립트</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>미주민</author>
      <guid isPermaLink="true">https://valueengine.tistory.com/73</guid>
      <comments>https://valueengine.tistory.com/73#entry73comment</comments>
      <pubDate>Wed, 5 Jul 2023 23:26:34 +0900</pubDate>
    </item>
    <item>
      <title>[React/기술면접] 생명 주기 (Life Cycle)</title>
      <link>https://valueengine.tistory.com/72</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #9feec3;&quot;&gt;&lt;b&gt;&amp;nbsp;생명 주기 (Life Cycle)&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;React.jpeg&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;665&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v9XgA/btsmfMNpetO/ZEDq0Mk7BtVEJDOBwWQm20/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v9XgA/btsmfMNpetO/ZEDq0Mk7BtVEJDOBwWQm20/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v9XgA/btsmfMNpetO/ZEDq0Mk7BtVEJDOBwWQm20/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv9XgA%2FbtsmfMNpetO%2FZEDq0Mk7BtVEJDOBwWQm20%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;500&quot; height=&quot;277&quot; data-filename=&quot;React.jpeg&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;665&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;&lt;span style=&quot;color: #000000;&quot;&gt;혹시 컴포넌트도 수명이 있다는 것을 알고 있나요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사람이 태어나서 성장하고 생명을 다하는 것처럼 리액트 컴포넌트도 이러한 과정을 겪으며, 이를 &lt;b&gt;생명주기(Life Cycle)&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;1. 생명 주기&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React 컴포넌트에는 생명 주기(라이프사이클)가 존재한다. 생명 주기는&amp;nbsp;&lt;b&gt;생성(mounting) - 업데이트(updating) - 제거(unmounting) 단계&lt;/b&gt;로 구성되어져 있으며, 각 단계마다 특정한 이벤트가 발생하며 그 때마다 사용되는 메서드가 있다. 이러한 생명주기 함수는 클래스형 컴포넌트에서만 사용할 수 있으며, 함수형 컴포넌트에서는 사용할 수 없다. 함수형 컴포넌트에서는 Hooks으로 유사한 기능을 활용할 수 있으므로, 이 부분은 Hooks에서 다뤄볼 것이다.&lt;/span&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;2-1. 마운트&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;처음 DOM이 생명된 후 웹 브라우저상에 나타나는 단계를&amp;nbsp;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt; 마운트(mount)&lt;/b&gt; &lt;/span&gt;라 하며, 다음과 같은 메서드들이 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &lt;b&gt;1. constructor&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688460072908&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;constructor(props) { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컴포넌트의 생성자 메서드로, 컴포넌트가 생성될 때 가장 먼저 실행된다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 메서드 내에서 state를 정의할 수 있으며, state가 필요없다면 constructor를 작성하지 않아도 된다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;주의&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;해당 함수의 1번째 라인에 반드시 super(props)를 호출해야 하며, 미호출시 props가 생성되지 않는다&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 2. &lt;b&gt;getDerivedStateFromProps&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React 16.3 버전 이후에 나온 라이프사이클 메서드&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;props로 받아온 값을 state에 동기화해주는 메서드로, 컴포넌트가 마운트될 때와 업데이트될 때 호출된다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp; 3. render&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688460652331&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;render() { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컴포넌트를 렌더링 해주는 메서드&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;렌더링할 것이 없는 경우, null 또는 false를 리턴한다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;주의&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;여기서 state를 수정해서는 안 되며, state를 수정할 경우 render()가 다시 호출될 수 있다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;브라우저의 DOM에 접근해서는 안 되며, DOM의 정보를 가져오거나 state에 변화를 줄 때는 componentDidMount에서 처리해야 한다&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 4.&amp;nbsp;&lt;b&gt;componentDidMount&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688461356811&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;componentDidMount() { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴포넌트의 첫 번째 렌더링이 끝나면 호출되는 메서드&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;이 메서드가 호출되는 시점에는 화면에 컴포넌트가 나타난 상태이다&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;이 안에서는 JS 라이브러리나 프레임워크 함수를 호출하거나 이벤트 등록, setTimeout, setInterval, 네트워크 요청 같은 비동기 작업을 처리할 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;2-2. 업데이트&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React 컴포넌트에 변화가 있을 때를&amp;nbsp;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt; 업데이트(update)&lt;/b&gt; &lt;/span&gt;라 하며, 다음과 같은 경우에 업데이트를 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;props가 바뀔 때&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;부모 컴포넌트에서 넘겨주는 props가 바뀔 때&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;state가 바뀔 &lt;span style=&quot;color: #000000;&quot;&gt;바뀔 때&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;setState 함수를 통해 state가 업데이트될 때&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;부모 컴포넌트가 리렌더링될 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;때&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: circle;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;자신에게 할당된 props 또는 state가 바뀌지 않아도 리렌더링된다&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;this.forceUpdate로 강제로 렌더링을 트리거할 때&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;span style=&quot;color: #000000;&quot;&gt;이때 실행되는 메서드는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 1. &lt;b&gt;getDerivedStateFromProps&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컴포넌트의 props나 state가 바뀌었을 때 호출된다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 2. &lt;b&gt;shouldComponentUpdate&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688461804502&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;shouldComponentUpdate(nextProps, nextState) { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;props 또는 state를 변경했을 때, 컴포넌트가 리렌더링 할지 말지를 결정하는 메서드&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;반드시 true 또는 false 값을 반환해야 하며, false를 반환할 경우 업데이트 과정은 중단된다&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;이 메서드를 따로 생성하지 않으면 언제나 true를 반환한다&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;메서드 내부에서 현재 props, state는 this.props, this.state로 접근이 가능하며, 새로 설정될 props와 state는 각각 nextProps, nextState로 접근이 가능하다&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp; 3. render&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688462458434&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;render() { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컴포넌트를 리렌더링해준다&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; 4. &lt;b&gt;getSnapshotBeforeUpdate&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688462141251&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;getSnapshotBeforeUpdate(prevProps, prevState) {
    if (prevState.array !== this.state.array) {
        const { scrollTop, scrollHeight } = this.list
        return { scrollTop, scrollHeight };
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;컴포넌트 변화를 DOM에 반영하기 바로 직전에 호출하는 메서드로, React 16.3 버전 이후에 만들어졌다&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 메서드에서 반환하는 값은 componentDidUpdate의 3번째 파라미터인 snapshot 값으로 전달받을 수 있으며, 주로 업데이트하기 직전의 값을 참고할 때 활용된다&lt;br /&gt;&lt;br /&gt;* 예시 : 스크롤바 위치 유지&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp; 5. componentDidUpdate&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688462296860&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;componentDidUpdate(prevProps, prevState, snapshot) { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리렌더링(업데이트) 작업이 완료된 후 실행하는 메서드&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;업데이트가 끝난 직후이므로 DOM 관련 처리를 해도 된다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여기서는 prevProps, prevState를 사용해서 컴포넌트가 이전에 가졌던 데이터에 접근이 가능하다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;2-3. 언마운트&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;&amp;nbsp;언마운트(unmount)&lt;/b&gt; &lt;/span&gt;는 마운트의 반대 과정으로, 컴포넌트를 DOM에서 제거하는 과정이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. componentWillUnmount&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688463119386&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;componentWillUnmount() { ... }&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;컴포넌트가 웹 브라우저상에서 사라지기 전에 호출하는 메서드&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;componentDidMount에서 등록한 이벤트, 타이머, 직접 생성한 DOM 등이 있다면, 여기서 제거 작업을 해야 한다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;2-4. (추가적인) 라이프사이클 메서드&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp; 1. componentDidCatch&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688378084332&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;componentDidCatch(error, info) {
    this.setState({
        error: true
    });
    console.log({ error, info });
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;React 16 버전에서 새롭게 도입된 메서드&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;컴포넌트 렌더링 도중에 에러가 발생했을 때 어플리케이션이 먹통이 되지 않고 오류 UI를 보여준다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;여기서 error는 어떤 에러가 발생했는지 알려주며, info는 어디에 있는 코드에서 오류가 발생했는지 알려준다&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;그러나 이 메서드는 자신의 컴포넌트 에러는 잡아내지 못하기에 this.props.children으로 전달되는 컴포넌트에서 발생하는 에러만 잡아낼 수 있다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8165051221932976&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;b&gt;&amp;lt;/&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;끊임없이 성장하기 위해 공부한 내용을 글로 작성하고 있습니다. 틀린 부분이나 추가해야 할 부분이 있다면 언제든 댓글로 남겨주세요&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;❗️&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도서 &amp;lt;리액트를 다루는 기술&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=pjakE0D4CeI&quot;&gt;https://www.youtube.com/watch?v=pjakE0D4CeI&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chanhuiseok.github.io/posts/react-9/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://chanhuiseok.github.io/posts/react-9/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gseok.gitbooks.io/react/content/bd80-bd84-bd80-bd84-c9c0-c2dd-b4e4/react-component-lifecycle-api-c815-b9ac.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gseok.gitbooks.io/react/content/bd80-bd84-bd80-bd84-c9c0-c2dd-b4e4/react-component-lifecycle-api-c815-b9ac.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/React</category>
      <category>life cycle</category>
      <category>react</category>
      <category>기술면접</category>
      <category>라이프사이클</category>
      <category>리액트</category>
      <category>마운트</category>
      <category>생명주기</category>
      <category>생명주기 함수</category>
      <category>언마운트</category>
      <category>업데이트</category>
      <author>미주민</author>
      <guid isPermaLink="true">https://valueengine.tistory.com/72</guid>
      <comments>https://valueengine.tistory.com/72#entry72comment</comments>
      <pubDate>Mon, 3 Jul 2023 15:50:28 +0900</pubDate>
    </item>
    <item>
      <title>[React/기술면접] ref란?</title>
      <link>https://valueengine.tistory.com/71</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #9feec3;&quot;&gt;&lt;b&gt;&amp;nbsp;ref란?&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;React.jpeg&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;665&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xggYN/btsl1gIlQaL/4NQmshyyFScCs6Mmo5LyRk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xggYN/btsl1gIlQaL/4NQmshyyFScCs6Mmo5LyRk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xggYN/btsl1gIlQaL/4NQmshyyFScCs6Mmo5LyRk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxggYN%2Fbtsl1gIlQaL%2F4NQmshyyFScCs6Mmo5LyRk%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;500&quot; height=&quot;277&quot; data-filename=&quot;React.jpeg&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;665&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;* 기술면접 질문은 맨 아래에 적혀 있습니다&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;일반적으로 DOM 요소에 이름을 달 때 id를 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리액트의 public/index.html 파일에서도 div 요소의 id로 root를 설정해 리액트 컴포넌트를 렌더링 시켜준다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688206685397&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// public/index.html
&amp;lt;div id=&quot;root&quot;&amp;gt;&amp;lt;/div&amp;gt;

// src/index.js
const root = ReactDOM.createRoot(document.getElementById('root'));&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;&lt;span style=&quot;color: #000000;&quot;&gt;그러나 리액트 컴포넌트 안에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;특수한 경우가 아니라면 id의 사용을 권하지 않는다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그 이유는 &lt;b&gt;HTML에서 id는 유일해야 하는데, 컴포넌트를 재사용할 때마다 중복 id를 가진 DOM이 여러 개가 생겨나기 때문&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;따라서 리액트에서 DOM에 이름을 달기 위해&amp;nbsp;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt; ref(reference)&lt;/b&gt; &lt;/span&gt;를 사용한다. ref는 전역적으로 작동하지 않고, &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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ref가 어떻게 구성되어 있는지 콘솔을 찍어보면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ref는 current 프로퍼티를 가진 객체이다. 뒤에서 살펴보겠지만, ref는 &lt;b&gt;current&lt;/b&gt;를 사용해 DOM 요소에 접근할 수 있다.&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;ref.png&quot; data-origin-width=&quot;188&quot; data-origin-height=&quot;41&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/orynH/btsl1Wb1JVJ/WGmSAuqzJ0KMHM5USqptW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/orynH/btsl1Wb1JVJ/WGmSAuqzJ0KMHM5USqptW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/orynH/btsl1Wb1JVJ/WGmSAuqzJ0KMHM5USqptW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2ForynH%2Fbtsl1Wb1JVJ%2FWGmSAuqzJ0KMHM5USqptW1%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;500&quot; height=&quot;109&quot; data-filename=&quot;ref.png&quot; data-origin-width=&quot;188&quot; data-origin-height=&quot;41&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;1. ref를 사용해야 하는 상황&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그렇다면 언제 ref를 사용해야 할까? 바로 &lt;b&gt;'DOM을 직접적으로 건드려야 할 때'&lt;/b&gt; 이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아래와 같은 경우에는 DOM에 직접적으로 접근해야 합니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;특정 input에 focus 주기, 텍스트 선택 영역 혹은 미디어의 재생을 관리할 때&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;애니메이션을 직접적으로 실행시킬 때&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Canvas 요소에 그림 그리기&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위와 같은 경우들은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;비제어 컴포넌트를 제어하는 경우&lt;/b&gt;&lt;/span&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;&lt;span style=&quot;color: #000000;&quot;&gt;즉, React 시스템 내에서 제어하지 않고, 순수 JS를 이용해 컴포넌트를 제어한다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이것이 일반적인 경우와 어떻게 다른지 살펴보고 가자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1-1. 제어 컴포넌트&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1688288025348&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { Component } from &quot;react&quot;;

class Example1 extends Component {
  constructor(props) {
    super(props);

    this.state = {
      value: &quot;&quot;
    };
  }

  render() {
    return (
      &amp;lt;input
        value={this.state.value}
        onChange={({ target: { value } }) =&amp;gt;
          this.setState({ ...this.state, value })
        }
      /&amp;gt;
    );
  }
}

export default Example1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 코드는 React의 상태로 제어하는 컴포넌트다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;state로 input의 value를 관리하기 때문에 입력창에 값을 입력할 때마다 state가 변하게 되고, React에서 state가 변한다는 것은 그때마다 UI를 리렌더링 해줘야 한다는 것을 의미한다. 즉, React의 내에서 input의 value를 제어하게 되면 리렌더링이 반복적으로 일어나 성능을 떨어트릴 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1-2. 비제어 컴포넌트&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1688288413366&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { Component } from &quot;react&quot;;

class Example2 extends Component { {
  constructor(props) {
    super(props);

    this.ref = React.createRef();
  }

  render() {
    return (
      &amp;lt;input ref={this.ref} /&amp;gt;
    );
  }
}

export default Example2;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그렇다면 React가 해당 input 요소를 관리하지 않으면 문제는 해결된다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;뒤에서 자세히 살펴볼 것이기에 간단하게 설명하자면, ref는 input 요소만 가리키고 있기에 입력창에 아무리 값을 입력해도 state는 변경되지 않으므로 리렌더링이 발생하지 않는다.&lt;/span&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;2. ref 사용 방법&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그럼 이제 ref의 사용법에 대해 자세히 살펴보자. ref를 사용하는 방법에는 2가지가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2-1. 콜백 함수를 통한 ref 설정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;첫 번째 방법은 콜백 함수를 사용하는 것이다. &lt;b&gt;원하는 요소에 ref라는 콜백 함수를 props로 전달&lt;/b&gt;해주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아래 코드처럼 input의 props로 ref 콜백함수를 전달해주면, this.inputTag는 input 요소의 DOM을 가리키게 된다. 여기서 ref의 이름인 setInput는 자유롭게 지어주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688290502567&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { Component } from &quot;react&quot;;

class callbackRef extends Component {
	inputTag = null;
    
    setInput = (ref) =&amp;gt; {
    	this.inputTag = ref;
    };

    render() {
        return (
            &amp;lt;div&amp;gt;
            	// this.ref이름
                &amp;lt;input ref={this.setInput} /&amp;gt;
            &amp;lt;/div&amp;gt;
        )
    }
}

export default callbackRef;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2-2. createRef를 통한 ref 설정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;두 번째 방법은 React에 내장되어 있는 createRef 함수를 사용하는 것이다. 이 기능은 React 16.3 버전부터 사용이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이를 사용하기 위해선 먼저 변수에 React.createRef()를 할당해줘야 한다. 그리고 해당 변수를 props로 넣어주면 된다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;만약 DOM에 접근하려면 &lt;b&gt;this.ref이름.current&lt;/b&gt;를 사용하면 된다. 콜백 함수 때와 달리 끝에 current 프로퍼티를 붙여 사용해줘야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1688292112120&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { Component } from &quot;react&quot;;

class createRef extends Component {
    setInput = React.createRef();

    handleFocus = () =&amp;gt; {
        this.setInput.current.focus();
    }

    render() {
        return (
            &amp;lt;div&amp;gt;
                &amp;lt;input ref={this.setInput} /&amp;gt;
            &amp;lt;/div&amp;gt;
        )
    }
}

export default createRef;&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;b&gt;&amp;nbsp;3. 컴포넌트에 ref 달기&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리액트에서는 컴포넌트에도 ref를 달 수 있다. 이 방법은 &lt;b&gt;컴포넌트 내부의 DOM 요소를 컴포넌트 외부에서 사용해야 할 때&lt;/b&gt; 활용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ref를 다는 방법은 동일하다.&lt;/span&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;span style=&quot;color: #000000;&quot;&gt;이렇게 할 경우, 컴포넌트 외부에서 컴포넌트 내부의 메서드나 변수에 접근이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예시 : myComponent.handleClick, myComponent.input&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1688299358300&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;MyComponent
    ref={(ref) =&amp;gt; { this.myComponent = ref; }}
/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8165051221932976&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;  React 기술면접 질문&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1. ref는 무엇이고, 언제 사용해야 하나요?&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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; ref는 reference의 줄임말로, DOM 요소에 직접 접근해야 할 때 주로 사용되며, 비제어 컴포넌트를 제어하는 경우가 여기에 해당한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;예를 들어, 입력창의 값을 state로 관리하게 되면 값이 바뀔 때마다 state가 바뀌고, 이로 인해 불필요한 리렌더링이 반복적으로 발생하게 된다. 이러한 문제점을 해결하기 위해 입력창에 ref를 달아주면 입력창의 값을 state로 관리하지 않더라도 외부에서 입력창의 값에 접근할 수 있게 된다.&lt;/span&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;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2. React 컴포넌트 내에서 id가 아니라 ref를 사용하는 이유는 무엇인가요?&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 data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; HTML에서 id는 유일해야 하는데, 컴포넌트를 재사용할 때마다 중복 id를 가진 DOM이 여러 개가 생겨나기 때문에 이를 방지하고자 ref를 사용한다. ref는 전역적으로 작동하지 않고 오직 컴포넌트 내부에서만 작동하기 때문에 이러한 문제점을 해결해 줄 수 있다.&lt;/span&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;b&gt;&amp;lt;/&amp;gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;끊임없이 성장하기 위해 공부한 내용을 글로 작성하고 있습니다. 틀린 부분이나 추가해야 할 부분이 있다면 언제든 댓글로 남겨주세요&lt;span style=&quot;background-color: #ffffff; text-align: left;&quot;&gt;❗️&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;도서 &amp;lt;리액트를 다루는 기술&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;https://ko.legacy.reactjs.org/docs/refs-and-the-dom.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.legacy.reactjs.org/docs/refs-and-the-dom.html&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tecoble.techcourse.co.kr/post/2021-05-15-react-ref/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://tecoble.techcourse.co.kr/post/2021-05-15-react-ref/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/React</category>
      <category>createRef</category>
      <category>DOM</category>
      <category>dom api</category>
      <category>JSX</category>
      <category>react</category>
      <category>ref</category>
      <category>state</category>
      <category>useRef</category>
      <category>리액트</category>
      <category>비제어 컴포넌트</category>
      <author>미주민</author>
      <guid isPermaLink="true">https://valueengine.tistory.com/71</guid>
      <comments>https://valueengine.tistory.com/71#entry71comment</comments>
      <pubDate>Sat, 1 Jul 2023 19:28:26 +0900</pubDate>
    </item>
  </channel>
</rss>