<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>moony_moon.log</title>
        <link>https://velog.io/</link>
        <description>모든 코드에 의미를 담겠습니다.</description>
        <lastBuildDate>Wed, 10 Jan 2024 23:50:43 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>moony_moon.log</title>
            <url>https://images.velog.io/images/moony_moon/profile/02faf5db-d6d4-435c-8395-698745c8e059/스크린샷 2020-06-09 오후 1.39.22.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. moony_moon.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/moony_moon" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[자바스크립트 기초]]></title>
            <link>https://velog.io/@moony_moon/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@moony_moon/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Wed, 10 Jan 2024 23:50:43 GMT</pubDate>
            <description><![CDATA[<p>컴퓨터 언어중 하나로써, 브라우저상에서 HTML + CSS를 통해서 페이지를 꾸미고 Javascript로 행동(Behavior)을 명령할 수 있게 해준다.</p>
<p>Javascript 언어는 1995년에 만들어졌다.</p>
<p>또한, node.js 프레임워크의 탄생으로 컴퓨터 내에서도 javascript 언어를 사용할 수 있게 되었다.</p>
<h1 id="2-자바스크립트-엔진">2. 자바스크립트 엔진</h1>
<p>자바스크립트 동작을 위해서 Javascript Engine 필요</p>
<p>인터프리터가 Javascript를 런타임시 한줄씩 읽어가면서 실행</p>
<p>자바스크립트는 컴파일링 언어가 아니라 인터프리터로 실행을 먼저한 후 한줄 씩 읽어냄</p>
<p>자바는 컴파일링 언어 → 컴파일링 먼저한 후 실행파일을 읽음, 그렇기에 컴파일링 과정에 시간이 걸리지만 그 이후 실행속도는 굉장히 빨라진다</p>
<h1 id="3-ecmascript란">3. ECMAScript란?</h1>
<p>각 브라우저마다 각기 다른 엔진을 보유</p>
<table>
<thead>
<tr>
<th>Browser Edge</th>
<th>Chrome</th>
<th>Safari</th>
<th>FireFox</th>
</tr>
</thead>
<tbody><tr>
<td>V8</td>
<td>V8</td>
<td>Javascript Core</td>
<td>SpiderMonkey</td>
</tr>
</tbody></table>
<p>각 브라우저별로 다른 엔진에서 Javascript를 사용하기위해 공통된 문법 규격 표준사항을 만든것이 ECMAScript</p>
<p>ES 버전별로 새로운 문법, 개선사항들이 추가되고 브라우저 엔진별로 기능을 호환하기도하고 안하기도 함</p>
<p><img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/8672ffba-4307-4b5a-94ac-8dd148b2b404/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2023-01-26_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_5.48.17.png" alt="스크린샷 2023-01-26 오후 5.48.17.png"></p>
<p>가장 많은 대격변을 일으킨 문법 호환 시기는 ECMASCript 6 → class, for…of 등 있음</p>
<p>브라우저별로 호환 가능한 문법 확인하는 사이트: <a href="https://kangax.github.io/compat-table/es5/">https://kangax.github.io/compat-table/es5/</a></p>
<h1 id="4-자바스크립트란">4. 자바스크립트란?</h1>
<p>JS is a lightweight, interpreted, or just-in-time compiled language with first-class functions. (1급 객체 함수 언어)</p>
<p>JS is a prototype-based, multi-paradignm, single-threaded, dynamic language.</p>
<p>자바스크립트는 본래 브라우저상에서만 사용할 수 있는 언어로 많이 알려졌었는데, 이제는 자바스크립트 엔진이 있는 어느곳이든 (Node.js, Apache DB, Acrobat) 다 사용 가능함.</p>
<h1 id="5-자바스크립트-공부방법">5. 자바스크립트 공부방법</h1>
<p>자바스크립트 - 프로그래밍 언어 (정해진 문법으로 특정한 로직을 수행하도록하도록 프로그래밍)</p>
<p>자바스크립트 혼자서는 프로그래밍을 할 수 없다. (외부 환경 라이브러리 필수)</p>
<p>Node API, Web API </p>
<p>자바스크립트 자체 = 문법임 ( 문법외에 필요한 요소들이 많다)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[배열과 오브젝트 분석]]></title>
            <link>https://velog.io/@moony_moon/%EB%B0%B0%EC%97%B4%EA%B3%BC-%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@moony_moon/%EB%B0%B0%EC%97%B4%EA%B3%BC-%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-%EB%B6%84%EC%84%9D</guid>
            <pubDate>Thu, 04 Jan 2024 14:20:50 GMT</pubDate>
            <description><![CDATA[<h1 id="2-analyzing-performance-of-arrays-and-objects">2. Analyzing Performance of Arrays and Objects</h1>
<p><strong>Objects</strong></p>
<ul>
<li>Unordered, key value pairs</li>
<li>Unordered(순서)가 없어서 key value를 지울때, 추가할 때, 변경할 때 performance는 O(1)이다.</li>
<li>키의 값을 찾거나 키 자체를 찾을때 (Object.keys(), Object.values())는 O(N)이다.</li>
<li>Object.hasOwnProperty()는 O(1)인데 왜?<ul>
<li>Object.hasOwnProperty() 메서드는 맞는 키값을 찾을때까지 array처럼 모든 키들을 iterate하는것처럼 보인다. 하지만, Object는 모두 hashing 되어있어서 순회하지않고 direct key를 찾을 수 있다!</li>
</ul>
</li>
</ul>
<p><strong>Arrays</strong></p>
<ul>
<li>Ordered Lists, 순서가 필요없는 data structure라면 성능을 위해서 object를 사용하는게 좋다</li>
<li>accessing O(1), searching O(N), insertion(it depends… 어디에 추가하냐에 따라), removal(it depends… 어디 element를 삭제하냐에 따라)</li>
<li>push: O(1), pop: O(1), shift &amp; unshift: O(N), foreach, concat, slice, splice … : O(N)</li>
<li>sort : O(NlogN)</li>
</ul>
<p>Time complexity에서 가장 중요한것: input이 늘어남에따라 어떻게 복잡도가 변하는지를 생각해야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Time Complexity]]></title>
            <link>https://velog.io/@moony_moon/Time-Complexity</link>
            <guid>https://velog.io/@moony_moon/Time-Complexity</guid>
            <pubDate>Wed, 03 Jan 2024 11:26:52 GMT</pubDate>
            <description><![CDATA[<h1 id="big--o-notation">Big- O Notation</h1>
<p><strong>BIG O Notation이 필요한 이유?</strong> </p>
<p>문제에대한 코딩을 할 때 여러가지 해결방법으로 풀 수 있다.</p>
<p>가령, join 메서드를 이용해서 문제를 해결한다던가 다른 메서드를 이용해서 문제를 해결하는 방법도 있다.</p>
<p>정답은 똑같이 도출되는데 그렇다면 어떤 문제해결방식(알고리즘)이 더 효율적일까?</p>
<p><strong>효율성(성능)을 고려하는 것이 BIG-O Notation이라고 할 수 있다!!!</strong></p>
<p>내가 개인 프로젝트를 하고 성능에 관계없는 코드를 짠다면 BIG-O Notation이 그렇게 중요하지 않을 수 있지만,</p>
<p>몇만줄을 실행하는 회사에서 한 줄의 코드 변경으로 인해 성능이 확 바뀐다면? 그게 BIG-O notation의 중요성이라면? 당연히! 필요하다.</p>
<p><strong>좋은코드란?</strong></p>
<p>주로 3가지를 본다.</p>
<ul>
<li>Speed(이 알고리즘이 얼마나 빠르게 실행되는가?)</li>
<li>Memory Loss(이 알고리즘이 얼마나 메모리를 차지하는가?)</li>
<li>Readable(이 알고리즘이 얼마나 쉽게 읽히는가?)</li>
</ul>
<p>혼자 개발하면 가독성은 빼도 되지만 함께 개발하는 문화에서는 종종 실행 성능을 어느정도 포기하고 가독성을 높이는 경우도 많다.</p>
<p><strong>Speed, Time Complexity (알고리즘 성능 확인할때 가장 중요한것 중 하나) 측정하는방법!</strong></p>
<ol>
<li>TimeStamp 사용하기</li>
</ol>
<pre><code class="language-jsx">timeOne = performance.now()
// 이 곳에 성능 측정하고 싶은 코드 넣기
timeTwo = performance.now()

console.log(`이 알고리즘이 걸리는 시간은?: ${(timeTwo- timeOne) / 1000}`)</code></pre>
<p>위의 방식을 자주 사용하지만 만약 특정 알고리즘이 엄청나게 시간소요(2시간, 4시간) 걸린다면?</p>
<ol>
<li>BIG-O Notaion으로 짐작하기</li>
</ol>
<ul>
<li>BIG-O Notaion이란 무엇인가? 특정 알고리즘(함수)의 Input값이 변함에 따라 성능(시간)의 변화를 대략적으로 측정하는것을 의미한다.</li>
</ul>
<p><strong>BIG O Notation의 종류</strong></p>
<ol>
<li>Big O could be linear (f(n) = n) → n operations</li>
<li>Big O could be quadratic(f(n) = n^2) → n^2 operations</li>
<li>BIg O could be constant (f(n) = 1) → 1 operation regardless of n size</li>
<li>Big O could be totally different</li>
</ol>
<p><strong>BIG O Notation Shorthands</strong></p>
<ol>
<li>Arithmetic operations ( + -)는 constant</li>
<li>배열(Array)안에 요소들(elements) 접근할때 혹은 object의 key value 접근할때는 constant</li>
<li>할당 (x = 20000, x=1)은 constant</li>
<li>loop function은 complexity N 하지만 안에 nested loop이 추가될때마다 n *n *….</li>
</ol>
<p><strong>Space Complexity (공간 복잡도)</strong></p>
<p>Shorthands</p>
<ol>
<li>Most primitives(numbers, booleans, undefined, null) are constant space</li>
<li>Strings require O(n) space (where n is string length)</li>
<li>Reference types are generally O(n), where n is the length(array) or number of keys in objects</li>
</ol>
<p><strong>Logarithm - 왜 필요한가?</strong></p>
<p>Big O 복잡도 계산을 할 때 O(1) O(n) 이런식으로 깔끔하게 복잡도가 계산되는 경우는 적다</p>
<p>대부분 O(logN) 이런식이라서 로그에 대해서 알아 두면 좋다.</p>
<p>Log란?</p>
<p>곱셈과 나눗셈이 항상 같이 나오듯이, 지수와 로그는 서로 붙어 있다</p>
<p>logn(8) = 3 → N^3 = 8 이 나오는 N의 값을 찾아라 정도다. 정답은 2</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[컴퓨터의 기본이해 및 Javascript 문법]]></title>
            <link>https://velog.io/@moony_moon/Day-02-%EC%BB%B4%ED%93%A8%ED%84%B0%EC%9D%98-%EA%B8%B0%EB%B3%B8%EC%9D%B4%ED%95%B4-%EB%B0%8F-Javascript-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@moony_moon/Day-02-%EC%BB%B4%ED%93%A8%ED%84%B0%EC%9D%98-%EA%B8%B0%EB%B3%B8%EC%9D%B4%ED%95%B4-%EB%B0%8F-Javascript-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Sun, 29 Jan 2023 06:03:23 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/moony_moon/post/254488d0-035d-4ae2-bc38-2c51c1715d4b/image.png" alt=""></p>
<h2 id="컴퓨터의-구성요소메모리">컴퓨터의 구성요소(메모리)</h2>
<p>컴퓨터의 기본동작은 3가지 구성요소로 크게 진행된다.
CPU(Central Processing Unit), RAM(Random Access Memory), HDD(하드디스크)</p>
<p>CPU: 주 기억장치라고 불리는 RAM에서 코드들을 불러와 연산, 논리, 흐름제어 등을 한다.</p>
<p>RAM: 하드 디스크에서 임시적인 내용들을 그대로 불러와서 CPU와 네트워킹을 한다. 개발자가 가장 많이 신경써야하는 부분은 RAM</p>
<p>HDD: 보조기억장치라고도 불리며 응용 프로그램들을 저장해 놓았다가 실행이 되면 RAM에서 복사를 해준다.</p>
<blockquote>
<p>CPU, RAM, HDD 비교</p>
</blockquote>
<p>가격: CPU - RAM- HDD 순으로 비싸다.
크기: HDD - RAM- CPU 순으로 크다.
처리속도: CPU - RAM - HDD 순으로 비싸다.</p>
<p>위에서 처리속도를 비교해보면 HDD와 CPU간에 속도차이가 심해서, 네트워킹을 할 때 문제가 생겨서 RAM이 만들어진것도 있다.</p>
<h2 id="ram메모리의-구조">RAM(메모리)의 구조</h2>
<ul>
<li>RAM은 위에서 말했다시피 운영체제와 운영시스템으로 구성되어 있기때문에 프론트엔드 개발자 입장에서 가장 많이 신경써야하는 부분이다.</li>
<li>하드디스크에서 RAM으로 코드가 복사되면 기계어로 컴파일링 되서 해당 기계어들이 데이터 - 힙 - 스택 세가지 중에 하나에 쌓인다.</li>
<li>RAM이 코드-데이터-힙-스택 이렇게 나누는 건 메모리에서 나누는게 아니라 OS별로 임시적으로 나눈다.</li>
</ul>
<p>정확히 RAM의 구조에 대해서 말하면, 컴퓨터를 실행시키는 순간 RAM의 운영체제에 기본적인 정보들이 다들어간다.</p>
<blockquote>
<p>운영체제 구성요소: CPU, 메모리, 앱, 화면, 사운드카드, 마우스</p>
</blockquote>
<p>그리고 HDD에서 프로그램이 실행되는 순간, 운영체제의 앱 별로 메모리가 코드- 데이터 - 힙 - 스택 형식으로 쌓이게 되는 것이다.</p>
<h2 id="cpu의-구조">CPU의 구조</h2>
<ul>
<li>연산, 논리 , 흐름 제어등이 실행되는 공간</li>
<li>정확히 말하면 제어장치(Control Unit) 와 연산 장치(Arithmetic Unit)으로 나뉘어 각자 역할을 한다.</li>
<li>코드들은 각 동작단위 (Statement)로 주솟값에 저장되어서 해당 주솟값들의 코드들은 기계어로 바뀐 뒤 Control Unit에서 평가를 받는다.
CU에서 평가를 받았을 때 연산이 필요하면 ALU로 넘어가고 필요하지 않다면 바로 데이터-힙-스택 중 한곳으로 저장이 된다.</li>
</ul>
</br>
</br>
</br>

<p>그렇다면 이런 컴퓨터의 동작원리를 알아야 하는 이유는?</p>
<p>최소한 메모리에는 어떤 방식으로 코드가 저장되고 실행되는 지 알아야지, Javascript내에서 주솟값에 저장된 데이터들이 왜 이런식으로 변형되고 동작하는지 알 수 있다.</p>
<h2 id="javascript-변수">Javascript 변수</h2>
<p>메모리 내에서 입력 -&gt; 처리 -&gt; 출력 과정에서 처리할 때 저장할 수 있는 공간이 필요하다.</p>
<p>변수: 이름을 정해서 데이터를 저장할 수 있는 공간</p>
<blockquote>
<p>여기서 중요포인트는 이름을 정한다는 것이다. 그렇다면 변수의 이름은 개발자 입장에서 최대한 의미있는 이름으로 정해져야 한다.</p>
</blockquote>
<p>변수이름 짓는 방법론</p>
<ul>
<li>자바스크립트 언어에 원래 있는 예약어 (default, const, continue ...)는 사용할 수 없다.  예약어와 변수 관련한 것은 다른 프로그래밍 언어에서도 마찬가지다.</li>
<li>변수 이름에 두가지 이상이 사용되면 camelCase를 사용한다.</li>
<li>특수문자를 사용할 수 없다.</li>
<li>숫자를 변수의 시작으로 사용할 수 없다.</li>
</ul>
<h2 id="javascript-데이터-타입">Javascript 데이터 타입</h2>
<p>데이터 타입은 메모리 저장에 있어서 가장 중요한 부분이다. 코드의 데이터가 메모리에 저장될 때 크게 데이터 타입은 두가지로 나뉜다.</p>
<p>원시 데이터(Primitive): Number, String, Null, Undefined, Boolean, Symbol</p>
<p>객체 데이터 (Reference): Object, array, function</p>
<p>이렇게 데이터를 나누는 이유는 뭔가?
흔히들 인강 또는 책에서 원시 데이터는 copy by value, 객체 데이터는 copy by reference라고들 한다. 이게 무슨말이냐?</p>
<p>메모리셀에 데이터를 저장할 때 각 동작별로 고유의 주솟값에 저장을 한다.</p>
<p><img src="https://velog.velcdn.com/images/moony_moon/post/6060755a-1222-4047-bf8c-f612cc03ac4e/image.png" alt=""></p>
<p>원시 데이터: 값 자체를 주소에 저장한다.
객체 데이터: 값 자체가 너무커서 Heap이라는 객체 저장하는 곳에 데이터를 저장하고 해당 데이터를 주소는 참조를 한다.</p>
<p>사실 조금 더 자세하게 들어가면, 원시 및 객체 타입 둘다 <a href="">Core Javascript</a> 책을 참조하면 둘다 참조를 하지만, 값이 한 단계 더 들어가냐 마냐의 차이긴하다.</p>
<p>이렇게 둘의 차이를 두면 무슨 변화가 생기냐? 다음 코드를 보자.</p>
<pre><code class="language-javascript">let a = 1;
b = a; 
console.log(a,b) // 1 1
b = 2
console.log(a,b) // 1 2

let a = {name: &#39;Taewoong Moon&#39;, age: 16};
b = a
console.log(a,b) // 둘다 {name: &#39;Taewoong Moon&#39;, age: 16};
b.name = &#39;문태웅&#39;
console.log(a,b) // 둘다 {name: &#39;문태웅&#39;, age: 16};
</code></pre>
<p>값을 복사한 원시 데이터 같은 경우는 b에 새로운 값을 재할당 했을 때, 새로운 주소를 생성해서 b에 데이터를 복사하는 반면
객체 데이터 같은 경우는 힙의 내부 데이터가 변한것이기 때문에 Heap의 값만 바뀌고, a와 b는 둘다 같은 주소를 참조하고 있다. 그렇기 때문에 b가 a를 그대로 복사하면 둘 다 내부의 데이터가 바뀌는 문제가 발생한다.</p>
<blockquote>
<p>그래서 객체형 데이터 같은 경우는 Javascript 를 깊은 복사를 하거나 얕은 복사를 해야한다.</p>
</blockquote>
<h3 id="참조형-데이터-복사-방법">참조형 데이터 복사 방법</h3>
<h3 id="1-얕은-복사-진행">1. 얕은 복사 진행</h3>
<pre><code class="language-javascript">let a = {name: &#39;TaewoongMoon&#39; , age: 16};
function copyShallowObject(object){
      return {
        name: object.name;
          age: object.age;
    }
};</code></pre>
<p>위의 함수와 아애 새로운 객체를 리턴하는 함수를 만들어서 진행해도 된다. 다만 이런식으로 하드코딩했을 경우에는 내부의 프로퍼티 key값이 무엇인지 항상 알아야하는 단점이 있다.</p>
<pre><code class="language-javascript">let a = {name : &#39;TaewoongMoon&#39;, age: 16};

function copyShallowObject(object){
    let result = {};
      for(prop in object){
        result[prop] = object[prop];
    }
      return result;
}</code></pre>
<p>위의 함수는 굳이 하드코딩을 할 필요가 없다. 다만 a의 내부프로퍼티에서 nested object, 즉, 객체가 중첩될 경우에는 shallow copy를 한 함수기 때문에 nested object는 또 힙의 데이터를 참조만 해서 문제가 된다. 그렇기 때문에 깊은 복사를 재귀함수를 통해서 하는 것이다.</p>
<h3 id="2-깊은-복사-진행">2. 깊은 복사 진행</h3>
<pre><code class="language-javascript">let a = {name : &#39;Taewoong Moon&#39;, age: {young: &#39;16&#39;, old: &#39;27&#39;}}

function copyObjectDeep(object){
    let result = {};
      if(typeof object === &#39;object&#39; &amp;&amp; object !== null){
        for(prop in object){
            result[prop] = copyObjectDeep(object[prop])
        }
    }else{
    result = object;
    }
    return result;
}
</code></pre>
<p>위의 재귀함수를 구현해서 깊은 복사를 한 후 메모리에 저장을 하면 문제가 발생하지 않는다. 위의 코드를 처음보면 이해가 잘 되지 않지만, 계속해서 눈으로 익숙해지며 재귀함수 프로그래밍을 많이 짜봐야 이해가 되긴한다. (사실 아직도, 잘 눈에 안익음)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript 시작]]></title>
            <link>https://velog.io/@moony_moon/DAY-01-Javascript-Mastery</link>
            <guid>https://velog.io/@moony_moon/DAY-01-Javascript-Mastery</guid>
            <pubDate>Sat, 28 Jan 2023 20:44:02 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/moony_moon/post/cbe66685-051e-4af2-a2e5-9fb52b314a79/image.png" alt=""></p>
<p>흔히들 말하는 HTML(뼈대) + CSS(뼈대 꾸미기) 그리고 Javascript (행동) 이렇게 세개로 묶일 때 무슨말인지 이해 못했다.</p>
<p>공부를 조금 하다보니 이해를 하는 걸 보니 확실히 나 같은 경우는 이론적으로 습득한 이후에 이론 적용을 프로그래밍에 하는 것 보다는</p>
<p>프로젝트를 하면서 그리고 직접 오류를 내가면서 배우며 피부로 느끼는게 더 효율적(?)이라는 생각이 든다.</p>
<p>준비 &lt; 실전
공부 &lt; 시험
생각 &lt; 표현</p>
<p>위의 3가지 중에 왼쪽으로 개발 공부를 하려고 노력중이다. Tistory 블로그에 매일 생각 정리하는 것도 표현을 더 우선시하기에 오늘부터 시작한다. 남들에게 보여주는 블로그라기보다는 내 가벼운 생각들을 정리해서 표현해는 일기장이다.</p>
<p>자바스크립트</p>
<ul>
<li><p>1995년에 만들어졌고 HTML + CSS로 웹 페이지를 꾸미고 정적으로 만들면 웹 페이지를 동작하게끔 만들어 주는 언어라고 보면 되겠다</p>
</li>
<li><p>즉, 브라우저 상에서 행동을 맡고 있는 것이다.</p>
</li>
<li><p>자바스크립트는 요즘에 브라우저 뿐만 아니라 다양한 환경(Node.js, Apache, Acrobat 등) 에서 쓸 수 있다.</p>
</li>
</ul>
<p>자바스크립트의 특징?
JAVA, C 언어들은 컴파일 언어임. 무슨말이냐? 우리가 쓴 코드들을 한번 쭉 훑고 컴파일(프로그래밍 언어 -&gt; 기계언어) 과정을 거쳐서 실행이 됨.</p>
<p>위의 언어들과는 다르게 자바스크립트는 인터프리터 언어. 한 줄씩 읽어가면서 실행이 된다 (Just in-time compilation). 때문에 동적인 언어라고도 불리며 시시각각 정해지는게 많음</p>
<p>자바스크립트 - ECMAScript
자바스크립트는 자바스크립트 엔진이 있다는 가정하에 실행됨. 우리는 다양한 브라우저들을 사용함 (Edge, Chrome, FireFox, Safari).</p>
<table>
<thead>
<tr>
<th align="left">Edge</th>
<th align="center">Chrome</th>
<th align="center">FireFox</th>
<th align="center">Safari</th>
</tr>
</thead>
<tbody><tr>
<td align="left">V8</td>
<td align="center">V8</td>
<td align="center">SpiderMonkey</td>
<td align="center">Javascript Core</td>
</tr>
</tbody></table>
<p>각 브라우저는 각기 다른 엔진을 가지고 있지만, 자바스크립트의 표준규격을 따르는 ECMAScript를 따르기 때문에 Javascript와 호환되어 사용하는 것이다.</p>
<p>인강에서 ES6+ 와 같은 내용들이 나올때 ES는 ECMAScript를 가리키는것. 각 버전별로 ECMAScript 문법 추가 및 개선을 하는데, ES6에서 가장 큰 변화들이 일어나서 그 기준으로 새로운 인강들이 많이 나온것이다.</p>
<p>버전별로 뭐가 나왔는지 history를 보면 생각보다 재밌으니 한번 참고해보는 것도 좋다.</p>
<p><a href="https://en.wikipedia.org/wiki/ECMAScript_version_history">https://en.wikipedia.org/wiki/ECMAScript_version_history</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - (1일차)]]></title>
            <link>https://velog.io/@moony_moon/TIL-%EC%9B%90%ED%8B%B0%EB%93%9C-%ED%94%84%EB%A6%AC%EC%98%A8%EB%B3%B4%EB%94%A9-1%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@moony_moon/TIL-%EC%9B%90%ED%8B%B0%EB%93%9C-%ED%94%84%EB%A6%AC%EC%98%A8%EB%B3%B4%EB%94%A9-1%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Thu, 29 Jul 2021 00:58:29 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/617d1b8f-d9d7-469d-b752-803564b7d7d5/TIL_React.png" alt=""></p>
<p>오랜만에 쓰는 velog...</p>
<p>원래는 프로젝트를 하는 기간중에도 자주 써야했지만 프로젝트에 집중하겠다는 변명을 가지고 거의 한달간 velog 작성을 하지 못했다. 그래도 프로젝트에만 집중할 수 있어서 스스로 만족할만한 중고마켓 페이지를 만들긴 했지만 앞으로는 프로젝트를 진행하면서 아무리 바쁘더라도 velog를 하루에 하나씩 써내려가는 목표를 세우겠다.</p>
<p>그렇다면 오늘의 velog는 무슨 기점으로 새로 시작하느냐...?? 바로</p>
<blockquote>
<p>원티드 x 위코드 x 루트임팩트 에서 주관하는 프리온보딩 코스에 합격</p>
</blockquote>
<p>프리온보딩 코스는 약 8주동안 9개 기업에서 제공하는 데이터를 기반으로 프론트엔드 이론 + 프로젝트를 진행하는 프로그램이다. </p>
<p><img src="https://images.velog.io/images/moony_moon/post/834aace7-5f8a-4861-9b41-3c8460e640c8/Minions.gif" alt=""></p>
<p>프리온보딩 코스를 마치고 난 이후에 참가자들의 평가를 기반으로 9개기업에서 채용을 진행한다. 또한, 프리온보딩 코스를 마치고 난 이후에는 원티드에서 수료했다는 의미로 뱃지를 주는데 이러한 혜택들이 굉장히 매력적인 것 같다.</p>
<p>그렇다면 프리온보딩 코스는 지원만하면 합격을 할 수 있나요?</p>
<blockquote>
<p>아니다. 원티드에서 사전과제를 제공하고 해당 사전과제를 github or 배포를해서 해당 사전과제를 기반으로 합-불 여부를 가린다.</p>
</blockquote>
<p>프리온보딩 사전과제는 원티드 페이지에서 Global Navigation Bar를 반응형을 포함하여 구현하는 것이었다. 과제를 마치고 제출할 당시에는 &#39;아 이정도면 되겠지. 만족스러운데?&#39; 라는 생각을 가졌고 실제로 합격을 해서 그런 줄 알았다.</p>
<p>하지만 합격한 후 첫 Orientation 세션 때 내가 제출하였던 사전과제는 굉장히 오류가 많았고 어떻게 통과했는지 신기할 따름이었다.</p>
<p>Wecode의 예리 멘토님 말씀에 공감이 갔었다. 일단 사전과제를 풀 수 있을 정도면 무조건 도전을 해라. 생각보다 지원자 수가 많지 않을 수 있다. 나는 운좋게도 프리온보딩 코스에 합격했다고 생각하고 남은 8주동안 최대한 내가 배울 수 있는것의 max치를 배워서 좋은 프론트엔드 개발자 역량을 갖추는게 목표이다.</p>
<p>물론 9개 회사 중 한곳에서 오퍼를 받으면 좋지만, 최선을 다해서 동료 및 멘토에게서 많은 것을 배워서 성장해나가는 것이 더 중요하다.</p>
<h2 id="1주차-오리엔테이션-세션-정리">1주차 오리엔테이션 세션 정리</h2>
<p>오리엔테이션은 크게 앞으로 프로젝트를 CRA 할 때 유의해야 될 사항, 과제 제출, 그리고 블로그 작성에 대한 내용을 전달하였고, 해당 부분에서 내가 조금 더 주의깊게 봤던것들을 정리해보았다.</p>
<h3 id="cra-프로젝트-생성-할-때-필수적인-요소들">CRA (프로젝트 생성) 할 때 필수적인 요소들</h3>
<ul>
<li>ReadMe 정리하기: 폴더 구조, 영상, 기술 스택, 구현 목록, 설치 및 동작방법에 대해서 정리해 놓으면 좋다</li>
<li>GitIgnore해야하는 부분들 정리하기: node_modules, .DS_STORE 등</li>
<li>Depth 하나 더 들어간 폴더 구조 만들지 말기 : 특정 폴더를 클릭해야지만 프로젝트 구조가 보인다면 git에 대해서 모르는 것이다라는 이야기를 예리님께서 해주셨을 때 엄청 뜨끔했다...</li>
<li>GitCommit 관리하기</li>
<li><blockquote>
<p>Commit을 한 번에 끝내지말고 과정을 보여줄 것</p>
</blockquote>
</li>
<li><blockquote>
<p>Commit Message 일관성 지킬 것</p>
</blockquote>
</li>
<li><blockquote>
<p>~작업중/ ~습니다/ 와 같은 어체로 끝내지 말것 | X</p>
</blockquote>
</li>
</ul>
<p>README 정리 순서 (보충)</p>
<ul>
<li>과제 구현 목록</li>
<li>필수 | 설치 및 시작방법</li>
<li>option | 프로젝트 구조 설명</li>
<li>필수 | 프론트엔드) 배포 주소 or 시연영상 백) api 명세</li>
<li>X | 코드 설명, 프로젝트 후기 등 장황해지면 읽지 않는다 =&gt; velog에 해당 부분들을 자세히 써낼 것</li>
</ul>
<h3 id="블로그-정리">블로그 정리</h3>
<ul>
<li>주니어 개발자로써 회사를 지원할 때, 특히 나같은 비전공자 출신이 지원할 때 꾸준함을 보여주는 건 블로그 정리만한게 없다고 생각한다</li>
<li>실제로 위코드 수강생중에 한명또한 블로그를 정말 잘쓰시고 그걸 기반으로 가장 좋은 회사에 취직하셨다는 것을 듣고 다시한번 블로그의 중요성에 대해서 느끼고 있다.</li>
</ul>
<p>아래는 오리엔테이션 때 잘 정리된 블로그 공유 링크들이다. 블로그 정리가 막막할 때마다 보면 좋을 내용들이다.
<a href="https://junilhwang.github.io/TIL/Review/2021-year/01-First-Quarter/">주니어 개발자의 회고</a>
<a href="https://velog.io/@hyounglee/series">TIL의 정석: 이지형님</a>
<a href="https://milooy.wordpress.com/2015/10/08/daily-commit/">일일 커밋 회고</a></p>
<h2 id="팀-결성">팀 결성</h2>
<ul>
<li>프리온보딩코스의 팀원 숫자는 약 70명 정도되면 8명씩 팀별 배정이 되었다. 해당 팀별로는 과제가 주어졌고, 의견을 공유해서 팀 리더가 취합을 해서 제출하는 형태였다.</li>
<li>또한 각 팀별로 2~3명씩 팀을 다시한번 나누어 과제를 수행해 나간다.</li>
</ul>
<p>팀 결성구조는 확실히 맘에 들었다. 오프라인 부트캠프를 한 번 경험해보면서 다른 사람들의 코드를 이해하고 소통하는게 굉장히 중요하다고 느꼈다. 또한, 나는 FE개발자로서 프리온보딩에 참여하신 다른 분들에 비해서 부족하다고 생각하고, 기술스택또한 React가 아닌 Next기반으로 프로젝트를 계속 진행해왔기에 모르는 부분들을 물어보는데 팀 구조만한게 없다고 생각했다.</p>
<blockquote>
<p>그런데 생각하지도 못했던 팀장 역할을 맡았다. 사다리타기에서 꽝이 걸렸기 때문....</p>
</blockquote>
<p>그래도 팀장역할을 한번쯤은 해보고 팀원들과의 의견 조율을 하는 과정또한 개발자 역량의 일부라고 생각하기 때문에 미리 많은 경험치를 쌓는다고 생각하려고 한다.</p>
<p>앞으로 5주간 팀장으로써 동시에 팀원으로써 많이 배우고 많이 공유해나가는, 또한, 코드 한줄한줄에 의미를 담는 개발자가 되겠다</p>
<h2 id="1주차-1회-과제-정리">1주차 1회 과제 정리</h2>
<h3 id="팀과제">팀과제</h3>
<p>주제: CSS 작성 방법</p>
<ul>
<li>React에서 많이 사용하는 CSS 작성 방법은 Styled Component, SASS, CSS Modules 등이 있습니다. 어떤 방식을 선택하셨나요? 선택한 방법의 편리한 점은 무엇이었나요? </li>
</ul>
<h2 id="팀-과제-내용-정리">팀 과제 내용 정리</h2>
<p>React 에서 적용한 방법 정리?</p>
<p>RE4CT 팀에서는 4팀중 3팀이 styled-components 활용 그리고 나머지 한팀이 SCSS (CSS 전처리기)를 사용하였습니다.</p>
<p>팀별로 Styled-components를 사용하는 이유를 종합하여 정리해보았습니다.</p>
<ul>
<li>SCSS(SASS) 처럼 라이브러리 설치 없이 scss 문법을 사용할 수 있습니다. (중첩, 상위요소 참조, 등)</li>
<li>CSS-in-js 문법이기에 변수처럼 활용하여 재사용성이 굉장히 높습니다.</li>
<li>className이나 id를 사용하지 않고 스타일링을 할 수 있다 (이 부분은 장점이자 단점으로 적용될 수 있습니다. Class 코드 컨벤션을 따르는 회사라면 styled-component는 좋지않습니다)</li>
<li>Material UI 및 Ant Design 커스터 마이징이 쉽습니다. import &quot;디자인 이름&quot; from &quot;materialui/core&quot; 에서 디자인이름을 가져와서 styled(&quot;디자인이름&quot;).div`` 이런식으로 쓰면 css를 쉽게 적용할 수 있습니다.</li>
<li>컴포넌트 단위로 만들어지기때문에 css 파일간의 의존성을 전혀 고려하지 않아도 됩니다.</li>
<li>동적 코딩이 가능합니다. (props(데이터)를 받아서 css 적용을 달리 할 수 있습니다.)</li>
</ul>
<p>Styled-component의 단점</p>
<ul>
<li>Global namespace 문제 ⇒ Class이름이 build time때 유니크한 해쉬값으로 전달이 되는데 개발자 도구에서 class의미를 확인하기가 쉽지 않습니다. 디버깅의 어려움이 생깁니다.</li>
<li>각 태그별로 컴포넌트화 시켜야 하기때문에 가독성이 떨어질 수 있습니다.</li>
<li>아무래도 속도면에서 scss 혹은 sass보다 느릴 수 있습니다. js의 css코드를 읽은 후에 파싱하는 단계로 넘어가야만합니다.</li>
</ul>
<p>SCSS 사용하는 팀에서는 SCSS(SASS) 장점을 아래와 같이 설명해주었습니다.</p>
<ul>
<li>고유 class, id 를 네이밍하여 작성할 수 있습니다 (장점이자 단점!)</li>
<li>간단하고 작은 프로젝트에는 편리하게 사용할 수 있습니다. (유지 보수성 확보)</li>
</ul>
<p>SCSS 단점</p>
<ul>
<li>요소가 많아질수록 관리가 힘들 수 있습니다 + 엄청난 코드의 양</li>
<li>직관성이 떨어집니다</li>
<li>클래스명에 대한 고민을 해야합니다.</li>
<li>브라우저에 보이지 않는 컴포넌트까지 스타일 정보로 읽히기 때문에 불필요한 컴파일 과정이 추가 됩니다.</li>
</ul>
<h2 id="기업과제-하얀-마인드-정리">기업과제 (하얀 마인드 정리)</h2>
<ul>
<li>1회차에서는 페이지네이션(무한스크롤)을 구현하는 과제였다.</li>
<li>Next.js에 너무 익숙한지라 react-app으로 깔아서 진행했을 때는 뭔가 익숙하지가 않은 기분이였다</li>
<li>통신또한 graphql로 해서 axios로 통신해서 데이터를 받아오는 것도 약간 신세계였다.</li>
</ul>
<p>무한스크롤 구현할 때 핵심파트</p>
<ul>
<li>useEffect를 통해서 첫 10개의 데이터를 불러오고 그 이후에 계속해서 불러와지는 callback함수가 있어야한다.
해당 콜백함수는 불러와질때마다 page수가 +1씩 업데이트 되어야한다.</li>
<li>500개에 도달할 때 callback함수는 종료가 되어야한다.</li>
</ul>
<p>react-infinite-scroller라는 라이브러리를 사용해서 onLoadMore 섹터에 callback함수를 넣고 구현을 하였는데, 스크롤이 끊임없이 늘어나는 문제현상을 해결하는 데 새벽까지 코드를 봤다.</p>
<p><img src="https://images.velog.io/images/moony_moon/post/8f692703-d449-41e2-a686-e3f0c82255d9/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-07-29%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%209.52.32.png" alt=""></p>
<p>문제 해결방법은 props.fetchData라는 함수를 그대로 쓰면 안되고 ()=&gt; props.fetchData(props.items.length / 10 + 1)} 로 써줘야한다는 것이다.</p>
<p>공식문서에 그렇게 써야만한다고 나와있지만, 왜 그렇게 써야하는지 아직까지도 이해못한 1인이다.... 더 조사를 해서 해결점을 찾아보도록 노력하겠다.</p>
<h3 id="기업과제를-하면서-아쉬웠던-점">기업과제를 하면서 아쉬웠던 점</h3>
<ul>
<li>위에 말했다시피, 특정 코드를 쓰고 왜 이렇게 써야만 하는지에 대한 답을 찾지 못했다. 질문 섹션에 남겨보도록 하겠다.</li>
<li>React-inifinite-scroller 라이브러리를 사용하지않고 window event listener를 사용해서 구현했으면 더 좋았을 것 같다.</li>
</ul>
<h3 id="끝으로">끝으로...</h3>
<p>앞으로 매일마다 TIL을 올릴예정이고 최대한 각 블로그별로 내가 take-away할 수 있는 의미있는 내용들만 담아보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React| React-Hook-Form & Webkit 자동완성 문제]]></title>
            <link>https://velog.io/@moony_moon/React-React-Hook-Form-Webkit-%EC%9E%90%EB%8F%99%EC%99%84%EC%84%B1-%EB%AC%B8%EC%A0%9C</link>
            <guid>https://velog.io/@moony_moon/React-React-Hook-Form-Webkit-%EC%9E%90%EB%8F%99%EC%99%84%EC%84%B1-%EB%AC%B8%EC%A0%9C</guid>
            <pubDate>Tue, 15 Jun 2021 05:06:10 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/a5ab4716-aebc-4c04-ad48-4ba6819647e0/Eureka.jpeg" alt=""></p>
