<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>코드로 대화하기</title>
    <link>https://talkwithcode.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 21 Aug 2026 13:55:03 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>아지송아지</managingEditor>
    <image>
      <title>코드로 대화하기</title>
      <url>https://tistory1.daumcdn.net/tistory/5047080/attach/aa310ca5cb8d4655b8504eac796b5204</url>
      <link>https://talkwithcode.tistory.com</link>
    </image>
    <item>
      <title>Typescript  typeof Array[number] 패턴 정리</title>
      <link>https://talkwithcode.tistory.com/101</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 typeof Array[number]에 대하여 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 이직을 하고 정신이 없어서 블로그 글도 못 올리고 1일 1 깃도 못했네요.&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;typeof Array[number]?&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1654390775543&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const names = [&quot;Song&quot;, &quot;James&quot;, &quot;Mike&quot;] as const;
type Name = typeof names[number];

// type Name: &quot;Song&quot;, &quot;James&quot;, &quot;Mike&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패턴은 위와 같이 생겼는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Name 타입을 정의할 때 유니온 타입을 사용하여 Song, James, Mike를 중복해서 적지 않은 것을 확인할 수 있습니다.&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;/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;h3 data-ke-size=&quot;size23&quot;&gt;문제점&lt;/h3&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;/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;b&gt;1. 타입을 정의하지 않는다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1654391573576&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const names = [&quot;Song&quot;, &quot;James&quot;, &quot;Mike&quot;];

// logName의 매개변수는 &quot;Song&quot;, &quot;James&quot;, &quot;Mike&quot; 셋 중 하나임을 가정
function logName(name: string){
    console.log(name);
}

logName('Song'); // o
logName('Tom'); // x&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애초에 타입을 적지 않으면 인자가 예상했던 값과 다른 값이 올 수도 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 타입을 선언한다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1654391772765&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const names = [&quot;Song&quot;, &quot;James&quot;, &quot;Mike&quot;];
type Name = 'Song' | 'James' | 'Mike';

function getName(name: Name){
    return names.find(n =&amp;gt; n===name)
}

logName('Song'); // o
logName('Tom'); // x&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입을 정의한다면 다른 값이 오는 것을 사전에 방지할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번의 문제점은 해결하였지만 이름들이 중복해서 사용됐습니다. 옳지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 세 개밖에 없어서 괜찮지만, 값이 늘어나면 불필요한 코드의 양도 늘어납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;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;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1654393208592&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const names = [&quot;Song&quot;, &quot;James&quot;, &quot;Mike&quot;] as const&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드부터 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654392185324&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const names = [&quot;Song&quot;, &quot;James&quot;, &quot;Mike&quot;];
// const names: string[]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 as const를 사용하지 않은 names의 타입 string[]입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희는 초기에 선언된 값 이외에는 더 추가되지 않을 것이기 때문에 이것을 불변한 값으로 바꿔줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;string[] -&amp;gt; readonly [&quot;Song&quot;, &quot;James&quot;, &quot;Mike&quot;] 이렇게 말이죠&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;b&gt;Const assertions&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;typescript 3.4 버전에서 추가된 기능인 Const assertions를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선언한 변수들을 마치 const처럼 만들어 줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 가지 예시를 들어보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654392668319&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const name = &quot;Song&quot;;
// const name: &quot;Song&quot;

let name2 = &quot;Song&quot;
// let name2: string

let name3 = &quot;Song&quot; as const
// let name3: &quot;Song&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const로 변수를 선언하면 타입은 &quot;song&quot;이지만 let으로 선언하면 string이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;as const를 사용하면 let으로 선언하였어도 타입은 &quot;song&quot;이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654392829911&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const abcd = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;];
// const abcd: string[]
abcd.push(&quot;e&quot;); // o

const ABCD = [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;] as const;
// const ABCD: readonly [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;]
ABCD.push(&quot;E&quot;); // Property 'push' does not exist on type 'readonly [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;]'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const로 선언한 객체는 객체 내부의 타입들이 넓은 범위의 타입으로 추론됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const assertion을 사용하면 그 범위를 좁혀줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654393365559&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;type Name = typeof names[number];
// type Name: &quot;Song&quot; | &quot;James&quot; | &quot;Mike&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;size16&quot;&gt;typeof names[number]를 사용하여 배열 안에 있는 숫자로 이루어진 모든 index 값을 가져와 유니온 타입으로 만들어줍니다. (index signature 문법)&amp;nbsp; 이로 인하여 똑같은 값을 한번 더 사용하지 않고도 유니온 타입을 만들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1654393833290&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const people = [
  { age: 20, name: 'Song' },
  { age: 21, name: 'James' },
  { age: 22, name: 'Mike' }
] as const

type Name = typeof animals[number]['name']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열 안에 오브젝트가 있을 경우 다음과 같이 사용하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 : &lt;a href=&quot;https://steveholgado.com/typescript-types-from-arrays/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://steveholgado.com/typescript-types-from-arrays/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Front-end/Typescript</category>
      <author>아지송아지</author>
      <guid isPermaLink="true">https://talkwithcode.tistory.com/101</guid>
      <comments>https://talkwithcode.tistory.com/101#entry101comment</comments>
      <pubDate>Sun, 5 Jun 2022 10:58:47 +0900</pubDate>
    </item>
    <item>
      <title>1년차 프론트엔드의 우당탕탕 이직기</title>
      <link>https://talkwithcode.tistory.com/100</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오랜만에 제 이야기를 해보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3월 11일 퇴사 후 5월 16일 새로운 회사에 입사하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 이직 회고 글들을 찾아보았는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 회사를 하나씩 리뷰하기보다는 전체적인 이직 과정을 말씀드리려하려 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;입사 지원&lt;/h3&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;/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://talkwithcode.tistory.com/77?category=1021262&quot;&gt;이전 글&lt;/a&gt;에서 처음 취업을 할 때는 100곳 이상 무지성으로 입사 지원을 했다고 말했었는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 이직은 아래 기준을 정하여 꼭 가고 싶은 회사만 지원하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 서비스 회사에 가서 하나의 서비스를 깊게 파고들고 싶다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- si 회사에서 정말 많은 것을 배웠고 소중한 경험들을 하였지만, si 특성상 심도 깊은 개발은 불가능하다고 판단하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 제작한 프로젝트가 사람들에게 어떤 기여를 하고있고 서비스가 운영되는 과정을 지켜보고 싶었습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 도전과제가 많은 회사에 가고 싶다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 회사에 들어가 똑같은 작업만 반복하고 유지 보수만 하는 것이 아닌 도전과제를 깨며 성장하고 싶습니다. 그 속에서 많은 것을 깨닫고 성취감을 얻는게 목표입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 저는 코딩 테스트보다는 과제 테스트에 더 자신이 있어 과제 트스트를 보는 회사에 주로 지원하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입사 지원은 원티드, 회사 사이트, 프로그래머스 프론트엔드 데브 매칭을&amp;nbsp; 이용하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그래머스 데브 매칭 10곳을 포함하여 총 20곳 지원하였습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많이 지원한 것 같기도 하네요...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;프로그래머스 데브 매칭&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-05-20 오후 10.27.33.png&quot; data-origin-width=&quot;1704&quot; data-origin-height=&quot;822&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z43WY/btrCHDVQyWc/bMGxiMsPliQTt8BmevQl71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z43WY/btrCHDVQyWc/bMGxiMsPliQTt8BmevQl71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z43WY/btrCHDVQyWc/bMGxiMsPliQTt8BmevQl71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ43WY%2FbtrCHDVQyWc%2FbMGxiMsPliQTt8BmevQl71%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;678&quot; height=&quot;327&quot; data-filename=&quot;스크린샷 2022-05-20 오후 10.27.33.png&quot; data-origin-width=&quot;1704&quot; data-origin-height=&quot;822&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지인이 추천해줘서 데브 매칭에 지원하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대기업과 유명 스타트업을 한 번에 지원해 볼 수 있는 좋은 기회였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 하필 프로그래머스 과제 테스트를 보는 날 제가 코로나에 걸려 열이 38.9도까지 올라가서 컨디션이 매우 안 좋았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머리가 너무 아파 테스트를 보지 말까 고민하였지만 떨어질때 떨어지더라고 한번 도전해보자 라는 생각에 참여하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_4836.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDBCo7/btrCJSKAmtA/biGUnlXjyxA1aKqxoqeD9K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDBCo7/btrCJSKAmtA/biGUnlXjyxA1aKqxoqeD9K/img.jpg&quot; data-alt=&quot;코로나...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDBCo7/btrCJSKAmtA/biGUnlXjyxA1aKqxoqeD9K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDBCo7%2FbtrCJSKAmtA%2FbiGUnlXjyxA1aKqxoqeD9K%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;199&quot; height=&quot;265&quot; data-filename=&quot;IMG_4836.JPG&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;코로나...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 과제에 통과하여 지원한 몇몇의 회사들에게 연락이 왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(코로나를 핑계로 테스트를 안 봤으면 정말 후회를 많이 했을 것 같습니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;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;/h3&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;데브 매칭 회사들 포함 12개의 회사에서 서류에 합격하였습니다.&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;과제 테스트를 진행하며 제 코드를 돌아보게 되었고 2개의 회사에서 코드 피드백을 받았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나름 제 코드에 자신이 있었지만, 테스트를 보며 많이 반성하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 제 코드의 퀄리티는 좋지 못하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전달받은 피드백과 과제 테스트를 위해 받았던 여러 회사들의 코드를 보며 부족함을 느꼈습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;합격 여부와 상관없이 피드백과 해당 코드들을 분석하며 제 코드의 문제점을 파악하였습니다. 몇 개의 프로젝트는 직접 리팩토링도 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;h3 data-ke-size=&quot;size23&quot;&gt;기술 면접&lt;/h3&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;그렇게 9개의 회사와 기술 면접을 진행하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기술 면접을 보며 제가 CS 지식이 부족하다는 것을 많이 느꼈습니다.&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;이때는 개인 프로젝트를 진행하기보다는 CS를 공부하며 부족했던 이론을 다졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글에 &quot;프론트엔드 면접 질문&quot;을 검색하여 나온 내용들을 공부하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접을 위해 공부했던 것도 있지만 공부를 하면 할수록 지금까지 경험했던 내용들이 더 단단해지는 느낌을 받았습니다.&lt;/p&gt;
&lt;p 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;IMG_4835 복사본.jpg&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdVhOb/btrCIH362cF/TSr19oiHXLQZ3Hk6NumTg1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdVhOb/btrCIH362cF/TSr19oiHXLQZ3Hk6NumTg1/img.jpg&quot; data-alt=&quot;기술 면접을 준비하면서&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdVhOb/btrCIH362cF/TSr19oiHXLQZ3Hk6NumTg1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdVhOb%2FbtrCIH362cF%2FTSr19oiHXLQZ3Hk6NumTg1%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;431&quot; height=&quot;323&quot; data-filename=&quot;IMG_4835 복사본.jpg&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;750&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기술 면접을 준비하면서&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;최종 면접&lt;/h3&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;7개의 회사가 좋게 봐주셔서 최종 면접을 진행하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저의 목표와 경험, 회사의 목표들 생각하며 최종 면접을 준비하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식상한 말일 수도 있지만 면접은 꾸며내기보다는 제 자신을 솔직하게 보여주었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6개의 회사에 합격하였고 1개의 회사에서 불합격 통보를 받았습니다.&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;6개의 회사 중 정말 고민을 많이 했었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 도전 과제가 넘치는 회사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 개발에 몰입할 수 있는 회사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 끊임없이 성장이 가능한 회사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 요소들 말고도 여러 가지를 생각하며 결국 하나의 회사를 선택하였습니다.&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;/h3&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;2개월간 이직을 위해 시간을 투자하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이직을 준비하며 많은 경험하였는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과제와 기술면접을 준비할 때는 놓치고 있었던 기술적 디테일을 배웠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기술/최종 면접을 진행할 때는 여러 회사들의 개발자, HR담당자, 대표님들을 만나며 진솔한 얘기를 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그분들이 어떠한 생각을 가지고 있는지 같이 공감하였고, 기술 외적으로도 면접을 통해 배우며 성장한 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 사람들과 소통하는 것을 좋아하여 개인적으로 면접을 볼 때가 이직하면서 가장 재밌었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 글로 정리하고 나니 생각보다 2개월 동안 의미 있는 삶을 산 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;748&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LwaVN/btrCHPhw8sm/FPhqVepF0gLx0IR6rJFlU0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LwaVN/btrCHPhw8sm/FPhqVepF0gLx0IR6rJFlU0/img.jpg&quot; data-alt=&quot;꼭 한번 넣어보고 싶었던 짤&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LwaVN/btrCHPhw8sm/FPhqVepF0gLx0IR6rJFlU0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLwaVN%2FbtrCHPhw8sm%2FFPhqVepF0gLx0IR6rJFlU0%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;664&quot; height=&quot;497&quot; data-origin-width=&quot;748&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;꼭 한번 넣어보고 싶었던 짤&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 직장을 준비하시는 모든 분들 화이팅입니다!!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 좋은 곳 가실 겁니다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 겨우 1년 차 주니어 개발자가 이런 말을 하니 부끄럽네요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;h3 data-ke-size=&quot;size23&quot;&gt;이직 후 일주일&lt;/h3&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 회사인 만큼 꿈같은 시간이었습니다. 하지만 기술적으로 무지함을 뼈저리게 느꼈습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에도 포기하지 않고 끝까지 달려보려고 합니다. 지켜봐 주시면 감사하겠습니다.&lt;/p&gt;</description>
      <category>개발일지</category>
      <author>아지송아지</author>
      <guid isPermaLink="true">https://talkwithcode.tistory.com/100</guid>
      <comments>https://talkwithcode.tistory.com/100#entry100comment</comments>
      <pubDate>Sat, 21 May 2022 00:09:02 +0900</pubDate>
    </item>
    <item>
      <title>Next.js getServerSideProps, getStaticProps, getStaticPaths</title>
      <link>https://talkwithcode.tistory.com/99</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 pre-rendering과 data fetching에 관련된 지식들을 알아보겠습니다.&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;Pre-rendering?&lt;/h3&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;nextjs에서 가장 중요한 개념 중 하나인 Pre-rendering을 먼저 얘기해보겠습니다.&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;nextjs는 클라이언트 측에서&amp;nbsp; 자바스크립트로 모든 작업을 실행하는 대신 &lt;u&gt;&lt;b&gt;각 페이지에 대한 HTML을 미리 생성&lt;/b&gt;&lt;/u&gt;하는데 이것이 pre-redering(사전 렌더링)입니다. 사전 렌더링을 하면 &lt;u&gt;렌더링 성능과 SEO가 향상&lt;/u&gt;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 기본적으로 next.js는 모든 페이지를 사전 렌더링 합니다.&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Yjiiz/btrCbnEtu1G/KTy34ceTRSrWXegTGxjVa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Yjiiz/btrCbnEtu1G/KTy34ceTRSrWXegTGxjVa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Yjiiz/btrCbnEtu1G/KTy34ceTRSrWXegTGxjVa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYjiiz%2FbtrCbnEtu1G%2FKTy34ceTRSrWXegTGxjVa1%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;1269&quot; height=&quot;630&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;688&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;Pre-rendering을 하지 않으면, 초기에는 렌더링이 되지 않았다가 자바스크립트가 로드되면 페이지 요소들이 채워집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnr1Dp/btrB8YeoisC/LHUfc6zmKggKkSy7eAowi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnr1Dp/btrB8YeoisC/LHUfc6zmKggKkSy7eAowi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnr1Dp/btrB8YeoisC/LHUfc6zmKggKkSy7eAowi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbnr1Dp%2FbtrB8YeoisC%2FLHUfc6zmKggKkSy7eAowi1%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;1362&quot; height=&quot;810&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;824&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;반면 Pre-rendering이 있다면 사전에 만들어진 HTML 파일을 보여주고 이후 자바스크립트가 로드되면 Hydration이 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 시점에서 &amp;lt;Link /&amp;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;* Hydration이란, 브라우저가 모두 로드되었을 때 사용자와 상호작용할 수 있는 상태를 의미합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Pre-rendering의 종류&lt;/h3&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;Pre-rendering은 &lt;u&gt;&lt;b&gt;Static Generation과 Server-side Rendering&lt;/b&gt;&lt;/u&gt; 두 가지 종류가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 둘의 차이점은 &lt;u&gt;&lt;b&gt;언제 HTML 파일이만들어지는가&lt;/b&gt;&lt;/u&gt; 입니다. 중요한 포인트는 &lt;b&gt;&quot;언제&quot;&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;Static Generation은 &lt;u&gt;&lt;b&gt;빌드 시점에서 HTML&lt;/b&gt;&lt;/u&gt;이 만들어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Server-side Rendering은 &lt;u&gt;&lt;b&gt;매 요청마다 HTML&lt;/b&gt;&lt;/u&gt;이 새롭게 만들어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/018Cn/btrCcFkBjyQ/9YuhuQpcuu1tOqdMAYKk91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/018Cn/btrCcFkBjyQ/9YuhuQpcuu1tOqdMAYKk91/img.png&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;744&quot; data-is-animation=&quot;false&quot; style=&quot;width: 51.211%; margin-right: 10px;&quot; data-widthpercent=&quot;51.81&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/018Cn/btrCcFkBjyQ/9YuhuQpcuu1tOqdMAYKk91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F018Cn%2FbtrCcFkBjyQ%2F9YuhuQpcuu1tOqdMAYKk91%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;1386&quot; height=&quot;744&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ASrT2/btrB6Q9ckwL/ImmmgDC2wF4pdUJBmPvcs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ASrT2/btrB6Q9ckwL/ImmmgDC2wF4pdUJBmPvcs1/img.png&quot; data-origin-width=&quot;1386&quot; data-origin-height=&quot;800&quot; data-is-animation=&quot;false&quot; style=&quot;width: 47.6262%;&quot; data-widthpercent=&quot;48.19&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ASrT2/btrB6Q9ckwL/ImmmgDC2wF4pdUJBmPvcs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FASrT2%2FbtrB6Q9ckwL%2FImmmgDC2wF4pdUJBmPvcs1%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;1386&quot; height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;좌측 : Static Generation&amp;nbsp; 우측 : Server-side Rendering&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Static Generation&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자의 요청과는 별개로 미리 만들어두어도 괜찮다면 이 방법이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한번 만들어지면 CDN을 통해 재사용하기 때문에 서버에서 매번 요청하는 것보다 빠릅니다.&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;공식 문서에 나와있는 Static Generation 페이지 예시입니다.&lt;br /&gt;* Marketing pages - 마케팅 페이지&lt;br /&gt;* Blog posts - 블로그 포스트&lt;br /&gt;* E-commerce product listings - 제품 목록&lt;br /&gt;* Help and documentation - 도움말, 문서&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Server-side Rendering&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;속도는 느릴 수 있지만, 매번 서버에 요청을 하여 렌더링 하기 때문에 해당 페이지는 항상 최신 상태를 유지합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;next.js는 data fetching에 있어 (데이터를 가져오는 데 있어) 예전에는 getInitialProps를 사용하였지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9.3 버전부터는&lt;u&gt;getStaticProps, getStaticPaths, getServerSideProp&lt;/u&gt;&lt;span&gt;&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;&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;h3 data-ke-size=&quot;size23&quot;&gt;1. getStaticProps&lt;/h3&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;u&gt;&lt;b&gt;빌드 시에만 서버에서 데이터&lt;/b&gt;&lt;/u&gt;를 가져와 html과 json 파일을 미리 만듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 서버에서 데이터가 바뀌어도 다시 통신을 하지 않기 때문에 주의하셔야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;html, json 파일 모두 퍼포먼스 향상을 위해 CDN에 캐싱합니다.&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;b&gt;사용법&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1652602179129&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const Detail = ({ data }) =&amp;gt; {
  return &amp;lt;&amp;gt;&amp;lt;/&amp;gt;;
};