<p>FE 개발자로써 유효성 검사를 하다보면 되게 수고가 많아지는 경험을 하곤한다. 나도 첫 개인프로젝트를 진행할 때 commons 폴더에 function 하나를 빼놓고 해당 폴더안에서 이메일, 패스워드, 이름, 등 유효성 검사를 early exit 형태로 진행하도록 구현하였다.</p>
<p>특히, 이메일의 유효성 검사를 정규표현식으로 할 때가 가장까다로웠다. 물론, 다른 사람들이 보편적으로 만들어 놓은 유효성 검사를 위한 정규표현식도 있었지만 쓰기전에 이해하는 것이 중요하기 때문에 이해하고 구현하는데 꽤 애먹은 기억이있다.</p>
<p>이러한 유효성 검사 과정속에 form 자체를 버튼을 통해서 submit 하는 경우에 좀 더 쉽게 만들라고 나온 것이 </p>
<p><strong>REACT-HOOK-FORM</strong>이다.</p>
<p>React Hook form에는 다양한 API들이 있어 한번에 모두다 익히기에는 무리가 있다.
그렇기 때문에, 하나씩 써가면서 익혀가는 것을 추천한다.</p>
<p>오늘 내가 코드를 통해서 React-Hook-form 을 설명할 파트는 당연히 Validation Check (=유효성 검사)다.</p>
<p><img src="https://images.velog.io/images/moony_moon/post/d03fb847-1d3b-43ba-80ac-9257f224d5ef/Minions.gif" alt=""></p>
<p>React-hook-form에서 유효성 검사를 체크 할때에는
<img src="https://images.velog.io/images/moony_moon/post/5f7849a1-df5c-4bb6-ba98-462535477e08/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%201.25.51.png" alt=""></p>
<p>이런식으로 원하는 값을 불러온다. register의 역할은 원하는 input창에 원래 정의해 놓았던 FormValues라는 타입에 맞추어서 일치하는 key에다가 value를 계속해서 override하는 구조이다.</p>
<p>그렇게 overriding 하는 프로세스를 실시간으로 볼수있는게 watch()의 기능이고, submit했을 때 에러가 있는지 없는지 확인하고 성공했다면 입력된 데이터를 실시간으로 console을 통해 찍어볼 수 있는 함수가 handleSubmit이다.</p>
<p>또한 formState에는 많은 기능들이 내포되어있는데, formState에서 가장 빈번하게 쓰이는게 errors기능이다. errors는 에러가 발생한다면 어디 input에서 에러가 발생했고 만약 메세지를 담고 있으면 메세지또한 반환을 해준다.
<img src="https://images.velog.io/images/moony_moon/post/17b65f8e-4e39-4dde-aa45-6a9c933d1027/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%201.30.20.png" alt=""></p>
<p>여기서 required는 빈칸이 아니라 입력값을 무조건 줘야한다로 생각하면 좋다. 그리고 input의 성격에따라 pattern, minLength, maxLength 이런식으로 주고 실패한다면 전달할 메세지 또한 담을 수 있다.</p>
<p>이렇게 한다면 우리가 기존에 onChange 함수를 통해서 매번마다 [event.target.id]: event.target.value를 통해서 실시간으로 데이터를 state에 저장하고 저장한 state를 활용해서 validation check를 할 필요가 전혀없다.</p>
<blockquote>
<p>주의해야할 점</p>
</blockquote>
<p>그런데 이런 React-Hook-form의 default option은 처음에 실시간으로 error를 발생시켜서 보여주는게 아니라 한번 submit이 된 이후에 쭉 훑어서 에러가 있는 부분들을 감지한다. 그 부분들을 감지하고 난 이후에는 실시간으로 고치면 바로 에러 메세지가 없어지는 것을 확인할 수 있다.</p>
<p>만약 그런데,  Submit 하기 전부터 해당 기능을 구현하고 싶다면 어떻게 해야될까?</p>
<p>React-Hook-form의 isValid 옵션을 사용하면 된다. isValid 옵션을 활용하기 전에 useForm의 모드를 onChange로 바꾸어 줘야만 form submit 이전에도 발생한 에러부분들을 파악하고 메세지를 띄워줄 수 있다.
<img src="https://images.velog.io/images/moony_moon/post/ea5e5914-0578-4b99-8560-90c8e6c62c71/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%201.59.08.png" alt=""></p>
<p>formState안에 여러가지 기능들이 있으니 React Hook form 문서를 참고하길 바란다.</p>
<p><a href="https://react-hook-form.com/api">React Hook Form</a></p>
<p>또한, React-Hook-Form 외에 사소한 부분 한가지를 공유해보고자 한다.</p>
<p>Input창을 대개 만들고 아이디 및 패스워드란에 자동입력이 완성이 되면 내가 원하지 않는 background-color가 종종 뜨곤하는것을 볼 수 있다.
<img src="https://images.velog.io/images/moony_moon/post/6b1e0898-1699-493e-a802-71627bf414cd/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%202.02.04.png" alt=""></p>
<p>이런식으로 말이다. 이것은 autocomplete을 완성했을 때 webkit에서 default로 제공하는 background-color가 있고, 해당 부분을 끄고 싶다면 input의 webkit autofill 부분을 제어해야한다</p>
<p>제어하는 방법은 크게 두가지가 있는 것같다.</p>
<p>가장 간단한 방법은 자동완성 기능자체를 없애버리는 것이다.</p>
<pre><code class="language-javascript">&lt;input type = &quot;password&quot;, autocomplete= &quot;off&quot; /&gt; </code></pre>
<p>이런식으로 자동완성(autocomplete)을 끄면 아애 저런 박스가 형성될 수 조차 없다. 그런데 자동완성을 끈다면 UX 측면에서도 좋지 않은 경험을 할 수 있기 때문에 자동완성을 살리면서 background-color를 제어할 수 있는 방법을 살펴보니,
...</p>
<pre><code class="language-javascript">  :-webkit-autofill,
  :-webkit-autofill:hover,
  :-webkit-autofill:focus,
  :-webkit-autofill:active {
    transition: background-color 5000s ease-in-out 0s;
    -webkit-transition: background-color 9999s ease-out;
    -webkit-box-shadow: 0 0 0px 1000px white inset !important;
    box-shadow: 0 0 0px white inset !important;
    -webkit-text-fill-color: #fff !important;
  }</code></pre>