export async function getStaticProps(context) {
  const data = await fetch(&quot;--&quot;);
  return {
    props: { data }, // 페이지 컴포넌트에 props로 넘길 것
  };
}

export default Detail;&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;2. getStaticPaths&lt;/h3&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;getStaticProps와 동일하게 빌드시에 서버에서 데이터를 받아옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차이점이 있다면 getStaticPaths는 Dynamic Routes 에서 사용됩니다.&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;b&gt;사용법&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1652603105632&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// [id].js
const Detail = ({ data }) =&amp;gt; {
  return &amp;lt;&amp;gt;&amp;lt;/&amp;gt;;
};

export async function getStaticPaths() {
  return {
    paths: [
      { params: { id: &quot;100&quot; } },
      { params: { id: &quot;200&quot; } },
      { params: { id: &quot;300&quot; } }
    ],
    fallback: true // false or 'blocking'
  };
}

export async function getStaticProps(context) {
  const data = await fetch(&quot;--&quot;);
  return {
    props: { data }, // 페이지 컴포넌트에 props로 넘길 것
  };
}

export default Detail;&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;u&gt;&lt;b&gt;getStaticProps와 반드시 같이 사용&lt;/b&gt;&lt;/u&gt;하며 getServerSideProps와는 같이 사용할 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;path로 설정된 경로들은 빌드시 미리 만들어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시는 id값이 100, 200, 300인 페이지를 미리 생성합니다.&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;fallback이&lt;u&gt; false일 경우 path에서 설정하지 않은 경로들은 대응하지 않습니다.&lt;/u&gt; 즉 404페이지가 뜹니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;fallback이 &lt;u&gt;true일 경우에는 백그라운드에서 정적 파일로 htm과 json을 생성하여 pre-render목록에 추가합니다.&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;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;h3 data-ke-size=&quot;size23&quot;&gt;3. getServerSideProps&lt;/h3&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;서버 측에서 프리렌더를 하여 반환 데이터를 getServerSideProps로 페이지에 전달합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;빌드와 상관없이 &lt;/b&gt;&lt;b&gt;&lt;u&gt;매&lt;/u&gt; 요청마다 서버에서 데이터&lt;/b&gt;&lt;/u&gt;를 가져옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서 계속 데이터를 가져오기 때문에 정보들은&amp;nbsp;&lt;u&gt;&lt;b&gt;항상 최신 상태로 유지&lt;/b&gt;&lt;/u&gt;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 제품 상세 페이지, 관리자 페이지와 같은 곳들에서 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;사용법&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1652442748662&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const Detail = ({ data }) =&amp;gt; {
  return &amp;lt;&amp;gt;&amp;lt;/&amp;gt;;
};

export async function getServerSideProps(context) {
  const data = await fetch(&quot;--&quot;);
  return {
    props: { data }, // 페이지 컴포넌트에 props로 넘길 것
  };
}