<p>이렇게 webkit의 autofill의 box-shadow 및 background color를 아애 투명하게 해버리는 방법이 있다. 만약 나중에 나와 비슷한 경험을 한다면 참고하면 좋을 것 같다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL React | 회원가입/로그인 -1]]></title>
            <link>https://velog.io/@moony_moon/TIL-React-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85%EB%A1%9C%EA%B7%B8%EC%9D%B8-1</link>
            <guid>https://velog.io/@moony_moon/TIL-React-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85%EB%A1%9C%EA%B7%B8%EC%9D%B8-1</guid>
            <pubDate>Mon, 07 Jun 2021 10:05:28 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/cc1fb1cd-2a08-414a-9039-e3d55e5c9651/TIL_React.png" alt=""></p>
<p>오늘은 모든 홈페이지에는 거의 무조건 있다는 회원가입/로그인에 대해서 알아보겠다. 모든 홈페이지에서 회원가입/로그인 기능이 있기 때문에 비전공자 입장에서는 구현이 그리 어렵지 않을 거라 생각했지만....</p>
<p>태초마을로 가서 회원가입/로그인의 초기부터 살펴보자.</p>
<h3 id="회원가입">회원가입</h3>
<p>회원가입을 할 때에는 요즘에는 OAuth를 통해 (즉, 소셜로그인)을 통해서 많이 하지만 전통적인 방식에서는 아이디/패스워드를 입력하고 회원가입을 등록을 했다.</p>
<p>그 과정에서 비밀번호를 개발자들이 알고 있다면 이것은 크나큰 문제가 될 수 있다. 보통 개인이 한 사이트에서 사용하는 ID 및 비밀번호는 다른 사이트들에서도 사용될 수 있기때문에 서버를 관리하는 개발자들이 개인정보를 남용할 수 있는 경우의 수가 높아진다.</p>
<p>그래서! 비밀번호를 입력해서 DB로 받을 때 비밀번호는 해쉬함수를 통해서 암호화가 된다. 해쉬는 비밀번호를 랜덤한 숫자 및 문자로 변환시켜 서버에서 데이터를 받을 때 랜덤한 형태로 숫자로 return되는 역할을 해준다.</p>
<p>암호화의 종류에는 양방향과 단방향 두가지로 나뉘었다.</p>
<p>양방향에는 암호화와 복호화(인코딩된 번호를 원래 번호로 디코딩하는 프로세스)가 있었는데</p>
<p>보안이슈와 해쉬가 나온 이후부터는 복호화에 대한 개념이 회원가입에서는 필요없어졌다.</p>
<p>단방향 암호화에는 3가지 방식으로 크게 나뉘어진다.</p>
<p>Session/ Token/ Token &amp; Refresh 방식</p>
<p>-&gt; Session : 세션은 유저가 회원가입 정보를 입력해서 서버에 저장하는 방식을 말한다. 기존에는 이렇게 하게 되면 2가지 문제점이 생긴다.</p>
<ul>
<li>확장성에 문제가 생긴다. 확장성 문제란 회원가입 정보를 서버에 저장하면 특정 서버에만 저장이 된다. 그렇다면 로그인을 시도할 때마다 백엔드 쪽에서는 특정 서버를 통해서만 인증이 가능하다는 이야기인데, 그 서버안에 갑자기 엄청많은 유저가 한번에 인증을 시도한다면? 바로 서버 과부화가 발생하면서 서버가 down되는 현상까지 발생할 수 있다. 물론 똑같은 서버를 여러개 만들어서 샤딩을 할 수 있지만 그 과정자체가 복잡하다.</li>
<li>서버 과부화 문제가 생긴다.적은 데이터량은 받은 서비스라면 문제가 없겠지만 페이스북과 같은 대형회사라면 어마어마한 유저 인증정보가 세션에 저장이되고 서버과부화 현상이 일어날 수 밖에 없다.</li>
</ul>
<blockquote>
<h3 id="session의-특징-상태를--서버에-저장하고-그-기반으로-움직인다">Session의 특징: 상태를  서버에 저장하고 그 기반으로 움직인다.</h3>
</blockquote>
<p>-&gt; Token: 해당 문제점을 해결하기 위해서 나온 게 Token이다. 토큰은 stateless, 즉 상태유지를 하지 않는다는 점에서 굉장히 유용하다. 토큰은 로그인 정보를 기입하면 서버에서 토큰을 발급한다. 이 과정에서 토큰은 DB에 인증정보를 저장하고 로그인할 때마다 원하는 서버에 정보를 저장시키고 클라이언트에 뿌려준다.</p>
<ul>
<li>Token 형식은 저장을 만약에 DB에도 하지 않는다면 과부화 문제도 없다 (다만, 현업에서는 DB에 보통 저장을 한다).</li>
<li>또한, 특정 서버에 접근해야만 데이터인증을 받을 수 있는 구조가 아니기 때문에 유동적으로 어느 서버에서든지 인증을 진행 할 수 있다.</li>
</ul>
<p>Token 과정을 요약하자면,</p>
<ol>
<li>유저가 아이디와 비밀번호를 로그인 하면,</li>
<li>서버에서는 아이디와 비밀번호를 확인한 이후에 토큰을 발급한다.</li>
<li>발급된 토큰을 클라이언트 local 저장소에 저장해서 요청을 할때마다 http headers파트에 같이 보내준다.</li>
<li>받은 토큰을 기반으로 서버에서 response를 한다.</li>
</ol>
<p>여기서 더 추가된게 Token &amp; Refresh 토큰 방식이다.</p>
<p>특정시간이 지나면 Token을 만료시키고, 만료연장을 한다면 토큰을 refresh해서 보내주고 해당 토큰으로 request &amp; response를 한다. </p>
<p>Token을 만료시키는 이유는 보안의 문제가 가장 크다고 생각한다. 특정 유저가 우연의 일치로 accessToken을 맞추더라도 특정시간이 지나면 token이 만료되는 형태로 보안을 높이는 것이다.</p>
<p>로그인과정에서 토큰을 받아내고 그 토큰을 받아서 어떻게 전역에 적용시킬 수 있는지 코드를 통해서 다시한번 복기해보자.</p>
<p>회원가입 같은경우는 특별한 파트는 없다. 그냥 백엔드에 mutation을 통해서 원하는 값들을 전달해 주면 된다. 그리고 저장된 id/password를 로그인할 때 조금 다르다.</p>
<p>-&gt; mutation을 활용하여서 로그인페이지에서 accessToken을 받아내야한다.
-&gt; 해당 accessToken을 app_tsx에서 활용해서 모든 컴포넌트에 적용되어 headers에 포함되어야한다.
-&gt; 그렇기 때문에 여기서 전역변수가 활용된다. (Context API)</p>
<pre><code class="language-javascript">export const GlobalContext = createContext({
    accessToken: &#39;&#39;,
      setAccessToken: (_: any) =&gt; {}
})

function MyApp({Component, pageProps}: AppProps) {
    const [accessToken, setAccessToken] = useState(&#39;&#39;)
    const uploadLink = createUploadLink({
      uri: &#39;....&#39;,
      headers: {
        authorization: `Bearer ${accessToken}`
      }
    })

    return(
    //여기서 ContextAPI를 적용시킬 곳을 선택한다. 
      &lt;GlobalContext.Provider value = {{accessToken: accessToken, setAccessToken: setAccessToken}}&gt;
      &lt;ApolloProvider client = {client}&gt;
        &lt;Component {...pageProps}&gt;
      &lt;/ApolloProvider&gt;
&lt;/GlobalContext.Provider&gt;
    )</code></pre>
<p>이렇게 전 컴포넌트에 지정해준후에 원하는 state를 자식컴포넌트에서 바꿔도 부모컴포넌트에서 사용할 수 있다.<img src="https://images.velog.io/images/moony_moon/post/fa05b301-5203-456d-b9dd-d4b422adb033/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-07%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%207.00.58.png" alt=""></p>
<p>setAccessToken이 바뀌고 로그인을 할 때 변경되면 끝!!!</p>
<p>원하는 페이지에서 로그인되있는지 안되어있는지 확인하는 방법은
useEffect를 통해서 걸러낼 수 있다.</p>
<p><img src="https://images.velog.io/images/moony_moon/post/e1cc447b-5b53-4dd0-b913-d3f89ec089c7/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-07%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%207.03.23.png" alt="">이런식으로 써줄 수 있다. 그런데 페이지가 생길 때마다 이렇게 써주는건 조금 비효율적이어보인다. 그래서 다음에는 HOC(Higher order component)를 통한 권한분기에 대해서 좀 더 자세하게 알아보겠다.</p>
<p>회원가입/로그인에대해서 알아보았는데 굉장히 재밌다!!</p>
<p>아직 추가하지 못한 부분이 많다. 예를 들어서, validation 파트에서 정규표현식을 활용해서 걸러내는 방법 이런 부분들도 조금 더 꼼꼼하게 하나씩 추가해볼 생각이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL React  | 검색기능]]></title>
            <link>https://velog.io/@moony_moon/React-%EA%B2%80%EC%83%89%EA%B8%B0%EB%8A%A5</link>
            <guid>https://velog.io/@moony_moon/React-%EA%B2%80%EC%83%89%EA%B8%B0%EB%8A%A5</guid>
            <pubDate>Mon, 07 Jun 2021 00:54:13 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/18767d21-6661-46c3-8691-88002a19977a/TIL_React.png" alt=""></p>
<blockquote>
<p>모든 코드에 의미를 담겠습니다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/moony_moon/post/760593aa-3fbc-43f8-ae50-8c3827701265/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-07%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%209.39.36.png" alt=""></p>
<p>지금까지 내가 구현한 자유게시판에는 Pagination 기능과 게시물을 등록할 수 있는 기능까지만 올림차순으로 정리해놓고 내용을 클릭하면 등록한 게시판으로 넘어갈 수 있는 구조를 만들어 놓았다.</p>
<p>여기서 금일에 추가한 내용은 검색을 하였을 때 원하는 제목에 따라서 게시판이 re-rendering되게끔 하는 것이다.</p>
<p>처음에 구상은 굉장히 단순했다. Search Input창을 하나 만들고 Input value들을 state에 담아서 그 state를 클릭했을 때 마다 graphql의 기능을 사용한 refetch가 실행되면 될 것 같았다.</p>
<p>그렇게 구현하고 나서 만든 UI가 아래와 같았다.<img src="https://images.velog.io/images/moony_moon/post/b2a05687-c17d-4037-b1a4-87e6ae2c5d9d/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-07%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%209.43.38.png" alt=""></p>
<p>분명 이렇게 검색창에 검색하고싶은 제목을 넣으면 제목들이 list형태로 나왔고 1페이지 까지는 괜찮았다. 하지만!, 2페이지를 누르는 순간부터 내가 원하는 제목이 아닌 refetch되기전 페이지의 리스트들이 나오는 것이다.</p>
<p>코드를 한번 살펴보자.
<img src="https://images.velog.io/images/moony_moon/post/2dc5e9e9-d9bb-4bdf-9816-6595fc261cde/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-07%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%209.46.43.png" alt=""></p>
<p>원래 코드는 위와 같았다. 정의된 두개의 state의 변화에따라서 page가 변하는 것이었는데 문제는 2페이지를 클릭할때마다 currentPage도 같이 바뀌면서 hook이 useQuery문을 건드는 것이다. 그렇게 되면 refetch의 값을 불러오는게 아니라 useQuery의 값을 2페이지 부터 보여줄 수 밖에 없는것이다.</p>
<p>결론은, refetch를 사용하되 처음에 렌더링되는 useQuery문은 최대한 state를 건드리지 않고 렌더링을 하게끔 해야한다.</p>
<p>그래서 page에는 하드코딩으로 1을 입력해주고 페이지를 클릭할때마다 모든 경우에서 refetch가 되게끔 하면 되는것이다.</p>
<p>코딩은 굉장히 간결하게 해결할 수 있지만, 이것을 사고하는 과정까지는 엄청힘든 것 같다.</p>
<p><img src="https://images.velog.io/images/moony_moon/post/f6487f9f-d67a-4b04-b191-130037056182/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-07%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%209.51.12.png" alt=""></p>
<p>React 혹은 Javascript의 기능들의 동작원리를 더 깊게 공부해야 응용을 할 수 있겠다는 생각이 들었다. 만약 내가 state를 변경한다면 변수를 포함하고 있던 hook이 변경된다는 걸 알았다면 처음부터 페이지네이션에서 그런 부분들을 고려하여 조금 더 깔끔하게 코딩하지 않았을까라는 생각을 하게 된다.</p>
<p>그래서 앞으로 지하철 출퇴근길에는 React 및 Javascript 이론 영상 위주로 시청을 하려고 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL React | 이미지 처리  - 2]]></title>
            <link>https://velog.io/@moony_moon/React-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC-2-mzc7fcjd</link>
            <guid>https://velog.io/@moony_moon/React-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC-2-mzc7fcjd</guid>
            <pubDate>Fri, 04 Jun 2021 08:41:24 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/f5ef6b8d-b049-469d-9b59-08e9225c2a50/ezgif.com-gif-maker%20(1).gif" alt=""></p>