export default Detail;&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;b&gt;return&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드에는 props만 반환하고 있지만 getServerSideProps는 세 가지의 반환 값을 가집니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;props : 컴포넌트로 리턴할 값&lt;/li&gt;
&lt;li&gt;redirect : 페이지 접속 시 지정한 경로로 리디렉션 시키기 위해 사용되는 값
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;{ destination : string, permanent : boolean} 형태입니다.&lt;/li&gt;
&lt;li&gt;status 코드가 필요하거나 변경해야 할 때는 permanent 대신 statusCode를 사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;notFound : boolean 값입니다. true일 경우 404 status와 에러 페이지를 보여줍니다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&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;b&gt;context&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;context 객체를 인자로 받으며 아래 정보들을 담고 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;params: 다이나믹 라우트 페이지면 해당 데이터를 가져온다.&lt;/li&gt;
&lt;li&gt;req: Request 정보&lt;/li&gt;
&lt;li&gt;res: Response 정보&lt;/li&gt;
&lt;li&gt;query: 쿼리 스트링&lt;/li&gt;
&lt;li&gt;preview: preview mode 사용 유무&lt;/li&gt;
&lt;li&gt;previewData: preview mode 사용 시 전달된 데이터&lt;/li&gt;
&lt;li&gt;resolvedUrl: 짧은 URL
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;ex)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://localhost:3000/detail/100&quot;&gt;http://localhost:3000/detail/100&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;-&amp;gt; /detail/740&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;locale: 현재 locale 정보&lt;/li&gt;
&lt;li&gt;locales: 지원되는 모든 locale 정보&lt;/li&gt;
&lt;li&gt;defaultLocale: 기본 locale 정보&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;preview mode에 대한 지식은 아직 부족하여 공부를 더 하고 글을 올리겠습니다.&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;/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;a href=&quot;https://nextjs.org/learn/basics/data-fetching/pre-rendering&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nextjs.org/learn/basics/data-fetching/pre-rendering&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching/get-static-paths&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nextjs.org/docs/basic-features/data-fetching/get-static-paths&lt;/a&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;</description>
      <category>Front-end/Nextjs</category>
      <author>아지송아지</author>
      <guid isPermaLink="true">https://talkwithcode.tistory.com/99</guid>
      <comments>https://talkwithcode.tistory.com/99#entry99comment</comments>
      <pubDate>Sun, 15 May 2022 18:06:27 +0900</pubDate>
    </item>
    <item>
      <title>Next.js 페이지 이동 Link, Router</title>
      <link>https://talkwithcode.tistory.com/98</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 글에서 다이나믹 라우팅에 대해 살펴보았는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 넥스트에서 페이지 전환할 때 사용하는 방법인 Link, Router에 대하여 알아보겠습니다.&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;페이지를 이동할 때 a태그를 사용한다면 전체 새로고침이 되며 다시 정보들을 새롭게 가져오게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 흰 화면이 보일 수도 있고 매번 통신을 새롭게 하다 보니 사용자 경험 측면에서도 떨어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Link&lt;/h3&gt;
&lt;pre id=&quot;code_1652152868216&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Link from &quot;next/link&quot;;
...
// path
&amp;lt;Link href={`/detail/${id}`}&amp;gt;
  &amp;lt;a&amp;gt;item name&amp;lt;/a&amp;gt;
&amp;lt;/Link&amp;gt;

// object
&amp;lt;Link href={{ pathname: &quot;/about&quot;, query: { name: &quot;song&quot; } }}&amp;gt;
    &amp;lt;a&amp;gt;item name&amp;lt;/a&amp;gt;