<p>금일은 이미지 처리를 하는데에 아침 점심을 모두 다썼다. 조금 늘었다고 생각을 했지만 이미지 처리 알고리즘 짜면서 밤을 새면서 더 해야겠다는 생각이 들었다.</p>
<p>구현 기능 (이미지 처리)</p>
<ol>
<li>이미지 업로드 버튼 박스가 Default 값으로 3개를 게시물 등록페이지에서 보여준다.</li>
<li>이미지 업로드 버튼 박스를 클릭했을 때 버튼 박스는 없어지고 이미지와 함께 Cancel 버튼도 같이 보여준다 - Challenge 파트: 업로드를 3번째에서 했고 첫번째 박스가 비어져 있다면, 첫번째 박스 위치로 이미지가 옮겨져야한다.</li>
</ol>
<ol start="3">
<li>Cancel 버튼을 클릭했을 때 이미지는 없어지고 이미지 업로드 버튼 박스가 다시 보여져야한다. - Challenge파트:  지워진 위치 다음 박스에 이미지가 있다고 해당 이미지는 앞으로 당겨져야 한다.</li>
</ol>
<p>사람마다 하는 방식은 너무나도 다르기 때문에 난 나만의 방식으로 풀어보겠다.</p>
<p>우선, 이미지 컴포넌트를 하나 만들어서 Map을 돌려 3개를 만드는 게 훨씬 효율적일 것 같아서 이미지 업로드 컴포넌트를 presenter, container, query, style 파트로 나눠서 코드를 작성하기 시작했다.<img src="https://images.velog.io/images/moony_moon/post/d1cecebd-dec7-41cd-aed9-3ec83a8397cd/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-04%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.18.43.png" alt="">이미지를 나눈후에 컴포넌트를 부모 컴포넌트 presenter에 붙여서 map을 돌렸다</p>
<pre><code class="language-javascript">const [fileUrl, setFileUrl] = useState([]) // 부모컴포넌트에서 파일 Url을 받아올 배열을 생성한다
{props.fileUrl.map((data: any) =&gt; (&lt;WriteImage key =&quot;&quot; data = {data} setFileurl = {props.setFileUrl} fileUrl = {props.fileUrl}&gt;&lt;/WriteImage&gt;
))} // fileUrl의 배열 length 에따라서 fileUrl WriteImage를 그려준다.
{new Array(3- props.fileUrl.length).fill(1).map((_, index)) =&gt; (
  &lt;WriteImage
  key = &quot;&quot;
  data = &quot;&quot;
  setFileUrl = {props.setFileUrl}
  fileUrl = {props.fileUrl}
&gt;&lt;/WriteImage&gt; // 이미지에서 fileUrl이 없는 수만큼 그에 알맞는 data를 데이터를 그려준다. 여기서는 data는 &quot;&quot;, 즉 빈값이다.
</code></pre>
<p>이렇게 자식컴포넌트에 넘겨주고 data라는 컴포넌트를 활용해서 자식 컴포넌트에서 컴포넌트에 삼항연산자를 사용해 원하는 html &amp; css를 보여준다.</p>
<p><img src="https://images.velog.io/images/moony_moon/post/9fc31132-0f29-4387-acaa-ee8a4c0b2d42/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-04%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.28.32.png" alt=""></p>
<p>파일을 클릭했을 때 실행되는 함수구조이다.  file을 읽어오는 코딩과 온로드 되었을 때로 나누는데 온로드 되었을 때 기존의 fileUrl 의 배열을 얕은복사하고 업로드한 이미지 주소를 붙인다. 그리고 event.target.value를 &#39;&#39;로 할당해서 초기화하는 이유는 배열에 이미 주소값이 들어가 있고 초기화해주지않으면 이미지를 업로드하고 삭제하고 다시 업로드 하려고 할때 만약에 주솟값이 전에 업로드한것과 같다면 업로드가 되지않는다!</p>
<p>그이유는 event.target.value가 그대로 onChange함수에 기억되어있기 때문에 그렇다. 그래서, event.target.value를 초기화 시켜주는것이 중요!!</p>
<p><img src="https://images.velog.io/images/moony_moon/post/68893193-6aaf-4c38-b94c-329890789ef5/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-04%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.33.15.png" alt=""></p>
<p>지금 여기서 빨간줄은 ESlint이니 무시해도 좋을 것 같다(나중에 고쳐보자 ㅠ). 여기서 어떤 컴포넌트를 불러올지 결정되는 것이다. mapping할 때 데이터가 존재하는 것이면 UploadImageContainer를 불러오고 해당 Image는 props.data가 되는 것이다. 삼항 연산자 조건은 그렇기 때문에 만약 props.data가 존재한다면 UploadImageContainer 를 불러오고 그게 아니라면 UploadButton을 불러오는것이라고 보면 되겠다.</p>
<p>이렇게 코드를 짜게되면 이미지를 3번째에서 업로드를 해도 첫번째 업로드박스가 비어있더라도 차례대로 쌓이게 된다.</p>
<p>그리고 차례대로 삭제하는 로직은 filter보다 splice함수를 사용해서 빼야한다. 로컬저장소에서 url을 불러오는 것이기때문에 똑같은 이미지를 업로드하게되면 주소가 같다. 그래서 filter를 통해서 props.data가 같지 않는것을 뽑아내면 같은 이미지들은 다 지워진다.
그래서 splice함수를 사용하는 것이다.
<img src="https://images.velog.io/images/moony_moon/post/f5833cbe-1890-4aef-a608-f1cee53fa810/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-04%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.38.43.png" alt=""></p>
<p>이렇게 원래 배열을 받을 수있는 변수를 설정하고 배열을 담는 변수에대해서 splice를 한 이후에 aaa로 바꾸면 된다.</p>
<p>이렇게 개발일지를 작성하다면 확실히 코딩짜는 흐름을 한번 정리할 수 있고 확 기억에 남는 것 같다. 또, 쉬운것 같은데 왜 이렇게 올렸지라는 생각이 든다. 이렇게 계속 노력하다면 능숙한 FE개발자가 될 수 있으리라 다시 한번 굳게 다짐하면서... 글을 마친다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Infinite Scroll & CSR & SSR]]></title>
            <link>https://velog.io/@moony_moon/Infinite-Scroll-CSR-SSR</link>
            <guid>https://velog.io/@moony_moon/Infinite-Scroll-CSR-SSR</guid>
            <pubDate>Wed, 02 Jun 2021 16:54:04 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/ab7105b1-35f1-4094-aa07-e918f2f2c735/Eureka.jpeg" alt=""></p>
<blockquote>
<p>모든 코드에 의미를 담겠습니다.</p>
</blockquote>
<p>지금 내가 구현하는 기능중에 꽤나 유용했고 알아두면 좋은 기능들을 정리하면서 개발일지에 한번 정리해보려고 한다.
그런것들은 위와 같이 유레카 이미지가 들어가 있고, TIL과는 다른 개발일지로 구분이 될 것 같다.</p>
<blockquote>
<p> 오늘의 유레카!!!</p>
</blockquote>
<p>무한 스크롤(Infinite) &amp; CSR &amp; SSR 부분. </p>
<blockquote>
<p>무한스크롤...</p>
</blockquote>
<p>이 부분은 내가 쓰게 된 이유에 대해서 고민하게 되었다. 왜 굳이?? 써야하는가? 그냥 데이터를 한번에 받아와서 특정 height를 주고 overflow: hidden을 app_tsx파일 전체에 적용을 하면, 나머지 데이터들은 스크롤을 내릴 때 받아오지 않는가?</p>
<p>당연히 이런 방법도 작은 서비스의 회사이거나 아니면 뿌려줄 데이터 양이 적을 경우에는 좋다. 하지만, 한번에 백엔드를 통해 받아와야하는 데이터의 양이 페이스북 같은 거대기업이라면? 그런 회사가 아니더라도 데이터를 한번에 뿌려줄때 서버사이드에서 부담이 되는 곳이라면  무한스크롤을 사용해야 한다.</p>
<h3 id="무한-스크롤-동작원리">무한 스크롤 동작원리</h3>
<p>백엔드 쪽에서 보통 무한 스크롤 및 다양한 Pagination 활용을 위해서 보통 page별로 데이터를 나누고 한 페이지에는 10개 혹은 6개 정도의 데이터가 들어간다.</p>
<p>데이터를 받고나서 처음에는 page 1번의 데이터를 먼저 뿌려주고 Apollo-graphql기준으로는 fetchMore 그리고 updateQuery 함수를 써서 데이터를 다보여주고 해당 데이터를 추가로 보여준다.</p>
<p>코드를 통해 살펴보자.</p>
<pre><code class="language-javascript">const [page, setPage] = useState(1) //백엔드에 request할때 페이지 숫자

const onLoadMore = () =&gt; {
      if(!commentData) return
      if(commentData?.fetchBoardComments?.length % 10 !== 0) return 
    fetchMore({
        variables: {
            boardId: String(router.query._id),
              page: Math.floor(commentData?.fetchBoardComments.length /10) + 1
        },
    updateQuery: (prev, { fetchMoreResult }) =&gt; {
          const aaa = Object.assign({}, prev, {
          fetchBoardComments: [
            ...prev.fetchBoardComments,
            ...fetchMoreResult.fetchBoardComments
            ]
        })

        return aaa
    }
})</code></pre>
<p>여기서 중요한점은 onLoadMore 안에 함수에서 최대한 setState를 사용하지 않고 풀어나가야 한다. 이유는 정확하게 아직 파악하지 못했는데 라이브러리의 함수와 꼬여서 원하는 값을 정확히 반환하지 못한다 (아시는 분은 이유좀...)</p>
<p>Infinite Scroll의 return 부분은 library를 사용해서 특별히 다를 건 없다.</p>
<p>무한 스크롤을 사용하는 이유와 그 원리를 조금 이해한것 같아서 기쁘다. 시간이 된다면, infinite scroll 구현을 직접 모달창과 함께 해보고 싶은 마음이다.</p>
<blockquote>
</blockquote>
<p>클라이언트 사이드 렌더링 vs 서버 사이드 렌더링</p>
<p>이 두 렌더링은 항상 나오는 이야기인것 같다. 서버 사이드 렌더링은 데이터에 변화가 있을 때마다 응답을 받아와줘서 컴포넌트를 다시 그리는 형태이다. </p>
<p>서버사이드는 렌더링은 보통 데이터 변경이 필요해서 통신을 할 때를 제외하고는 나머지 부분들은 클라이언트 사이드 렌더링에서 해결을 하는게 좋다. </p>
<p>서버에 요청을 최대한 많이 하지않는 프론트엔드 개발자가 좋은 개발자다!!!!</p>
<h4 id="서버사이드-렌더링-보통-seo-나-og태그를-활용해서-slack이나-카카오톡이-해당-정보를-채팅에서-간략하게-보여줄-때-사용을-해야한다">서버사이드 렌더링: 보통 SEO 나 OG태그를 활용해서 slack이나 카카오톡이 해당 정보를 채팅에서 간략하게 보여줄 때 사용을 해야한다.</h4>
<p>SEO같은 경우, 검색봇이 웹페이지들을 돌아다니면서 curl을 한다. 클라이언트 사이드 렌더링은 curl을 할경우 (React 기준) javascript 문법만 들어와서 검색봇이 해석을 하지 못한다. (실제로 내용들이 id=&#39;root&#39; 형태로 들어옴). 그래서 개발한 게 next.js 프레임워크다 (React 기능 + server side rendering 기능 추가)</p>
<h4 id="클라이언트사이드-렌더링-대표적인-프레임워크가-react이다">클라이언트사이드 렌더링: 대표적인 프레임워크가 React이다.</h4>
<p>서버사이드 렌더링과 다르게 데이터를 받아올 때마다 html &amp; css 페이지를 렌더링하는게 아니라 서버사이드에서 한번에 html &amp; css를 다 받아오고 요청에 대한 응답이 올 때 리소스를 추가 또는 제거를 해주는 형식이다.</p>
<p>이 내용을 다루는 이유는 무엇인가?</p>
<blockquote>
<p>라이브러리에서 가끔씩 이미지데이터나 내용을 받아올때 서버사이드에서 그려주지 못하는 경우가 있다.</p>
</blockquote>
<p>맨처음 클라이언트 사이드렌더링이 작동을 하려면 서버사이드에서 먼저 html 을 그려주고 클라이언트 사이드 렌더링의 html 그려준것과 비교한 이후에 같다면 그려주는 형태인데, 라이브러리는 서버사이드 렌더링을 할 때 문제가 있는 경우가 있다.</p>
<p><img src="https://images.velog.io/images/moony_moon/post/2cc13656-e92c-492a-b751-584f5855c398/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-03%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%209.49.57.png" alt=""></p>
<p>위와같이 typeof window 자체가 undefined가 아니면 클라이언트사이드 렌더링을 의미하는 것이고, 서버사이드렌더링은 undefined을 의미한다. 그래서 클라이언트 사이드 렌더링을 한다면</p>
<pre><code class="language-javascript">typeof window !== &#39;undefined&#39; &amp;&amp; (...)</code></pre>
<p>위 코드를 작성해주고 라이브러리를 사용해야한다. 서버사이드 렌더링이 안되는 몇몇개는 새로고침을 했을 떄 이미지같은 게 제대로 작동하지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 이미지 처리과정과 방법]]></title>
            <link>https://velog.io/@moony_moon/TIL-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC%EA%B3%BC%EC%A0%95%EA%B3%BC-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@moony_moon/TIL-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC%EA%B3%BC%EC%A0%95%EA%B3%BC-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Wed, 02 Jun 2021 02:23:39 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/53fb3f42-5b0b-48b6-8019-2a697e5322f5/TIL_React.png" alt=""></p>
<blockquote>
<p>모든 코드에 의미를 담겠습니다.</p>
</blockquote>
<p>금일은, 이미지를 어떻게 백엔드에 요청을해서 응답을 받아오는 지 한번 알아보자!!</p>
<p>현재 내가 사용하고 있는 기술 스택은 next.js(react.js)를 통해 Apollo-graphql을 통해서 백엔드 API와 통신을 해서 데이터를 받아오고 있다.</p>
<p>데이터를 Read하는 경우를 제외하고는 Apollo-graphql에서는 mutation을 이용한다. 그래서 이미지를 업로드할때도 그냥 <strong>똑같이 Mutation을 하면 되는 줄 알았다</strong>. </p>
<p>그러나 이미지 &amp; 동영상 같은 경우는 보통 용량이 큰 경우가 많다. 백엔드 DB에 저장하기에는 이미지 하나당 5MB이렇게 공간을 차지하는 경우가 너무 많은데 텍스트를 받아 저장하는 DB와 묶는건 사실 불가능한 일이다.</p>
<p>그래서!!! <img src="https://images.velog.io/images/moony_moon/post/3da24e8e-0d32-4a08-b063-f7d0d8cbeed2/Minions.gif" alt=""></p>
<blockquote>
</blockquote>
<p>이미지는 스토리지라는 저장공간(쉽게말해,  저장공간이 큰 C드라이브라고 보면 좋을 것 같다.)에 보관을 해둔다. 우리가 아는 유명한 스토리지는 AWS S3 or GCP(Google Cloud Platform) 와 같은것이 있다.</p>
<p>이미지처리 프로세스는 그래서 이와 같다.</p>
<p>클라이언트(Frontend) -&gt; API(백엔드) -&gt; 스토리지</p>
<p>스토리지 -&gt; API(백엔드) -&gt; 클라이언트(프론트엔드)</p>
<p>이런구조인데</p>
<p>apollo-graphql을 통해서 스토리지에도 저장을 하고 DB에도 저장을 해야한다. DB에 저장하는 url은 그냥 텍스트일 뿐이고 클라이언트에서 요청을 할 때 DB에서 보유하고 있던 url을 스토리지에서 식별을해서 스토리지에서 이미지를 클라이언트에 뿌리는 역할을 한다.</p>
<p>자 이론적인 개념은 여기까지고 실제로 어떻게 연결을 하여 데이터를 추가하고 불러오는 지 한번 확인해보자.</p>
<p>내가 백엔드와 통신하는 API는 Apollo-graphql이기 때문에 REST-API로 하시는 분들은 참고만 하시되 REST-API 통신형태로 하는 게 좋을 것 같다.</p>
<h2 id="이미지-처리-프로세스">이미지 처리 프로세스</h2>
<ol>
<li><p>아폴로 업로드 클라이언트를 설치한다 (yarn install apollo-upload-client). 아폴로 업로드 클라이언트를 설치할 때 node 버전을 확인해서 다운을 받아줘야한다. 나는 node 버전이 아폴로 클라이언트와 호환이 되지않아 버전 업그레이드를 했다 ㅠ </p>
</li>
<li><p>아폴로 클라이언트를 타입스크립트에서 읽을 수 있게 끔 <strong>yarn add -D @types/apollo-upload-client</strong> 한다.</p>
</li>
</ol>
<p>3.</p>
<pre><code class="language-javascript">//우선 _app.tsx or _app.js파일에 upload기능을 추가시켜줘야한다.

import {createUploadLink} from &#39;apollo-upload-clinet&#39;

function MyApp({ Component, pageProps}) : AppProps (타입스크립트 타입 선언) {
    const uploadLink = createUploadLink({
    uri: &#39;http://backend.codebootcamp.co.kr/graphql&#39;
    })

    const client = new ApolloClient({
    link : ApolloLink.from([uploadLink as unknown as ApolloLink]),
    cache: new InMemoryCache()
    })

    return (
        &lt;ApolloProvider client = {client}&gt;
              &lt;Component {...pageProps} /&gt;
        &lt;/ApolloProvider&gt;
)
}

export default MyApp

</code></pre>
<p>4.</p>
<pre><code class="language-javascript">import {gql, useMutation} from &#39;@apollo/client&#39;
import {useRef, useState} from &#39;react&#39;


const ImagePage = () =&gt; {
  const [myImage, setMyImage] = useState(&#39;&#39;)
  const [file, setFile] = useState(&#39;&#39;)
  const fileRef = useRef&lt;HTMLInputElement&gt;(null)

  const onChangeFile = (event:any) =&gt; {
    const file = event.target.file[0] //배열로 묶여있기때문에 0번째를 불러와야한다.
    if(!file.type.includes(&#39;png&#39;)) {
        alert(&#39;png파일만 가능합니다&#39;)
      return
    }
    if (file.size &lt; 5 * 1024 * 1024 // 5MB를 의미함) {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload= (event) =&gt; {
        if(event.target) setMyImage(String(event.target.result))
    }
  } else {
    alert(&#39;파일이 너무 큽니다 (5MB 제한!)&#39;)
    return 
  }
  setFile(file)
}

  const onClickImage = () =&gt; {
    fileRef.current.click()
  }

  const onClickImageFile = async() =&gt; {
    try{
    const result = await Promise.all([
          uploadFileMutation({ variables: {file : file} }),
        uploadFileMutation({ variables: {file : file} }),
          uploadFileMutation({ variables: {file : file} }),
          uploadFileMutation({ variables: {file : file} }),
      ]) //이런식으로 쓰면 비효율적이니 map으로 받아서하는 것도 방법이다. new Array(4).fill(1).map(() =&gt; uploadFileMuation({variables: {file: file}})

  return (
    &lt;div&gt;
        &lt;button onClick = {onClickImage}&gt; 이미지 &lt;/button&gt;
        &lt;input type =&quot;file&quot; ref = {fileRef} onChange = {onChangeFile style = {{display: &#39;none&#39;}}
        /&gt;
//여기서 input type의 attribute에 display none을 준 이유는 file 형태의 input 고정 html&amp;css을 javascript에서 제공해주기 때문에 원하는 형태로 변경을 하기가 힘들다.
//그렇기 때문에 버튼이미지를 만들어서 클릭했을 때 useRef 함수를 이용해서 input 태그에서 작동하는 모든 함수를 실행시킨다.
    &lt;img src = {myImage} style = {{ width : &#39;1000px&#39;, height: &#39;600px&#39;}} /&gt;
    &lt;button onClick = {onClickImageFile}&gt; 서버에 파일전송하기 &lt;/button&gt;
&lt;/div&gt;
)
}

export default ImagePage</code></pre>
<p>결과물
<img src="https://images.velog.io/images/moony_moon/post/39ef1bad-5333-4a68-bd93-ff81611a162e/ezgif.com-gif-maker.gif" alt=""></p>
<p>간단해보이지만 굉장히 유용하게 쓰일 수 있는 방법같다. 피드백은 언제든지 Welcome입니다 !!!!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - Layout, Global Styles]]></title>
            <link>https://velog.io/@moony_moon/TIL-Layout-Global-Styles</link>
            <guid>https://velog.io/@moony_moon/TIL-Layout-Global-Styles</guid>
            <pubDate>Sun, 30 May 2021 22:48:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/407e581d-11ed-4a28-b2c8-8d1dc87759b2/TIL_React.png" alt=""></p>
<blockquote>
<p>모든 코드에 의미를 담겠습니다.</p>
</blockquote>
<p>오늘은 내가 이해한 바의 LayoutOut, Global Styles에 대해서 이야기 해보겠다. 물론 피드백은 환영.. 제발요..
.<img src="https://images.velog.io/images/moony_moon/post/1db4d4a0-168a-4f83-abe4-c6cdeae447be/Minions.gif" alt=""></p>
<p>지금까지 내가 개인 실습 프로젝트를 자유게시판을 만들면서 Layout을 사용하지 않았다. Presenter/Container 폼으로 컴포넌트들을 잘게 쪼개어서 재사용성 및 state에서 렌더링이 여러번 되는것에 대해서 고민을 많이 하였지만, HTML, CSS 파일하나를 제대로 만들어놓고 범용적으로 사용해야겠다는 생각을 하지 못했다.</p>
<p>그런 범용성을 높여주는게 레이아웃!!</p>
<p>우리가 홈페이지를 만들때 구조가 변하지 않는 컴포넌트들을 자세히 보면 알 수 있다.
<img src="https://images.velog.io/images/moony_moon/post/007e0acc-00d7-4d64-9256-a99869f5f174/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-31%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%207.30.40.png" alt=""></p>
<p>가령 위의 카카오페이지를 보면 상단 헤더부분은 어떤 탭을 눌러도 변하지 않는다는것을 알 수 있다.</p>
<p>그렇다면 이런 헤더를 컴포넌트 하나를 만들때마다 적용하는게 아니라 렌더링될 때 가장 먼저 실행되는 파일인 _app.tsx파일에 적용할 수 있으면 얼마나 좋을까? </p>
<p>그렇게해서 만들어진게 레이아웃이라고 보면 좋을 것 같다.</p>
<p><img src="https://images.velog.io/images/moony_moon/post/9caf659c-994b-4403-bb60-ac94437eb66b/_2021-05-27__11.30.09.png" alt=""></p>
<p>사용법은 위와같다. 모든 페이지를 렌더링하는 Component를 LayOut이라는 컴포넌트로 감싸면 되는 것이다. 굳이 Layout이라고 컴포넌트 명을 안지어도 되고 그냥 관례라고 보면 될 것같다.</p>
<p>그러면 레이아웃 폴더구조는 어떻게 될까? 내가 현재 실무에서 뛰고 있진 않지만, 현재 개발멘토님의 말씀과 다른 실무자들의 velog를 염탐했을 때....</p>
<p>Header, Body, Footer로 나누고 그 나눈파일을 layout폴더의 index.tsx에 합치는 구조가 가장 이상적인 것 같다.
<img src="https://images.velog.io/images/moony_moon/post/73344aa7-fe7a-456c-8af1-48464e499257/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-31%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%207.39.19.png" alt=""></p>
<p>이렇게 만들고 index파일에서는 렌더링될 각기 다른 페이지들이 children으로 상속이된다. 보통 Body파트 경우를 많이 일컫고 페이지 부분은 마진 혹은 패딩을 통해 여백을 주는정도로만 사용이 된다.</p>
<p><img src="https://images.velog.io/images/moony_moon/post/d14538c5-122c-4e40-a3b6-a507589367b7/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-31%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%207.42.15.png" alt=""></p>
<p>위와같이 Layout을 짜주고 app 파일에 적용하면 좋다. 이제는 Global styles에 대해서 알아보자.</p>
<p>Globalstyles 같은 경우는 페이지 전체에 style을 적용하는 것이라고 보면 좋을 것 같다. 다만, 하위 컴포넌트 단에서 개별로 스타일을 또 줄경우에는 globalstyles가 적용되는게 아니라, 하위 컴포넌트에 적용된 style이 반영된다.</p>
<p>Emotion에서 global styles라는 모듈을 불러와서 전체에 적용하는 방법이다.</p>
<p><img src="https://images.velog.io/images/moony_moon/post/2fc170f8-6bf5-4ae8-8052-4fde80c6f49c/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-31%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%207.46.18.png" alt=""></p>
<p>전체에 적용하고 싶은 부분은  * 그리고 특정폰트를 사용하고 싶다면 @font-face{}
이렇게 사용하면 된다.</p>
<p>확실히 Layout과 css를 알고 있다면 html, css를 하루에 어느정도 작업해야하는 회사입장에서는 중요한 기술일 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL -TypeScript 활용]]></title>
            <link>https://velog.io/@moony_moon/TIL-TypeScript-%ED%99%9C%EC%9A%A9</link>
            <guid>https://velog.io/@moony_moon/TIL-TypeScript-%ED%99%9C%EC%9A%A9</guid>
            <pubDate>Sat, 29 May 2021 10:00:55 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/b81241d3-511c-4ded-a722-ebdc2c785c33/TIL_React.png" alt=""></p>
<p>금일은 TypeScript의 활용에 대해서 알아보고자 한다. Typescript는 컴파일러 언어중에 하나로써 나중에 언어를 Javascript로 변환해서 컴퓨터가 읽게끔 합니다.</p>
<h4 id="컴파일-vs-트랜스파일">컴파일 vs 트랜스파일</h4>
<p>컴파일: 하나의 언어가 다른 언어로 변경되는 작업을 의미한다.
트랜스파일: 하나의 언어가 다른 버전으로 변경되는 작업을 의미한다.</p>
<p>타입스크립트는 자바스크립트를 안전하게 사용하기 위한 언어이며, 변수 또는 상수의 타입을 한번 정해주거나 state의 타입을 정해주면 그 이후에는 무조건 그 타입을 따라야만한다.</p>
<p>예)</p>
<pre><code class="language-javascript">게시물의 갯수 - 5개
0 + 1 + 1 + 1 + 1 + 1 = 5

이렇게 들어갈 수도 있지만, 타입스크립트를 통해서 변수의 속성을 처음부터 정해주지 않으면 문제가 발생한다.

&#39;0&#39; + 1 + 1 + 1 + 1 + 1 = 011111

이렇게 값이 들어가는 부분에 대해서 방지를 해야한다.</code></pre>
<p>이렇게 하고난 후 타입스크립트 같은 경우는 js파일을 ts 혹은 tsx파일로 변경해주면 된다. tsx파일은 컴포넌트가 구성되는 presenter 혹은 container파일을 tsx파일로 변경해주면 되고, ts 파일같은 경우는 graphql-query 혹은 emotion 파일들을 변경해주면 좋다.</p>
<p>그런데, 백엔드에서 받아오는 데이터의 형 변환을 적어줘서 조금 더 쉽게 백엔드 데이터의 속성을 추론하고 싶다면 code generator를 이용하면 좋다.</p>
<h3 id="typescript-generic">Typescript Generic</h3>
<p>자바나 C++에서 자주볼 수 있는 구조인데 함수나 클래스를 사용하기전에 타입을 미리 선언해주는 것이다. </p>
<p>자바스크립트 같은 경우는 원래 모든 타입을 다 받기 때문에 typescript처럼 타입을 지정해줄 수 없다.</p>
<p>정적인 언어에서 쓰이는 프로그래밍 기법이라고 보면 될 것 같다.</p>
<p>왜 generic이 유용한지 class 예제를 통해서 한번 살펴보자</p>
<pre><code class="language-javascript">class A {

  data : any[] = [];

constructor()

examplefunction1() : any;

examplefunction2() : any;

}</code></pre>
<p>이렇게 class안에서 데이터 및 함수구조 타입을 any로 선언하고 사용을 할 수 있지만, any로 데이터를 받기 때문에 class A라는 것을 호출할때마다 자료구조 각각을 다 검사해야한다.</p>
<p>그렇다고 number, string, 이렇게 미리 자료구조의 타입을 선언해준다면? </p>
<p>당연히 범용적인 측면에서 효율이 떨어진다.</p>
<p>그렇기때문에 나온게 generic이라고 보면 될 것 같다.</p>
<pre><code class="language-javascript">class A&lt;T&gt;{

private data T[] : [];

constructor() {};

functionexample1(item: T) : void{
  this.data.push(item)
}

functionexample2() : T {
}
</code></pre>
<p>이렇게 지정해주고나서</p>
<pre><code class="language-javascript">const classtype1 = classA&lt;string&gt;
const classtype2 = classB&lt;number&gt;</code></pre>
<p>이렇게 범용성있게 사용할 수 있다.</p>
<p>Generic 함수</p>
<pre><code class="language-javascript">function example&lt;T&gt;(arr[] : T[]) : T {
    return arr[0]
}

이런식으로 함수를 작성하게 된다.


//함수에서 인자를 받는 데이터 타입이 2개이상인경우

function example2&lt;T, X&gt;(data1 : T, data2 : U) : [T, U] {

      return data1, data2
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Open API 에서 받아온 이미지로 Carousel(Slider) 만들기]]></title>
            <link>https://velog.io/@moony_moon/Open-API-%EC%97%90%EC%84%9C-%EB%B0%9B%EC%95%84%EC%98%A8-%EC%9D%B4%EB%AF%B8%EC%A7%80%EB%A1%9C-CarouselSlider-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@moony_moon/Open-API-%EC%97%90%EC%84%9C-%EB%B0%9B%EC%95%84%EC%98%A8-%EC%9D%B4%EB%AF%B8%EC%A7%80%EB%A1%9C-CarouselSlider-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Thu, 27 May 2021 01:43:42 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/a93f0a27-fbc9-4ec5-8456-a95d8120df24/TIL_React.png" alt=""></p>
<p>어제와 오늘은 헤더에 Carousel 만드는 작업을 진행해 보았다.
<img src="https://images.velog.io/images/moony_moon/post/8519c388-a3e9-4a1e-98d5-430999a59c07/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-27%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2010.20.45.png" alt=""></p>
<p>화질은 아무래도 Open API를 통해서 랜덤 이미지를 가져오다보니 Object-fit으로 했을 때 화질이 깨질 수 밖에 없었다. 실무에서 Carousel을 만든다면 디자이너에게 딱맞는 이미지 px을 받을테니 문제가 없을 것 같다.</p>
<h3 id="open-api를-이용한-carousel-만들기">OPEN API를 이용한 Carousel 만들기</h3>
<p>처음에 생각했을 때는 어렵지 않을 줄 알았다... 그런데 막상 만들다보니 여러가지 개념들이 들어가서 애를 먹은 코딩...
일단 Carousel Library는 가장 많이 사용된 React Slick을 찾아왔다.</p>
<p>React Slick을 사용하기 위해서 폴더에 다운로드를 받아주고 import를 해와서 해당 슬릭을 css 넘겨줬다. 여기서 주의해야할 상황은 외부라이브러리를 import해서 emotion을 줄때 보통 emotion stlye과는 다른 방법으로 선언을 해줘야한다.</p>
<pre><code class="language-javascript">// emotion with 일반케이스
import styled from &#39;@emotion/styled&#39;
const Slider = styled.div`
    padding-top: 20px;
    max-width: 20px;
    width:100%;
    height: 20px;
`
// emotion with library

const Slider = styled(외부라이브러리 이름)`
    padding-top: 20px;
    max-width: 20px;
    width: 100%;
    height: 20px;
`</code></pre>
<p>Inline style로 바로 태그에 속성을 부여하지 않는 이상 파일을 만들어서 할때에는 꼭 이렇게 해줘야한다.
사실 여기까지는 그렇게 큰 문제가 없었다.</p>
<p>그런데,  <a href="https://react-slick.neostack.com/">내가 사용한 라이브러리</a> 를 활용해 개 이미지를 랜덤으로 제공하는 OPEN API를 사용했는데 useEffect함수를 사용하면 axios.get을 할때 이미지 주소를 한개만 불러오고 그 이미지가 모든 슬라이더 페이지에 다 적용이 되었다.</p>
<blockquote>
<p>나의 목적: 각 슬라이더 페이지마다 다른 이미지가 들어오게끔 해야한다.</p>
</blockquote>
<p>그렇다면 axios를 슬라이더 페이지마다 불러와야하는것인가?</p>
<p>제일 처음 생각했던것은 useEffect를 통해서 axios를 한번 실행하고 그 이후에 setState 함수를 사용해서 첫번째 슬라이더가 클릭이 되면 state가 변경이 되면서 2번째 슬라이더의 이미지가 바뀌게끔 한것이다.</p>
<pre><code class="language-javascript">const [image, setImage] =useState&lt;string[]&gt;([])
useEffect(() =&gt; {
  getDogs = async()  =&gt; {
    const result = await.axios.get(&#39;주소&#39;)
    setImage([...image, result.data.message(&quot;이 방법이 OPEN API 개 이미지를 가져오는 방법이다&quot;)])

  }
  getDogs()
}, [])

async function onClickSwipe1(){
    const result = await.axios.get(&#39;주소&#39;)
      setImage(image.concat(result.data.message)) //다양한 문법을 사용해보기 위해서 스프레드 연산자 그리고 concat도 사용해 보았다. 둘 다 적용이 가능하다.

}
</code></pre>
<p>이런식으로 코드를 짜서 Component에 뿌려줬더니 클릭했을 때 이미지가 변하긴 했다. 그런데 슬라이더안에있는 버튼을 누르면, 그 버튼은 wrapper안에 혹은 box안에 있는것으로 인식을 전혀 못해서 문제가 생겼다 -.- . 그렇게 고안해낸 방법이 axios를 내가 원하는 슬라이더 갯수만큼 돌리면 되는거 아닌가? 라는 방법이었다.</p>
<p>이 때 map으로 돌려서 하는방법이 있고 for문을 돌려서 하는 방법이 있다. 실무에서는 for문보다는 map을 많이쓴다. 그 이유는 동기와 비동기의 차이때문에 속도면에서 많은 성능 차이를 보인다.</p>
<p>혹시 , 비동기와 동기에대해서 정확히 모른다면 공부를 하고 오는것도 좋다!</p>
<p>그런데 map을 돌려서 해보니 문제가 생겼다. map을 돌리면 원하는 이미지가 안나와서 console창에 image라는 state를 찍어보았다.</p>
<p>그런데 왠걸, promise가 5번찍히는 것이였다.</p>
<p>?????</p>
<p>뭐지.. 하다가 보니까 map 뒤에 내가 async await를 썼는데 map이전에 내가 실행한 배열가져오는건 이미 비동기구조로 작업이 끝났고 map이후는 동기화 처리가 되면서 값을 기다리는 상황이었기때문에 promise가 5번찍히고 그 값들이 setState에 들어가서 이미지 호출이 되지않은것이다.</p>
<p>흠냐흠냐, 그래서 오늘 새로배운 문법! Promise all</p>
<p>한번에 promise값들이 함수가 끝나면 가져오는 것이다. 내가 짠 코드를 한번 보여주겠다.</p>
<p><img src="https://images.velog.io/images/moony_moon/post/21424271-5f24-415b-ab8e-f25a1c8983c7/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-27%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2010.42.31.png" alt=""></p>
<p>이렇게 promise.all을 하게되면 비동기 및 동기가 섞이는 일은 없을것이다.</p>
<p>이렇게 고민하면서 코딩을하고 더 나은 방향으로 계속해서 고민하다보니 시간이 너무 빨리가고 또 너무 재밌는 것 같다.</p>
<p>앞으로 이런 흥미를 계속해서 잃지 않기를... PLEASE STAY...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - React]]></title>
            <link>https://velog.io/@moony_moon/TIL-React-73lqbs6f</link>
            <guid>https://velog.io/@moony_moon/TIL-React-73lqbs6f</guid>
            <pubDate>Wed, 26 May 2021 05:23:34 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/a531fc3d-a2de-4586-be31-a45a36012b45/TIL_React.png" alt=""></p>
<blockquote>
<p>모든 코드에 의미를 담겠습니다.</p>
</blockquote>
<p>오늘은 useEffect()함수에 대해서 배웠다!! React.js 함수형 컴포넌트를 통해서 배우다보니 Class형 컴포넌트에있던 willmount didmount이런 기능들과는 조금 다르기 때문에 확실히 2가지 모두 배우는 것이 좋아 보인다.</p>
<p>그리고 취업을 할 때 해당 회사에서 어떤 형태로 React컴포넌트 및 state 구성을 할 지 모르기에.... 나는 둘 다 최대한 능숙하게 다룰줄 알게끔 공부중이다... 또르륵..</p>
<p>확실히 React 공식문서에서도 함수형을 추천하고 있지만 Class형 나름대로 복잡하면서 매력적인 코드구조를 가지는 것 같아서 배우는 재미가 있다!
<img src="https://images.velog.io/images/moony_moon/post/44f894a6-d88c-4470-a421-f20e997a41ba/Minions.gif" alt=""></p>
<p>일단 useEffect()함수는 페이지가 렌더링 된 이후에 실행되는 함수를 일컷는다! 구조부터 한번 살펴보자!!</p>
<pre><code class="language-javascript">useEffect(() =&gt; {
  console.log(&#39;aaa&#39;
},[]} // 빈 배열을 추가해야지 컴포넌트가 그려지고 난 이후에 useEffect안에 있는 함수를 한 번 호출한다</code></pre>
<p>빈 배열이 아닌 state    값을 넣어주게 된다면 state가 변경될때마다 useEffect가 한번 더 실행이 된다. 우리는 useEffect를 실행시켜주는 배열을 <strong>dependency</strong> 배열이라고 한다! <img src="https://images.velog.io/images/moony_moon/post/f7fd6bbc-6c3f-4b96-8ccb-8f535ebb6736/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-26%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2011.48.15.png" alt=""></p>
<p>위와 같이 페이지가 렌더링 되고 난 이후에 특정 input에 커서가 깜빡이게끔 하는 함수를 볼 수 있다.</p>
<p>여기서 궁금한 점, 저 함수안에 state를 넣어서 써도 될텐데 setState를 자주 사용해도 될까???</p>
<p>여러가지 블로그도 뒤지고 공부해본 결과 정말 부득이한 경우가 아니라면 setState 기능 자체를 useEffect안에 쓰는걸 지양해야 한다.</p>
<blockquote>
<p>이유는??</p>
</blockquote>
<p>useEffect함수 자체가 렌더링을 한번 했을 때 사용되는 함수인데 setState를 사용하게 되면 렌더링이 한번 더 반복되게 된다. 여기서 여러번의 setState를 활용하면 렌더링이 많이 되면서 서비스가 조금만이라도 커지면 문제가 생길 가능성이 높다!!!</p>
<pre><code class="language-javascript">useEffect(() =&gt; {
  inputRef.current.focus()
  setTestState(prev =&gt; prev +1)
  console.log(&#39;aaaa&#39;)

  if(testState ===10) retrun () =&gt; {};
  console.log(&#39;useEffect가 실행되었습니다&#39;)
},[testState]) //이렇게 하면 testState가 무한반복이 되면서 랩탑이 터진다!! ㅋㅋ </code></pre>
<p>함수형 컴포넌트 vs 클래스형 컴포넌트</p>
<p>요즘에는 확실히 많은 회사에서 함수형 컴포넌트를 많이 쓰는 추세이다. this.state 등과 같이 복잡하게 쓰지 않아도 되니 확실히 함수형 컴포넌트 가 편리한걸 배우고나서야 느낀다.</p>
<p>그래도 함수형 컴포넌트에서 쓰이던게 클래스형 컴포넌트에서는 어떻게 쓰이고, vice versa를 확실히 알아야한다.</p>
<p><strong>클래스형 컴포넌트</strong>의 구조에 대해서 한번 파헤쳐 보자</p>
<pre><code class="language-javascript">import {Component, createRef} from &#39;react&#39; // 필요한 react의 모듈들을 불러온다

class MyClassPage extends Component {
  private inputRef : RefObject&lt;HTMLInputElement&gt; //Typescript 속성 정해주기 위한 방법

  constructor(props){
    super(props) // 초기값을 정해주는 곳이다
    this.state = {}
    this.inputRef = createRef();
  }

  componentDidMount() { //함수형에서는 useEffect with dependency array랑 같다고 보면 된다. 즉, 페이지가 렌더링 된 이후에 실행되는 함수라고 보면 되겠다.
    this.inputRef.current.focus //createRef()는 함수형의 useRef()랑 같은 함수이고 특정 태그를 지목하고 싶을 때 사용된다.
  }
  componentDidUpdate(){
    console.log(&#39;dddd&#39;) //어떤 동작이 실행될때마다 모든 값이 찍히는 함수 즉 useEffect()함수에서 dependency 배열이 없는것이라고 보면 될 것 같다.

  }</code></pre>
<p>오늘은 클래스형과 컴포넌트의 구분에 대해서 알아봤지만 둘 구조를 눈에 익을때까지 보고 class -&gt; function, function -&gt; class로 자유자재로 변환할줄알아야할 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript - Closure(클로저)]]></title>
            <link>https://velog.io/@moony_moon/Javascript-Closure%ED%81%B4%EB%A1%9C%EC%A0%80</link>
            <guid>https://velog.io/@moony_moon/Javascript-Closure%ED%81%B4%EB%A1%9C%EC%A0%80</guid>
            <pubDate>Tue, 25 May 2021 09:22:11 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/2cd8feaf-aac0-426d-ab14-c24ab2003953/TIL-javascript2.jpeg" alt=""></p>
<blockquote>
<p>모든 코드에 의미를 담겠습니다.</p>
</blockquote>
<p>Javascript에서 중요하다는, 또, 알게모르게 나도 프로젝트에서 쓰고 있었던 Closure(클로저) 함수에 대해서 알아보는 시간이다!!</p>
<p><img src="https://images.velog.io/images/moony_moon/post/5f5b25eb-b1e2-4951-ac90-3de19eaddc11/Minions.gif" alt=""></p>
<p>아직은 이론적으로만 배우는 단계라서 실무에서 클로저를 적극적으로 활용해서 어떤 느낌일지... 궁금하다.</p>
<p>항상 배운것을 바로 써먹어서 화면에 기능들이 바로 구현이 되는게 <strong>프론트엔드</strong>의 가장 큰 장점인 것 같다!!</p>
<p>내가 배웠던 부분들을 바로 실무에 적용해서 내 눈으로 보고싶다? 그렇다면 당신은 프론트엔드에 맞다! </p>
<p>잡설은 집어치우고, Closure는 MDN 공식문서에 따르면 독립적인 변수를 가지는 함수라고 한다. 즉, 내부에 있는 변수를 특정 함수에서만 사용하고 싶을 때 Closure함수가 와따봉!</p>
<p>Closure 함수의 예제를  보면서 이해를 해보자</p>
<pre><code class="language-javascript">function ClosureExample(){
  var text = &quot;문태웅입니다&quot;;
  return function(){
    console.log(&quot;Hello&quot; + text);
  };
}

var closure1 = ClosureExample() 
console.log(closure1()) //Hello 문태웅입니다)라고 출력이 된다.</code></pre>
<p>이렇게 보면 ClosureExample 함수안에 있는 var text의 선언값을 Closure함수안에서만 사용할 수 있고, 해당 함수를 closure1에 할당해서 사용해서 console을 찍어보니 값이 그대로 저장되어있는 부분을 확인할 수 있다.</p>
<p>이것을 통해서 Closure함수는 <strong>환경</strong>을 기억해서 저장하는구나 라는것을 유추할 수 있었다!!</p>
<p>나보다 더 자세하게 Closure함수에대해서 정리하신 분의 개발일지를 공유하도록 하겠다
<a href="https://hyunseob.github.io/2016/08/30/javascript-closure/">Closure 정리</a></p>
<p>Closure함수를 살펴보면 보통 함수안에 함수를 써서 함수자체를 return 시켜서 환경을 기억하도록 만들어 놓았다. </p>
<h3 id="장점">장점</h3>
<p>Javascript에서 Prototype에서는 은닉하고 싶은 변수도 쉽게 가져올 수 있는 단점이 있다.</p>
<blockquote>
<ol>
<li>함수 안에 내부 변수를 숨기고 싶다면 Closure함수처럼 외부로 끌고와서 사용하기 용이하다!</li>
</ol>
</blockquote>
<blockquote>
<ol start="2">
<li>function이 실행될때마다 고차원함수처럼 함수를 return하기 때문에 closure함수는 환경을 기억해서 동적으로 할당이 가능하다.</li>
</ol>
</blockquote>
<h3 id="단점">단점</h3>
<blockquote>
<p>환경을 매번마다 기억하기 때문에 메모리 차지가 심하다. 그러므로 사용한 이후에는 해당 함수를 nullify시켜주는게 좋다!</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Browser - 브라우저의 렌더링]]></title>
            <link>https://velog.io/@moony_moon/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EB%A0%8C%EB%8D%94%EB%A7%81</link>
            <guid>https://velog.io/@moony_moon/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EB%A0%8C%EB%8D%94%EB%A7%81</guid>
            <pubDate>Tue, 25 May 2021 06:41:00 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/48df2120-88c6-4314-b4bf-1f1eaaad131a/Eureka.jpeg" alt=""></p>
<blockquote>
<p>모든 코드에 의미를 담겠습니다.</p>
</blockquote>
<p>5일만에 쓰는 velog.... 주말동안 React 부분에서 해야 될 과제들이 산더미처럼 있어서 개인적인 프론트엔드 공부를 할 여유가 없었던 것 같다(이것도 변명인가..? ㅎㅎ..)</p>
<p>조만간, 주말동안에 씨름을 했던 TypeScript with ESLint에 대해서도 한번 짚고 넘어갈 예정이다.</p>
<p>우선, 오늘은 프론트엔드 개발자라면 한번쯤은!!</p>
<p>들어봤을법한 브라우저의 렌더링에 대해서 좀 다뤄볼까 한다.</p>
<blockquote>
<p>즉, 사용자에게 브라우저의 내용들이 어떻게 보여지는지에 대한 내용이다.</p>
</blockquote>
<p><strong>브라우저의 흐름 순서도에 대해서는 여러 velog에서 소개를 하고 있지만, 그 순서의 내부까지 자세하게 설명하고 있는 velog는 많이 못 본것같다.</strong></p>
<p>그래서 네이버 D2에서 번역한 이스라엘 개발자 Tali Garsiel의 브라우저 동작에 대해서 조금씩 조금씩 내가 이해한바로 써 내려갈 예정이다.</p>
<p>그러므로, 다른 개발일지와는 다르게 이번 일지 같은 경우는 조금 장기적으로(?) 써내려가면서 천천히 곱씹어 가면서 써내려 갈 것 이다.</p>
<blockquote>
<p>한 번에 못쓴다는 것을 돌려서 말하고 있는중...</p>
</blockquote>
<p>우선 유저들이 현대사회에서 많이 쓰고있는, 크롬, 사파리, 파이어폭스, 인터넷 익스플로러 같은 것들이 브라우저라고 보면 되겠다.</p>
<p>그렇다면 브라우저의 정확한 정의는 무엇인가?</p>
<blockquote>
<p>클라이언트 쪽에서 선택한 자원을 서버에 요청해서 요청한 파일을 브라우저라는 창에 뿌려주는 것.</p>
</blockquote>
<p>프론트엔드 개발자로서, 비전공자인 내 입장에서 자원은 음? HTML과 CSS이 둘밖에 없지 않나? 라는 생각을 하지만!</p>
<p>아니다. 사실은 이미지파일도 요청할 수 있고 PDF파일도 요청해서 자료를 받아올 수 있다. 그런데, 프론트 엔드 개발자로써 거의 HTML CSS 파일로 요청해서 렌더링을 하기 때문에 다른 자원에 대해서 생각해보지는 않았다.</p>
<p>내가쓰는 개발일지에서는 HTML CSS의 자원만으로 어떻게 브라우저가 작동하는지에 대해서 써볼것!!</p>
<h3 id="브라우저의-구조">브라우저의 구조</h3>
<ul>
<li>사용자 인터페이스: 주소창, 북마크, 기본적인 것들</li>
<li>브라우저 엔진: 사용자 인터페이스와 렌더링 엔진 사이에서 흐름을 제어하는 엔진!</li>
<li>렌더링 엔진: HTML과 CSS를 컴퓨터가 이해할 수 있는 언어로 파싱하는 엔진!</li>
<li>통신: REST-API, APOLLO-QL등 데이터를 가져오게 하게끔 하는 네트워크</li>
<li>자바스크립트 해석기: 자바스크립트를 해석해주는 기계</li>
<li>UI백엔드: 창같은 기본장치를 그리는 역할</li>
<li>자료 저장소: 모든 데이터를 웹 베이스에서 저장할 수 있게끔해주는 장치!</li>
</ul>
<p>이 구조들에 대해서 하나씩 더 자세하게 살펴봐야되지만, 현재는 여기서 이 정도의 개념을 파악하고 한번 흐름을 파악해보자!</p>
<p>나는 일단 흥미가 생긴후에 지식을 습득해야지 이해가 잘가는 경우라 너무 원론적인 부분을 파다보면 코드 없이 이론으로는 머릿속에 안박히는 경우가 많다!</p>
<p><img src="https://images.velog.io/images/moony_moon/post/b4b181b0-558b-42b5-ad69-665af8124698/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-25%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%202.51.34.png" alt=""></p>
<p>네이버 D2사이트에서 제공하는 브라우저 구조! 한번 참고해보면 좋을 것같다.</p>
<p>여기서 그러면 사용자에게 보여지는 화면을 뿌려주는 건 뭘까?</p>
<p>바로 렌더링 엔진이다!</p>
<p>렌더링엔진은 위에서 언급했듯이 HTML CSS 자료들을 파싱해서 화면에 뿌려주는 역할을 하는데 그 렌더링 과정에 대해서 알아야하지 않을까?</p>
<p>개인적으로 프론트엔드 개발자로써는 흐름에 대해서는 파악하고 있어야할 것같다.</p>
<h3 id="렌더링-순서">렌더링 순서</h3>
<ol>
<li>HTML, CSS을 파싱한다. 컴퓨터가 알아들을 수 있는 언어로 분리를 하는 것이다.</li>
<li>HTML을 파싱한 이후에 DOM 트리를 생성하고 CSS의 스타일 요소도 파싱해서 어태치먼트로 합친다. CSS의 스타일 요소는 p 태그 div태그 속성자체를 요소라고 칭한다.
DOM 같은 경우는 객체지향형 모델이라고 보면 되겠다. ({}) 이 부분에 대해서 잘 모르겠다면 객체 지향형 모델, DOM, Virtual DOM에대해서 배우고 오면 더 이해가 쉬울 것 같다.</li>
<li>그런 다음에, 시각화를 담당하는 렌더트리에 담아서 실행하고 배치!!</li>
<li>배치가 되면, UI백엔드에서 각 노드를 살피면서 정확한 위치에 원하는 요소 및 뼈대들을 뿌린다고 보면 되겠다!</li>
</ol>
<p>렌더링 엔진,즉 웹킷이냐 게코냐에 따라서 렌더링하는 동작방식과 명칭이 조금씩 다르지만 크게보면 흐름은 비슷하다고 보면 좋을 것 같다.</p>
<h3 id="파싱과-돔-구조">파싱과 돔 구조</h3>
<ul>
<li>렌더링에서 파싱과 돔 구조는 정말 중요하다고 하니 파싱에 대해서 조금 더 자세하게 살펴보자.</li>
</ul>
<p>문서를 파싱하면 보통 결과는 문서 구조를 나타내는 노드 트리 (파싱트리)로 구성이 보통 된다.</p>
<p>예를들어)
2+ 3 -1 이면 2,3, 1, +, -1 를 각각 구별하는 노드들을 구성해서 트리형태로 만들어버리는 것이다.</p>
<p>파싱은 또 두가지로 나뉜다.</p>
<p>어휘를 분석하고 구문을 분석한다.</p>
<blockquote>
<p>쉽게말하자면, 어휘분석을 통해 토큰자료형으로 잘게잘게 쪼갠다음에  각각 토큰이 구문 규칙에 맞는지 확인한 후에 파싱트리에 넣는것이다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/moony_moon/post/d841f5d6-e00a-467c-a4a6-fc1c37b2d1d2/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-25%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%203.29.58.png" alt="">
                    &lt;네이버 D2 출처 파싱 순서&gt;</p>
<p>그리고 난이후에, 파싱트리를 컴파일링하는것이다!</p>
<p>어휘는 정규표현식을 보통 따라서, 해당 정규표현식에 따라 토큰으로 각각 분류를 한다.</p>
<h1 id="to-be-continued">TO BE CONTINUED....</h1>
]]></description>
        </item>
        <item>
            <title><![CDATA[React- JSX문법]]></title>
            <link>https://velog.io/@moony_moon/React-JSX%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@moony_moon/React-JSX%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Wed, 19 May 2021 12:24:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/ef67756a-9f48-4fcf-a9ff-48cc3e4dd8bf/TIL_React.png" alt=""></p>
<blockquote>
<p>모든 코드에 의미를 담겠습니다.</p>
</blockquote>
<p>React에서 JSX문법을 정의하기에 앞서서 React는 SPA(single page application) 즉 하나의 url가지고 운영이되는 프레임워크다.</p>
<p>React에서 사용하는 JSX문법이란 과연 무엇일까??</p>
<p>HTML문법을 자바스크립트 내에 쓴것이라고 보면 되겠다. 자바스크립트로 썼던것이 나중에는 HTML파일로 변경이 되서 페이지에 뿌려지는 형태로 하나의 컴포넌트에 Javascript + HTML이 동시에 존재하는 구조라고 보면 되겠다.</p>
<pre><code class="language-javascript">import styled from &quot;emotion/styled&quot;
export const hi = &lt;div&gt;p&lt;/div&gt;
export const hi_myname = styled.div`
    max-width: 1200px;
    height: 50px;
    display: flex;
`
export element = {
      &lt;div&gt;hi&lt;/div&gt;
      &lt;p&gt;Coding is very funny &lt;/p&gt;
}</code></pre>
<p>이런식으로 javascript 처럼 변수안에 html 태그를 쓸 수 있어서 굉장히 편하다.</p>
<p>JSX문법에 몇가지 중요한 규칙이 있으니 짚고 넘어가보자.</p>
<p>(1) 속성 즉, 태그안에 style className 이런것들을 줄때 무조건 &quot;&quot;로 구성을 해야한다.</p>
<pre><code class="language-javascript">&lt;div style = &quot;{}&quot;&gt;&lt;/div&gt;</code></pre>
<p>(2) 태그는 항상 닫혀있어야 한다.
(3) 어떤 태그라도 self-closing이 가능하다. </self-closing></p>
<p>더 자세하게 React JSX 문법에 대해서 알고 싶다면, <a href="https://ko.reactjs.org/docs/introducing-jsx.html">JSX 공식문서</a>를 참조하라!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React- Next Router vs React Router]]></title>
            <link>https://velog.io/@moony_moon/React-Next-Router-vs-React-Router</link>
            <guid>https://velog.io/@moony_moon/React-Next-Router-vs-React-Router</guid>
            <pubDate>Wed, 19 May 2021 11:46:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/moony_moon/post/cc9b82e0-6cd2-4d42-85eb-c2748e5df4c8/TIL_React.png" alt=""></p>
<blockquote>
<p>모든 코드에 의미를 담겠습니다.</p>
</blockquote>
<p>Next 프레임워크와 React 프레임워크를 사용하면서 두 가지의 차이점이 무엇인지 궁금했다. 사실, React.js를 많은 스타트업 및 대기업에서 프론트엔드 프레임워크로 사용하고 있는데 Next.js가 React랑 많이 다르면 취업하는데 있어서 다른 개발자들에 비해서 이점을 가져가지 못하지 않을까?</p>
<blockquote>
<p>결론은 Next.js는 React를 감싸고 있는 프레임워크라고 보면 되겠다. React의 기능들을 그대로 가지고 있으면서 Next.js에서만 구현할 수 있는 추가 기능들이 있어서 오히려 더 배운다고 보면 되겠다.</p>
</blockquote>
<p>그런데, Next.js와 React에서 차이를 유일하게 크게 보이는 곳이 Router부분이다. 라우팅을 할 때 Next에서는 상대적으로 쉽게하는 반면 React는 상대적으로 경로 및 컴포넌트 설정에 있어서 복잡하다.</p>
<p>한번 자세히 살펴보자.</p>
<h3 id="react-link-vs-next-link">React Link vs Next Link</h3>
<p>Next-js 같은 경우는 자바스크립트 a 태그 형식과 거의 같다고 보면 될 것 같다.</p>
<pre><code class="language-javascript">// React Link

import {Link} from &quot;react-router-dom&quot;;

export default function App(){
    return &lt;Link to = &#39;/taewoongmoon&#39;&gt;&lt;/Link&gt;

}


// Next.js Link
import Link from &quot;next/Link&quot;;


export default function App(){
    return (
      &lt;Link href = &quot;/taewoongmoon&quot;&gt;
          &lt;a&gt;about&lt;/a&gt;
      &lt;/Link&gt;

</code></pre>
<p>Next.js같은 경우는 원하는 a 태그에  링크를 걸어서 href형식으로 주면된다. (javascript 형식과 굉장히 비슷하다.)</p>
<p>잠깐!!,</p>
<blockquote>
<h3 id="그렇다면-link-와-route의-큰-차이는-무엇일까">그렇다면 Link 와 Route의 큰 차이는 무엇일까?</h3>
</blockquote>
<p>Link는 SEO(search engine optimization), 즉 검색최적화를 위하여 많이 사용되고 Routing은 그 외에 함수를 실행시킬 때 많이 사용한다.</p>
<p>??? 도대체 무슨말일까?</p>
<p>Link 태그를 사용하는 경우는, 자동으로 다른페이지로 넘어갈 때 많이 사용된다. 즉, 어떤 태그를 클릭해서 다른 페이지로 넘어갈 때 함수를 동작시키지 않고 그냥 페이지를 보여주면 되는 경우에는 Link 사용하는 게 <strong>훨씬 효율적이고</strong> 실무에서 많이들 쓴다고 한다. </p>
<p>결국 Routing을 사용하게 되면 클릭했을 때 어떤 함수들이 실행되는지 다른 회사들에서는 모르니 SEO를 할때는 주소가 나와있는 Link href를 많이 사용하게 되는것이다.</p>
<p>반대로 라우팅 같은 경우는 함수를 동작시켜서 클라이언트에서 데이터 request &amp; response 요청을 할때 등 자동으로 페이지를 넘기지 않을 경우 router.push &amp; replace를 사용한다고 보면 되겠다.</p>
<p>자 넘어가서 이제는 react routing vs next routing을 살펴보자</p>
<pre><code class="language-javascript">//react routing
import {BrowseRouter as Router, Switch, Route} from &#39;react-router-dom&#39;

export default function App(){
&lt;Router&gt; //일단 라우팅 되는 부분을 감싸준다
      &lt;Switch&gt; //Switch는 안에있는 여러가지 Router중에서 조건에 만족하는 첫번째 Router를 불러온다.
          &lt;Route exact path = &quot;/taewoongmoon&quot;/ &gt;
          &lt;Route exact path = &quot;/&quot; /&gt; // 이렇게 / 하나만 쓰면 index.js 메인페이지를 불러온다.
        &lt;Route exact path = &quot;/iwanttogohome&quot; /&gt;
          &lt;Route exact path = &quot;&quot; /&gt;

      &lt;/Switch&gt;
&lt;/Router&gt;
</code></pre>
<p>Next.js에서는 실행이 굉장히 간단하다!!!!</p>
<p><img src="https://images.velog.io/images/moony_moon/post/19f2deff-0da7-4aea-bc35-083c54589052/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-05-19%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.33.42.png" alt=""></p>
<p>router.push를 만들고 타입스크립트 혹은 자바스크립트 파일명을 그대로 써주면 그 페이지가 주소가 되는 재밌는 구조를 볼 수 있다.</p>
<p>라우팅면에서는 확실히 next.js가 편하긴 하다. 하지만, 많은 스타트업에서는 React.js를 쓰고있기때문에 설령 next.js를 공부하는 사람이라도 정확히 알아놓으면 좋을 정보이다.</p>
<p>또한, React같은 경우는 Nested Routes를 설정할때 ``을 이용하여 <code>{match.path}:slug</code> 직접 설정해줘야하는데</p>
<p>Next.js에서는 파일명 []대괄호하고 동적 라우팅을 해주고 그 주소로 route.push를 하면 nested routes가 완성된다.</p>
<p>굉장히 효율적인 기능이라고 볼 수 있다!!!</p>
<p>동적 라우팅에 대해서 알고 싶다면 나의 전 블로그를 참고해주시길..</p>
]]></description>
        </item>
    </channel>
</rss>