&amp;lt;/Link&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Link 태그에 &lt;u&gt;href 속성을 추가&lt;/u&gt;하여 가고자 하는 주소를 넣습니다. (a 태그의 href와 동일합니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 안쪽에는 a 태그로 감싸줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* className과 같은 속성들을 a 태그에 추가합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 페이지 &lt;u&gt;새로고침 없이&lt;/u&gt; 페이지가 전환됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Link는 Client-side navigation으로 자바스크립트로 페이지 전환이 이루어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 navigation보다 빠르며 SPA의 특성을 유지합니다.&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;프러덕션 빌드에서 Link 요소가 뷰포트에 나타나면 넥스트는 백그라운드에서 해당 페이지의 코드를 자동으로 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Link와 연결된 페이지를 미리 로드하여 링크 클릭 시 빠르게 전환이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 &lt;u&gt;&lt;b&gt;pre-fetching&lt;/b&gt;&lt;/u&gt; 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;a 태그가 커스텀 컴포넌트일 경우?&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Next.js 공식 문서 - next/link 부분&lt;br /&gt;&lt;br /&gt;If the child of `Link` is a custom component that wraps an `&amp;lt;a&amp;gt;` tag, you must add `passHref`&amp;nbsp;to `Link`. This is necessary if you&amp;rsquo;re using libraries like styled-components. Without this, the `&amp;lt;a&amp;gt;` tag will not have the `href`&amp;nbsp;attribute, which hurts your site's accessibility and might affect SEO&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 styled-components와 같이 a 태그가 커스텀 컴포넌트일 경우 Link 태그에 passHref 속성을 주어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 속성이 없을 경우 a 태그에는 href 속성이 없어 접근성과 SEO에 영향을 줍니다.&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;h3 data-ke-size=&quot;size23&quot;&gt;2. Router&lt;/h3&gt;
&lt;pre id=&quot;code_1652154167428&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import Link from &quot;next/link&quot;;
import Router, { useRouter } from &quot;next/router&quot;;
...
const router = useRouter();
...
// Router
&amp;lt;div onClick={() =&amp;gt; Router.push(&quot;/about&quot;)}&amp;gt;Router&amp;lt;/div&amp;gt;

// router
&amp;lt;div onClick={() =&amp;gt; router.push(&quot;/about&quot;)}&amp;gt;router&amp;lt;/div&amp;gt;

// object
&amp;lt;div
    onClick={() =&amp;gt;
      router.push({ pathname: &quot;/about&quot;, query: { name: &quot;song&quot; } })
    }
&amp;gt;
	router
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라우터를 이용하여 페이지를 전환합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react-router-dom의 history.push()와 유사합니다.&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;* 크롤러가 링크를 감지하지 못하여 SEO가 좋지 않을 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &amp;lt;Link&amp;gt;는 클릭 시 바로 페이지가 전환되지만 라우터는 &lt;u&gt;로직을 처리 후 원하는 시점에서 전환이 가능&lt;/u&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;u&gt;외부 URL을 사용할 경우 window.location 혹은 a 태그를 사용해야 합니다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;router에는 push 말고도 많은 기능들이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그중 몇 가지 소개해드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. router.push&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지가 이동되며 히스토리 스택이 쌓입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Main -&amp;gt; Login -&amp;gt; List에서 마이페이지로 push 하면 Main -&amp;gt; Login -&amp;gt; List -&amp;gt; Mypage&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;b&gt;2. router.replace&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지가 이동되며 히스토리 스택이 교체됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Main -&amp;gt; Login -&amp;gt; List 에서 마이페이지로 replace 하면 Main -&amp;gt; Login -&amp;gt; Mypage&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;b&gt;3. router.back&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒤로 가는 기능이며 &quot;window.history.back()&quot;과 동일합니다.&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;b&gt;4. router.reload&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로고침 기능이며 &quot;window.location.reload()&quot;와 동일합니다.&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;/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;br /&gt;&lt;a href=&quot;https://nextjs.org/docs/api-reference/next/link&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nextjs.org/docs/api-reference/next/link&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/api-reference/next/router#userouter&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nextjs.org/docs/api-reference/next/router#userouter&lt;/a&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;</description>
      <category>Front-end/Nextjs</category>
      <author>아지송아지</author>
      <guid isPermaLink="true">https://talkwithcode.tistory.com/98</guid>
      <comments>https://talkwithcode.tistory.com/98#entry98comment</comments>
      <pubDate>Tue, 10 May 2022 14:59:06 +0900</pubDate>
    </item>
    <item>
      <title>Next.js Dynamic Routes를 알아보자</title>
      <link>https://talkwithcode.tistory.com/97</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 Next.js의 Dynamic Routes, Error Page에 대하여 알아보겠습니다.&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;리액트에서는 react-router-dom을 설치하고 여러 세팅들을 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 넥스트는 &lt;u&gt;폴더와 파일 단위로 라우팅&lt;/u&gt;을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pages 안에 있는 폴더와 파일들을 읽어 라우팅을 하고 url 주소가 생성됩니다.&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;1. pages, dynamic routes&lt;/h3&gt;
&lt;pre id=&quot;code_1652087661678&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pages
└── about.tsx   -&amp;gt; localhost:3000/about&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pages 폴더안에 about.tsx가 있다면 따로 더 설정할 필요 없이 url 주소는 &quot;localhost:3000/about&quot; 이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1652087587977&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pages
├── detail
│   └─ [id].tsx   -&amp;gt; localhost:3000/detail/1, localhost:3000/detail/2 ...
└── about.tsx   -&amp;gt; localhost:3000/about&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다이나믹 라우트는 폴더를 만든 후 그 안에 위와 같이 만들면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;&quot;next/router&quot;를 활용하면 Path Variable과 Query Parameter들을 가져올 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1652088411868&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { useRouter } from 'next/router';
...
const router = useRouter();
console.log(router.query);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;localhost:3000/detail/1 -&amp;gt; {id:'1'}&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;localhost:3000/detail/100 -&amp;gt; {id:'100'}&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;localhost:3000/detail/100?name=song -&amp;gt; { name:'song', id:'100'}&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &lt;u&gt;&lt;b&gt;쫌 더 깊은 depth&lt;/b&gt;&lt;/u&gt;를 사용해 볼 수는 없을까&amp;nbsp; 궁금했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;localhost:3000/detail/100/200/300 이렇게 말이죠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 [id].tsx 처럼 하면 에러 페이지가 뜹니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일명을 &lt;b&gt;[...id].tsx&lt;/b&gt;로 바꾸면 해결됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라우터의 쿼리는 값들을 배열로 반환합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1652089233105&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// localhost:3000/detail/100/200

console.log(router.query); // {id: ['100', '200']}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 시간에는 페이지 간 이동을 해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 :&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/routing/dynamic-routes&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nextjs.org/docs/routing/dynamic-routes&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Front-end/Nextjs</category>
      <author>아지송아지</author>
      <guid isPermaLink="true">https://talkwithcode.tistory.com/97</guid>
      <comments>https://talkwithcode.tistory.com/97#entry97comment</comments>
      <pubDate>Mon, 9 May 2022 18:47:31 +0900</pubDate>
    </item>
    <item>
      <title>Next.js  _app과 _document에 대하여</title>
      <link>https://talkwithcode.tistory.com/96</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 Next.js의 _app과 _document에 대하여 알아보겠습니다.&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;next.js를 처음 설치하면 pages 폴더 안에 _app파일이 보이실 겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_document가 없을 경우 따로 만드시면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-05-09 오후 12.31.34.png&quot; data-origin-width=&quot;317&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Jtgq3/btrBEenBroP/uRqm6Vu0hDMSExtzp1UWY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Jtgq3/btrBEenBroP/uRqm6Vu0hDMSExtzp1UWY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Jtgq3/btrBEenBroP/uRqm6Vu0hDMSExtzp1UWY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJtgq3%2FbtrBEenBroP%2FuRqm6Vu0hDMSExtzp1UWY0%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;317&quot; height=&quot;130&quot; data-filename=&quot;스크린샷 2022-05-09 오후 12.31.34.png&quot; data-origin-width=&quot;317&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 타입스크립트여서 .tsx 입니다.&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;1. _app&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 먼저 실행되는 컴포넌트로,&amp;nbsp;모든 페이지는 _app을 통해 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 특성들이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 페이지가 변경되어도 레이아웃과 상태 값을 유지합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &quot;componentDidCatch&quot;를 통해 에러 핸들링이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 페이지에 추가적인 데이터를 삽입할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Global CSS는 이곳에 추가합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 헤더와 푸터같이 공통적으로 사용하는 레이아웃은 이곳에 추가합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1652067666706&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import '../styles/globals.css'
import type { AppProps } from 'next/app'

function MyApp({ Component, pageProps }: AppProps) {
  return &amp;lt;Component {...pageProps} /&amp;gt;
}

export default MyApp&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적인 _app.tsx의 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;props로 Component와 pageProps를 받아오는데요.&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;b&gt;Component&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;Component는 현재 페이지를 의미합니다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지가 변경되면 Component가 변경됩니다.&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;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&quot;http://localhost:3000/&quot;은 index.tsx를 가리키며, &quot;http://localhost:3000/about&quot;은 about 컴포넌트를 가리킵니다.&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;b&gt;pageProps&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;getInitialProps, getStaticProps, getServerSideProps 를 통해 가져온 초기 속성값을 의미합니다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 값들이 없다면 빈 객체를 반환합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1652068992543&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// about.tsx
...
export async function getStaticProps() {
  const test = &quot;Hello&quot;;
  return {
    props: {
      test,
    },
  };
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1652069149443&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;_app.tsx
...
function MyApp({ Component, pageProps }: AppProps) {
  console.log(pageProps); // {test: 'Hello'}
  return &amp;lt;Component {...pageProps} /&amp;gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 위와 같이 about.tsx에서 getStaticProps를 사용한다고 했을 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_app.tsx에서 pageProps를 콘솔로 찍으면 {test: 'Hello'}가 출력됩니다.&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;b&gt;_app - getStaticProps, getServerSideProps&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;u&gt;_app은 getStaticProps와 getServerSideProps를 지원하지 않습니다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;_app - getInitialProps&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* _app에서 getInitialProps를 사용한다면 Automatic Static Optimization이 비활성화되어 모든 페이지가 서버 사이드 렌더링 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1652077725661&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import App from 'next/app'

function MyApp({ Component, pageProps }) {
  return &amp;lt;Component {...pageProps} /&amp;gt;
}

MyApp.getInitialProps = async (appContext) =&amp;gt; {
   const appProps = await App.getInitialProps(appContext);
   return { ...appProps }
 }

export default MyApp&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Custom&amp;nbsp;App&lt;br /&gt;When you add&amp;nbsp;getInitialProps&amp;nbsp;in your custom app, you must&amp;nbsp;import App from &quot;next/app&quot;, call&amp;nbsp;App.getInitialProps(appContext)&amp;nbsp;inside&amp;nbsp;getInitialProps&amp;nbsp;and merge the returned object into the return value.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_app에서 getInitialProps에서 사용할 때는 getInitialProps 안에 App을 통해 불러온 App.getInitialProps를 통해 반환해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. _document&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 페이지에서 공통적으로 사용하는 html, head(meta) 혹은 body 태그 안에 들어가는 커스텀할 때 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 서버에서만 렌더링 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. onClick 같은 이벤트나 CSS는 사용하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 &lt;u&gt;어플리케이션 로직은 넣으면 안 됩니다.&lt;/u&gt; 필요하다면 _app에서 넣어야 합니다.&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;3. 반드시 HTML, Head, Main, NextScript를 포함해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1652079535098&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    &amp;lt;Html&amp;gt;
      &amp;lt;Head /&amp;gt;
      &amp;lt;body&amp;gt;
        &amp;lt;Main /&amp;gt;
        &amp;lt;NextScript /&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/Html&amp;gt;
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적인 _document 구조입니다.&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;lt;head&amp;gt;만 _document에 넣으며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;title 같이 페이지마다 바뀌는 것들은 각 페이지 별로 넣어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_document 에서는 &quot;next/document&quot;의 Head를 사용하며 그 외 컴포넌트에서는 &quot;next/head&quot;의 Head를 사용합니다.&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;b&gt;_document - getStaticProps, getServerSideProps&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&lt;span&gt;&amp;nbsp;&lt;/span&gt;_documnet 또한&amp;nbsp; getStaticProps와 getServerSideProps를 지원하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;정리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 페이지는 _app과 _document 를 거쳐갑니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_app 이후에 _document가 실행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_app은 어플리케이션 로직, 글로벌 스타일 등을 다룹니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_document는 HTML 마크업 자체에 집중합니다.&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/advanced-features/custom-app&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nextjs.org/docs/advanced-features/custom-app&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nextjs.org/docs/advanced-features/custom-document&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nextjs.org/docs/advanced-features/custom-document&lt;/a&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;</description>
      <category>Front-end/Nextjs</category>
      <author>아지송아지</author>
      <guid isPermaLink="true">https://talkwithcode.tistory.com/96</guid>
      <comments>https://talkwithcode.tistory.com/96#entry96comment</comments>
      <pubDate>Mon, 9 May 2022 16:27:53 +0900</pubDate>
    </item>
    <item>
      <title>Next.js 시작하기 (typescript)</title>
      <link>https://talkwithcode.tistory.com/95</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 nextjs를 시작해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입스크립트로 프로젝트를 진행하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 초기 세팅&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;설치&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1651802550206&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npx create-next-app --ts
# or
yarn create next-app --typescript&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 입력하면 &quot;What is your project named?&quot;와 함께 프로젝트 이름을 입력하라고 나옵니다.&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;b&gt;실행&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1651802754638&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 개발자 모드
npm run dev

# 릴리즈 모드
npm run build
npm run start&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-05-09 오후 12.19.53.png&quot; data-origin-width=&quot;3502&quot; data-origin-height=&quot;1928&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2viF5/btrBEc4luza/rxb2ExrjmCW0FFp0wuPHn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2viF5/btrBEc4luza/rxb2ExrjmCW0FFp0wuPHn0/img.png&quot; data-alt=&quot;http://localhost:3000/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2viF5/btrBEc4luza/rxb2ExrjmCW0FFp0wuPHn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2viF5%2FbtrBEc4luza%2Frxb2ExrjmCW0FFp0wuPHn0%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;650&quot; height=&quot;358&quot; data-filename=&quot;스크린샷 2022-05-09 오후 12.19.53.png&quot; data-origin-width=&quot;3502&quot; data-origin-height=&quot;1928&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;http://localhost:3000/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ESLint, Prettier세팅&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ESLint와 Prettier 세팅을 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://talkwithcode.tistory.com/93&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;저번 글&lt;/a&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;.eslintrc&lt;/p&gt;
&lt;pre id=&quot;code_1651803146907&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module.exports = {
  root: true,

  env: {
    browser: true,
    node: true,
    es2021: true,
  },

  parser: '@typescript-eslint/parser',
  parserOptions: {
    sourceType: 'module',
    ecmaVersion: 'es5',
    ecmaFeatures: { jsx: true },
  },

  extends: ['eslint:recommended', 'plugin:react/recommended', 'plugin:@typescript-eslint/recommended'],
  plugins: ['import', 'react', '@typescript-eslint', 'react-hooks'],
  rules: {
    'react-hooks/rules-of-hooks': 'error',
    'react-hooks/exhaustive-deps': 'error',
    '@typescript-eslint/no-unused-vars': 'error',
    'react/react-in-jsx-scope': 'off',
  },
};&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;.prettierrc&lt;/p&gt;
&lt;pre id=&quot;code_1651803176150&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;printWidth&quot;: 120,
  &quot;singleQuote&quot;: true,
  &quot;trailingComma&quot;: &quot;es5&quot;,
  &quot;tabWidth&quot;: 2,
  &quot;arrowParens&quot;: &quot;avoid&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 세팅들은 프로젝트를 진행하며 더 추가할 예정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;2. 폴더 구조&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치하셨다면 기본적인 폴더들이 있을 겁니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;public - &lt;/b&gt;프로젝트에 사용되는 정적 파일들&lt;/li&gt;
&lt;li&gt;&lt;b&gt;pages - &lt;/b&gt;이 폴더 안에 각 페이지를 만들면 자동으로 라우팅 처리가 됩니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;styles - &lt;/b&gt;스타일 관련 파일들&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인의 방식에 따라 추가하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 src, components 등 폴더들을 추가하였습니다.&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;3. 스타일링&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평소 styled-components를 사용했었는데요.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 프로젝트에서는 emotion을 사용할 예정입니다.&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;* emotion 사용 이유&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. npm 다운로드 횟수가 더 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. CSS Prop과 styled-components 방식 모두 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. SSR &lt;span&gt;&lt;span&gt;&amp;nbsp;&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;</description>
      <category>Front-end/Nextjs</category>
      <author>아지송아지</author>
      <guid isPermaLink="true">https://talkwithcode.tistory.com/95</guid>
      <comments>https://talkwithcode.tistory.com/95#entry95comment</comments>
      <pubDate>Mon, 9 May 2022 12:02:26 +0900</pubDate>
    </item>
    <item>
      <title>Next.js 특징 살펴보기</title>
      <link>https://talkwithcode.tistory.com/94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 Next.js에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;719&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTTqWl/btrBibFU8lp/QiUDOnSmehWe2WxAoKh1GK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTTqWl/btrBibFU8lp/QiUDOnSmehWe2WxAoKh1GK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTTqWl/btrBibFU8lp/QiUDOnSmehWe2WxAoKh1GK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTTqWl%2FbtrBibFU8lp%2FQiUDOnSmehWe2WxAoKh1GK%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;631&quot; height=&quot;378&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;719&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Next.js?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js란 Verceld에서 만든 React 프레임워크입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSR, SEO 등 많은 특징들을 가지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쫌 더 자세히 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. Server Side Rendering (SSR)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;넥스트의 가장 대표적인 특징은 SSR입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트는 CSR로 SSR에 비해 초기 페이지 로딩이 오래 걸리고 SEO가 어렵다는 단점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 SSR은 서버에서 완성된 HTML을 보내주기 때문에 렌더링 속도가 빨라 &lt;u&gt;&lt;b&gt;로드 시간이 짧고 SEO가 좋습니다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSR보다 서버에 부하가 많고 페이지 이동 시 깜빡임 현상이 있을 수 있다는 단점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. Search Engine Optimization (SEO)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 특징에서 말씀드렸던 SEO입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 리액트는 html구성이 안되어있는 상태이기 때문에 검색엔진이 쉽게 찾을 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 넥스트는 &lt;u&gt;&lt;b&gt;서버에서 이미 html을 구성하였기 때문에 SEO가 좋습니다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글의 크롤러 봇은 자바스크립트를 실행할 수 있어&amp;nbsp; CSR의 크롤링도 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 아직 완벽한 상태는 아니며, 구글 측에서도 자바스크립트를 실행 전 더욱 빠른 크롤링과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 크롤러 봇들을 위해 SSR을 고려해보라는 말을 합니다.&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;SEO가 좋으면 사용자가 검색했을 때 제작한 페이지가 상단에 노출되어야 유입이 증가합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. Pre-rendering&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;넥스트는 모든 페이지를 사전 렌더링 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 가지 종류가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3-1. Static Site Generation (SSG)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적 생성의 경우 프로젝트가 빌드되는 시점에서 html 파일이 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3-2. Server Side Rendering (SSR)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSR은 매 요청마다 html 파일이 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 부분은 추후 더 자세히 설명드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4. Dynamic Routes&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트와 다르게 별도의 세팅 없이 &lt;u&gt;&lt;b&gt;폴더 및 파일 기반으로 라우팅을 지원&lt;/b&gt;&lt;/u&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;b&gt;5. 개발 중 저장하면 자동으로 리 렌더링이 일어납니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;6. 강력한 페이지 이동&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;넥스트는 &amp;lt;Link /&amp;gt;로 페이지간 이동이 빠르고 매끄럽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;a태그와 다르게 페이지가 &lt;u&gt;&lt;b&gt;리 로딩되지 않으며 &amp;lt;Link /&amp;gt;가 뷰포트에 보이면 해당 페이지를 백그라운드에서 미리 가져옵니다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;b&gt;7. Code Splitting&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 페이지가 로드될 때 모든 코드를 호출하는 것이 아닌, 번들을 여러 조각내어 처음에 필요한 부분만 전송해 주는 방식으로 로드 시간을 단축시킵니다. 코드 분할은 webpack, parcel 등 모듈 번들러도 지원하는 기능이지만 넥스트는 별도의 설정 없이 사용 가능합니다.&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 직접 작성하며 더 자세히 알아보겠습니다.&lt;/p&gt;</description>
      <category>Front-end/Nextjs</category>
      <author>아지송아지</author>
      <guid isPermaLink="true">https://talkwithcode.tistory.com/94</guid>
      <comments>https://talkwithcode.tistory.com/94#entry94comment</comments>
      <pubDate>Thu, 5 May 2022 12:26:38 +0900</pubDate>
    </item>
    <item>
      <title>ESLint, Prettier</title>
      <link>https://talkwithcode.tistory.com/93</link>
      <description>&lt;pre id=&quot;code_1650951214490&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install --save-dev --save-exact prettier&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 ESLint, Prettier에 대해 알아보겠습니다.&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;&quot;어떻게&quot;보다 &lt;b&gt;&quot;왜&quot;&lt;/b&gt;에 집중해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 ESLint, Prettier를 써야 하는 걸까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 하다 보면 팀 단위로 진행을 할 때가 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럴 때 깔끔하고 통일된 코드를 위해 규칙을 정합니다. 코드 컨벤션을 만드는 것이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;ESLint는 코드 퀄리티&lt;/b&gt;&lt;/u&gt;를 보장하며, &lt;u&gt;&lt;b&gt;Prettier는 코드 스타일&lt;/b&gt;&lt;/u&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;ESLint?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;문법적인 오류나 안티 패턴&lt;/u&gt;을 찾아주고 &lt;u&gt;일관된 코드 품질&lt;/u&gt;로 작성하도록 도와줍니다. 외부에 공개되어 많은 개발자가 사용 중인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/airbnb/javascript&quot;&gt;Airbnb Style Guide&lt;/a&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/google/eslint-config-google&quot;&gt;Google Style Guide&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&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;Prettier?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;줄 바꿈, 공백, 들여 쓰기&lt;/u&gt; 등 &lt;u&gt;일관된 스타일&lt;/u&gt;로 작성하도록 도와줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 eslint부터 알아보겠습니다.&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;ESLint!&lt;/h3&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;b&gt;1. eslint 설치&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1650873342878&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install eslint&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-04-25 오후 9.30.22.png&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;229&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dG3vOp/btrAs8WddsQ/Z5JwHdxxiptA9CzdfRK6N1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dG3vOp/btrAs8WddsQ/Z5JwHdxxiptA9CzdfRK6N1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dG3vOp/btrAs8WddsQ/Z5JwHdxxiptA9CzdfRK6N1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdG3vOp%2FbtrAs8WddsQ%2FZ5JwHdxxiptA9CzdfRK6N1%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;647&quot; height=&quot;229&quot; data-filename=&quot;스크린샷 2022-04-25 오후 9.30.22.png&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;229&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;eslint를 사용하기 위해서는 두 가지 세팅이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;npm 혹은 yarn을 통해 설치&lt;/u&gt;하고, &lt;u&gt;VSCode Extensions에서 eslint를 검색하여 설치&lt;/u&gt;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 추가 지식 (VSCode Extension 설명)&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;The extension uses the ESLint library installed in the opened workspace folder. If the folder doesn't provide one the extension looks for a global install version.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ESLint는 워크스페이스에서 먼저 설치된 것을 찾으며, 없으면 전역에서 찾습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. eslint 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 단계를 모두 했으면 사용할 준비는 끝났습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 세팅한 환경에서 무슨 규칙으로 어떻게 사용할 건지 정해봅시다.&lt;/p&gt;
&lt;pre id=&quot;code_1650873347503&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;eslint --init&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 실행하면 몇 가지 질문들을 하는데 저는 아래와 같이 답변했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-04-25 오후 4.58.15.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;253&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kfj2f/btrApm2d9DX/P1yUJwBKbSETmHQwrN9PA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kfj2f/btrApm2d9DX/P1yUJwBKbSETmHQwrN9PA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kfj2f/btrApm2d9DX/P1yUJwBKbSETmHQwrN9PA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKfj2f%2FbtrApm2d9DX%2FP1yUJwBKbSETmHQwrN9PA1%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;253&quot; data-filename=&quot;스크린샷 2022-04-25 오후 4.58.15.png&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;253&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;끝나면 .eslintrc(.js / .json) 파일이 자동으로 생성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 프로젝트를 자동으로 세팅해주는 라이브러리의 경우 이미 설치되어 있을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;eslintrc 파일에는 여러 가지 속성이 있습니다.&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;b&gt;env&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정의된 함수나 전역 변수 사용을 정의합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;browser:true, node:true&lt;/span&gt; 로 설정하면 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;console.log(), require&lt;/span&gt; 등을 에러 없이 사용할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650878301591&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  env: {
    node: true,
    browser: true,
  },&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;parser&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 Espree 파서를 사용합니다. 필요에 따라 다른 파서들도 사용합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Babel : &lt;a href=&quot;https://www.npmjs.com/package/@babel/eslint-parser&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;babel-eslint&lt;/a&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ESLint는 기본적으로 ES6 / JSX / spread까지 문법만 지원하여 그 이상의 문법이 필요할 경우 반드시 사용해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Typescript : &lt;a href=&quot;https://www.npmjs.com/package/@typescript-eslint/parser&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;@typescript-eslint/parser&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1650878097031&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    parser: &quot;babel-eslint&quot;,
    // parser: &quot;@typescript-eslint/parser&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;parserOptions&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ESLint를 사용하기 위해 지원하려는 Javascript 옵션을 지정할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;sourceType &lt;/b&gt;: parser의 export 형태를 설정&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529;&quot;&gt;ecmaVersion&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529;&quot;&gt; : ECMAScript 버전 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ecmaFeatures &lt;/b&gt;: ECMAScript의 언어 확장 기능 설정
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;impliedStric&lt;/b&gt;: strict mode 사용 여부&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;jsx:&lt;/b&gt; ECMScript 규격의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://facebook.github.io/jsx/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;JSX&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용 여부 (ESLint가 react를 잘 분석하기 위해서는 &lt;a href=&quot;https://github.com/jsx-eslint/eslint-plugin-react&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;eslint-plugin-react&lt;/a&gt;를 설치)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1650878173181&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    parserOptions: {
        sourceType: 'module',
        ecmaVersion: 6,
        ecmaFeatures: { jsx: 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;size18&quot;&gt;&lt;b&gt;plugins&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러그인 패키지를 설치하고, 사용할 플러그인을 가져옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가져오는 것만으로는 아무 일도 일어나지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용하기 위해서는 extends나 rules에 추가해야 합니다.&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;background-color: #dddddd;&quot;&gt;eslint-plugin-&lt;/span&gt; 접두사는 생략 가능합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650879748867&quot; class=&quot;css&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    plugins: [
        // 'eslint-plugin-react', eslint-plugin- 생략 가능
        'react', 
    ],
}&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;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;eslint-config-next :&lt;/b&gt; next 규칙을 추가&lt;/li&gt;
&lt;li&gt;&lt;b&gt;eslint-plugin-import :&lt;/b&gt; ES6의 import/export 체크, 파일 경로, import 이름 등 체크&lt;/li&gt;
&lt;li&gt;&lt;b&gt;eslint-plugin-react :&lt;/b&gt; 리액트 규칙을 추가&lt;/li&gt;
&lt;li&gt;&lt;b&gt;eslint-plugin-react-hooks :&lt;/b&gt; React함수 내에서 / 최상위에서 Hook을 호출해야 하는 규칙을 강제&lt;/li&gt;
&lt;li&gt;&lt;b&gt;eslint-config-prettier :&lt;/b&gt; ESLint와 Prettier가 충돌하면 ESLint에서 해당 부분을 비활성화&lt;/li&gt;
&lt;li&gt;&lt;b&gt;eslint-plugin-prettier :&lt;/b&gt; Prettier를 ESLint 플러그인으로 추가, Prettier 포맷 오류를 ESLint 오류로 출력&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;size18&quot;&gt;&lt;b&gt;extends&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러그인에서 사용해야 하는 규칙을 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가져온 플러그인을 rules에 일일이 넣는 것이 아닌 한 번에 적용합니다.&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;b&gt;rules&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러그인에서 가져와 사용할 규칙들을 넣어주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가져온 플러그인 중 특정 에러를 끄고 싶다면 여기서 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;eslint-plugin-&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;접두사는 반드시 생략해야 합니다. (ESLint는 접두사 없이 이름을 사용하여 규칙을 찾습니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://eslint.org/docs/rules/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이곳&lt;/a&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;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;off : 규칙을 사용하지 않음&lt;/li&gt;
&lt;li&gt;warn : 규칙을 경고로 사용&lt;/li&gt;
&lt;li&gt;error : 규칙을 에러로 사용&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;ESLint 검사 자체를 무시하고 싶다면, 파일 최상단에 아래 코드를 추가하시면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;/* eslint-disable */&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;Prettier!&lt;/h3&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;이제 prettier를 알아봅시다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;prettier를 사용하는 방법은 총 두 가지입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. VSCode Extension 직접 세팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. prettier 플러그인 세팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. VSCode Extension 직접 세팅&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-04-26 오후 2.30.57.png&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LPG85/btrAxjDtWhJ/m4otiZgavcBGgC862YcXs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LPG85/btrAxjDtWhJ/m4otiZgavcBGgC862YcXs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LPG85/btrAxjDtWhJ/m4otiZgavcBGgC862YcXs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLPG85%2FbtrAxjDtWhJ%2Fm4otiZgavcBGgC862YcXs0%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;676&quot; height=&quot;210&quot; data-filename=&quot;스크린샷 2022-04-26 오후 2.30.57.png&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Extension에서 prettier를 설치합니다.&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;Settings에 들어가서 원하시는 대로 설정합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* Settings 들어가는 방법&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;On Windows/Linux -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;File&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Preferences&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Settings&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;On macOS -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Code&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Preferences&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Settings&lt;/b&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;&lt;b&gt;2. prettier 플러그인 세팅&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1650951225488&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install --save-dev --save-exact prettier&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어로 설치를 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.prettierrc 파일을 만들어 세팅합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650951328138&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;singleQuote&quot;: true, // ''를 사용하는지 여부, 기본값은 &quot;&quot;
  &quot;tabWidth&quot;: 2, // 탭 너비 
  &quot;printWidth&quot;: 80, //  줄 바꿈 할 길이 (80자 이상이면 줄 바꿈)
  &quot;trailingComma&quot;: &quot;all&quot;, // 객체, 배열, 함수 등의 후행에 쉼표를 찍을지 제어
  &quot;semi&quot;: true, // 세미콜론 사용 여부
  &quot;arrowParens&quot;: &quot;avoid&quot;, // 화살표 함수 괄호 사용 방식
  &quot;overrides&quot;: [ 
    {
      &quot;files&quot;: &quot;*.json&quot;,
      &quot;options&quot;: {
        &quot;printWidth&quot;: 200
      }
    }
  ], // 특정 파일별로 옵션을 다르게 설정
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 많은 속성들이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 우선순위&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 방법 모두 세팅되어 있다면 &lt;u&gt;&lt;b&gt;.prettierrc이 우선적으로 적용&lt;/b&gt;&lt;/u&gt;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용하기&lt;/h3&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 세팅에 들어가 format on save를 검색합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 체크를 활성화시켜줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-04-26 오후 2.51.32.png&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZFAr8/btrAvG66szS/E2uCVKjDFAiRdaUVfNe19k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZFAr8/btrAvG66szS/E2uCVKjDFAiRdaUVfNe19k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZFAr8/btrAvG66szS/E2uCVKjDFAiRdaUVfNe19k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZFAr8%2FbtrAvG66szS%2FE2uCVKjDFAiRdaUVfNe19k%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;736&quot; height=&quot;222&quot; data-filename=&quot;스크린샷 2022-04-26 오후 2.51.32.png&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;222&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;2. command+shift+p 를 누르고 검색창에 &quot;&amp;gt;Open Settings (JSON)&quot;을 검색하여 들어갑니다.&lt;/p&gt;
&lt;pre id=&quot;code_1650953028124&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;editor.defaultFormatter&quot;: &quot;esbenp.prettier-vscode&quot;,
&quot;editor.formatOnSave&quot;: true,
&quot;editor.codeActionsOnSave&quot;: {
   &quot;source.fixAll.eslint&quot;: 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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 :&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tech.kakao.com/2019/12/05/make-better-use-of-eslint/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://tech.kakao.com/2019/12/05/make-better-use-of-eslint/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@kyusung/eslint-config-2#%ED%99%98%EA%B2%BDenv&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@kyusung/eslint-config-2#%ED%99%98%EA%B2%BDenv&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://develoger.kr/frontend/eslint-%EA%B8%B0%EB%B3%B8%EC%A0%81%EC%9D%B8-%EC%82%AC%EC%9A%A9%EB%B2%95/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://develoger.kr/frontend/eslint-기본적인-사용법/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@rimo09/ESLint-%EC%84%A4%EC%A0%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@rimo09/ESLint-%EC%84%A4%EC%A0%95&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@mayinjanuary/Next.js-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0-ESLint-Prettier-%EC%84%A4%EC%A0%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@mayinjanuary/Next.js-세팅하기-ESLint-Prettier-설정&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@velopert/eslint-and-prettier-in-react&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@velopert/eslint-and-prettier-in-react&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://helloinyong.tistory.com/325&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://helloinyong.tistory.com/325&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://code.visualstudio.com/docs/getstarted/settings&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://code.visualstudio.com/docs/getstarted/settings&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pstudio411.tistory.com/entry/%EC%95%84-%EB%B3%B4%EA%B8%B0-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EB%8B%A4-Prettier-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://pstudio411.tistory.com/entry/아-보기-좋은-코드다-Prettier-알아보기&lt;/a&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;</description>
      <category>Front-end/깊게 파고들기</category>
      <author>아지송아지</author>
      <guid isPermaLink="true">https://talkwithcode.tistory.com/93</guid>
      <comments>https://talkwithcode.tistory.com/93#entry93comment</comments>
      <pubDate>Tue, 26 Apr 2022 15:06:02 +0900</pubDate>
    </item>
    <item>
      <title>React Three.js 애니메이션 적용, obj 파일 추가</title>
      <link>https://talkwithcode.tistory.com/92</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 @react-three/fiber의 useFrame을 사용하여 geometry에 애니메이션을 추가해 보겠습니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;애니메이션&lt;/h2&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;Vanila JS에서는 requestAnimationFrame을 사용했지만 react에서는 useFrame을 사용합니다.&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;y 축으로 계속 회전하는 애니메이션입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1647852168025&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { useFrame } from '@react-three/fiber';
import React, { useRef } from 'react';

const ReactModel = (props) =&amp;gt; {
    
    const modelRef = useRef();

    useFrame(() =&amp;gt; {
        modelRef.current.rotation.y += 0.01;
    })

    return(
        &amp;lt;mesh position={[0, 0, 0]} ref={modelRef} castShadow&amp;gt;
            &amp;lt;torusKnotBufferGeometry
                attach='geometry'
                args={[10, 1, 300, 20, 6, 10]}
            /&amp;gt;
            &amp;lt;meshPhysicalMaterial
                attach='material'
                color={&quot;#61DBFB&quot;}
            /&amp;gt;
        &amp;lt;/mesh&amp;gt;
    )
};

export default ReactModel;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;useRef로 mesh에 접근 후 roatation 값을 조절합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위치를 이동하고 싶으시면 position 값을 사용하시면 됩니다.&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;h2 data-ke-size=&quot;size26&quot;&gt;OBJ 파일 추가&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre id=&quot;code_1647869584370&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import userObj from '../obj/user.obj';
import { useLoader } from '@react-three/fiber';

const UserModel = (props) =&amp;gt; {
    
    const obj = useLoader(OBJLoader, userObj);

    return (
        &amp;lt;mesh position={[0, -20, 15]}&amp;gt;
            &amp;lt;primitive object={obj} scale={4.0}/&amp;gt;
        &amp;lt;/mesh&amp;gt;
    );
};

export default UserModel;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* obj 파일이 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드와 같이 작성 후 Canvas 안에다 import 해주시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의하셔야 할 점은 &lt;b&gt;useLoader안에 경로를 직접 넣으시면 안됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1647869667272&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const obj = useLoader(OBJLoader, '../obj/user.obj');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2022-03-20 오후 9.43.47.png&quot; data-origin-width=&quot;2402&quot; data-origin-height=&quot;1696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YB1yG/btrwA6iyf3k/zwtf17bDspRyIKREwlKxXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YB1yG/btrwA6iyf3k/zwtf17bDspRyIKREwlKxXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YB1yG/btrwA6iyf3k/zwtf17bDspRyIKREwlKxXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYB1yG%2FbtrwA6iyf3k%2Fzwtf17bDspRyIKREwlKxXk%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;514&quot; height=&quot;363&quot; data-filename=&quot;스크린샷 2022-03-20 오후 9.43.47.png&quot; data-origin-width=&quot;2402&quot; data-origin-height=&quot;1696&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조그만 obj 가 생겼네요 :)&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;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공부해야 할게 많이 생겨서 이제 three.js 관련 글은 앞으로 안 올라올 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Front-end/Threejs</category>
      <author>아지송아지</author>
      <guid isPermaLink="true">https://talkwithcode.tistory.com/92</guid>
      <comments>https://talkwithcode.tistory.com/92#entry92comment</comments>
      <pubDate>Thu, 21 Apr 2022 11:34:24 +0900</pubDate>
    </item>
  </channel>
</rss>