<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>nana_kim.log</title>
        <link>https://velog.io/</link>
        <description>한 줄의 코드가 유저의 일상을 변화시키는 매력에 반해 프론트엔드 개발자가 되었습니다. 늘 배움의 자세로 유저를 위한 기술을 구현하겠습니다. 저는 함께 이뤄내는 결과의 가치를 믿습니다. </description>
        <lastBuildDate>Sat, 13 Feb 2021 06:21:09 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>nana_kim.log</title>
            <url>https://images.velog.io/images/nana_kim/profile/0acc4552-8d10-480e-9fdc-76ca1b4ab87c/Image from iOS (3).jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. nana_kim.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/nana_kim" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[javascript]프로그래머스 위장]]></title>
            <link>https://velog.io/@nana_kim/javascript%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9C%84%EC%9E%A5</link>
            <guid>https://velog.io/@nana_kim/javascript%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9C%84%EC%9E%A5</guid>
            <pubDate>Sat, 13 Feb 2021 06:21:09 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.</p>
<p>예를 들어 스파이가 가진 옷이 아래와 같고 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다.</p>
<blockquote>
<p>종류    이름
얼굴    동그란 안경, 검정 선글라스
상의    파란색 티셔츠
하의    청바지
겉옷    긴 코트</p>
</blockquote>
<p>스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.</p>
<p><strong>제한사항</strong>
clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.
같은 이름을 가진 의상은 존재하지 않습니다.
clothes의 모든 원소는 문자열로 이루어져 있습니다.
모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 &#39;_&#39; 로만 이루어져 있습니다.
스파이는 하루에 최소 한 개의 의상은 입습니다.
<strong>입출력 예</strong></p>
<blockquote>
<p>clothes    return
[[yellow_hat, headgear], [blue_sunglasses, eyewear], [green_turban, headgear]]    5
[[crow_mask, face], [blue_sunglasses, face], [smoky_makeup, face]]    3</p>
</blockquote>
<p><strong>입출력 예 설명</strong>
예제 #1
headgear에 해당하는 의상이 yellow_hat, green_turban이고 eyewear에 해당하는 의상이 blue_sunglasses이므로 아래와 같이 5개의 조합이 가능합니다.</p>
<blockquote>
<ol>
<li>yellow_hat</li>
<li>blue_sunglasses</li>
<li>green_turban</li>
<li>yellow_hat + blue_sunglasses</li>
<li>green_turban + blue_sunglasses</li>
</ol>
</blockquote>
<p>예제 #2
face에 해당하는 의상이 crow_mask, blue_sunglasses, smoky_makeup이므로 아래와 같이 3개의 조합이 가능합니다.</p>
<blockquote>
<ol>
<li>crow_mask</li>
<li>blue_sunglasses</li>
<li>smoky_makeup</li>
</ol>
</blockquote>
<p><img src="https://images.velog.io/images/nana_kim/post/c79b603b-eacb-4478-89c2-82587e51b24c/%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-02-13%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%203.18.16.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[javascript] 프로그래머스 완주하지 못한 선수]]></title>
            <link>https://velog.io/@nana_kim/javascript-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98</link>
            <guid>https://velog.io/@nana_kim/javascript-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98</guid>
            <pubDate>Mon, 08 Feb 2021 14:11:59 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.</p>
<p>마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.</p>
<p><strong>제한사항</strong>
마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.
completion의 길이는 participant의 길이보다 1 작습니다.
참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.
참가자 중에는 동명이인이 있을 수 있습니다.</p>
<p><strong>입출력 예</strong>
<img src="https://images.velog.io/images/nana_kim/post/bd818a2e-1808-4b95-966c-5009dde0ee48/image.png" alt=""></p>
<p><strong>입출력 설명</strong>
예제 #1
leo는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.</p>
<p>예제 #2
vinko는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.</p>
<p>예제 #3
mislav는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다.</p>
<p><strong>문제해결</strong>
<img src="https://images.velog.io/images/nana_kim/post/cbfbf680-6051-4930-8a1c-0dc5bfca089c/%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-02-08%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.51.54.png" alt=""></p>
<blockquote>
<ol>
<li>배열을 정리한다.</li>
<li>비교해서 다르면 반환한다.</li>
</ol>
</blockquote>
<p><img src="https://images.velog.io/images/nana_kim/post/c7f6a81d-354f-424a-8e09-e8bd240ea091/%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-02-08%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.54.32.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[var const let를 알아보자]]></title>
            <link>https://velog.io/@nana_kim/var-const-let%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@nana_kim/var-const-let%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Fri, 15 Jan 2021 08:51:01 GMT</pubDate>
            <description><![CDATA[<h4 id="javascript에서-변수-선언-방식인-var-const-let을-알아보자">JavaScript에서 변수 선언 방식인 var const let을 알아보자.</h4>
<h2 id="1-변수-선언-방식">1. 변수 선언 방식</h2>
<p><strong>var</strong>는 변수 선언방식에서 가장 큰 단점을 가지고 있다.
<img src="https://images.velog.io/images/nana_kim/post/f70fc4a3-2351-41a8-be72-c186a8cbb861/%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-01-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.19.50.png" alt=""></p>
<p>동일한 변수를 사용했음에도 불구하고, 에러가 나지 않고 서로다른 값이 나오는 것을 볼 수 있다. 이는 유연한 변수 선언으로 간단한 코드를 테스트 해보는 것은 유용하나, 코드가 많아지면 어디에서 어떻게 사용 될지도 파악이 힘들고 값이 바뀔 우려도있다.</p>
<h3 id="let">let</h3>
<p><img src="https://images.velog.io/images/nana_kim/post/5bfba177-0690-4b90-a9fb-1b93382da2cb/%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-01-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.24.14.png" alt=""></p>
<h3 id="const">const</h3>
<p><img src="https://images.velog.io/images/nana_kim/post/bf1c98c3-cbe7-4725-94cc-fb0e6ab0029d/%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-01-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.28.23.png" alt=""></p>
<p>let과 const는 name이 이미 선언됬다는 에러메시지가 나온다.</p>
<h2 id="그럼-let과-const-의-차이점은-무엇일까"><strong>그럼 let과 const 의 차이점은 무엇일까?</strong></h2>
<p><strong>let과 const의 차이점은 불변성,변경할 수 없는 것이다.</strong></p>
<h3 id="let-1">let</h3>
<blockquote>
<pre><code>  let name = &#39;kimhanna&#39;
    console.log(name) // kimhanna
    let name = &#39;hannakim&#39;
    console.log(name) 
    // Uncaught SyntaxError: Identifier &#39;name&#39; has already been declared
    name = &#39;nana&#39;
    console.log(name) //nana</code></pre></blockquote>
<pre><code>**let 은 변수에 재할당이 가능하다.**

&gt;### const</code></pre><p>const name = &#39;kimhanna&#39;
    console.log(name) // kimhanna
    const name = &#39;hannakim&#39;
    console.log(name) 
    // Uncaught SyntaxError: Identifier &#39;name&#39; has already been declared
    name = &#39;nana&#39;
    console.log(name) //nana
    //Uncaught TypeError: Assignment to constant variable.
    const는 변수 재선언, 변수 재할당 모두 불가능하다.</p>
<pre><code>
## 정리

기본적으로는 const를 변수로 선언하여 사용하고, 재할당이 필요한 경우에는 let을 한정해 변수로 선언하는 것이 좋다.
const는 의도치 않은 재할당을 방지해 주기 때문에 보다 안전하다.
재할당이 필요 없는 상수와 객체에는 const 를 사용한다.

&gt;
var: 동일한 변수 사용 가능
let: 동일한 변수 사용 불가능, 변수 재할당 가능
const: 동일한 변수 사용 불가능, 변수 재할당 불가능

</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[함수형 프로그래밍이란? ]]></title>
            <link>https://velog.io/@nana_kim/-%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@nana_kim/-%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Tue, 29 Dec 2020 03:23:05 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li>함수형 프로그래밍이란?<ul>
<li>(꼬리 질문) 자바스크립트 클로저란?</li>
<li>(꼬리 질문) 자바스크립트 프로토타입이란?</li>
</ul>
</li>
</ul>
</blockquote>
<h3 id="1-함수형-프로그래밍이란">1. 함수형 프로그래밍이란?</h3>
<ul>
<li>함수형 프로그래밍은 자료 처리를 수학적 함수의 계산으로 취급하고,
상태와 가변 데이터를 멀리하는 프로그래밍 패러다임의 하나이다.</li>
<li>문이 아닌 식이나 선언으로 수행되는 선언형 프로그래밍 패러다임을 따르고 있다.
(출처:위키백과)</li>
</ul>
<p>Input이 같으면 Output이 일정한 순수함수로 코딩을 했기 때문에
예상하지 못한 Output이 나왔을 때 Input값만 점검하면 된다.
그 Input값 역시 다른 순수함수의 Output이라면, 그 순수함수를 확인해보면 된다.
전체의 코드를 모두 점검할 필요가 없다는 뜻이다.</p>
<p>즉, 개발을 어떻게 하면 효율적으로 잘 할 수 있을지에 대한 의문에서 출발했을 때,
&quot;순수함수를 조합하여 프로그래밍해보니 좋더라!&quot;
라는 결론때문에 &quot;함수형 프로그래밍&quot; 방법을 적용하라는 것이다.</p>
<p>(개발 기간과 비용을 단축하여 효율적인 개발을 할 수 있는 프로그래밍 방법)</p>
<h2 id="함수형-프로그래밍의-특징">함수형 프로그래밍의 특징</h2>
<h3 id="1-순수함수pure-function">1) 순수함수(Pure function)</h3>
<ul>
<li>동일한 입력에는 항상 같은 값을 반환해야 한다.</li>
<li>함수의 출력(return)은 오로지 그 함수에 입력된 값(input)에만 의존한다.</li>
<li>함수의 실행은 프로그램의 실행에 영향을 미치지 않아야 한다.
(Self-contained되어야 한다, 즉, side effect가 없다.)<ul>
<li>Side effect가 없다는 의미는 오로지 출력(return) 만 수행한다는 의미이다.</li>
</ul>
</li>
</ul>
<h3 id="2-function-composition">2) Function composition</h3>
<ul>
<li>둘 이상의 함수를 조합하는 과정을 말한다.</li>
<li>함수형 프로그램은 여러 작은 순수 함수들로 이루어져있기 때문에
이 함수들을 연쇄적으로 또는 병렬로 호출해서 더 큰 함수를 만드는 과정으로
전체 프로그램을 구축해야 한다.
재사용이 가능한 순수 함수를 원하는 Output을 위해 서로 엮는 것이다.
함수를 엮기 때문에 고차원함수(Higher-Order Functions)를 활용해야 한다.</li>
</ul>
<blockquote>
<p>고차원 함수(Higher-Order Functions)ex: filter(), map(),reduce()</p>
</blockquote>
<ul>
<li>함수를 인자(argument)로 받는다.</li>
<li>함수를 결과로 반환한다.</li>
<li>함수형 프로그래밍에서는 함수가 1등급 객체(first-class object)이다.</li>
<li>함수가 1등급 객체이므로, 함수는 고차원 함수를 구현할 수 있다.</li>
</ul>
<blockquote>
<p>1등급 객체(first-class object (citizen, type, entity, value로 표현되기도 한다.)</p>
</blockquote>
<ul>
<li>자료구조에 저장된다.</li>
<li>인자(argument)로 전달된다.</li>
<li>결과로 반환한다.</li>
<li>함수가 실행되는 동안 새로운 함수가 만들어질 수 있다.</li>
</ul>
<h4 id="객제지향-프로그래밍-vs-함수형-프로그래밍">객제지향 프로그래밍 vs 함수형 프로그래밍</h4>
<p>명령형은 어떻게 풀어내는지(how to solve)에 집중하고,
선언형은 무엇을 풀어내는지(what to solve)에 집중한다.</p>
<p>예를 들어, 최종적인 목표가 &#39;물을 마시기&#39; 라고 해보자.</p>
<p>(명령형) 어떻게(how) 할 것인지를 설명</p>
<ul>
<li><p>자리에서 일어난다.</p>
</li>
<li><p>부엌으로 이동한다.</p>
</li>
<li><p>컵과 물을 찾는다.</p>
</li>
<li><p>컵에 물을 부어 마신다.</p>
<p>(선언형) 무엇(what)을 할 것인지를 설명</p>
</li>
<li><p>물을 마셔보자.</p>
</li>
</ul>
<p>☛👉 객체지향 프로그래밍 ➲ 상태 변화 ➲ Side effect 발생
☛👉 함수형 프로그래밍 ➲ 상태 변화 없음 ➲ Side effect 미발생</p>
<h3 id="3-immutability불변성">3) Immutability(불변성)</h3>
<ul>
<li>순수함수는 예측된 input과 함께 실행된다.</li>
<li>Input이 변하면, 순수함수는 개발자가 예측하지 않은 다른 출력값을 만든다.</li>
<li>즉, 다른 출력값은 다른 함수에도 영향을 미친다.</li>
</ul>
<h3 id="4-function-decoration">4) Function decoration</h3>
<ul>
<li>순수함수를 재사용하다보면, 이미 만들어진 순수함수를 그대로 적용하기보다
일부 개선하거나, 조금 다른 방향으로 수정해야 하는 상황이 발생할 수 있다.
이 때 function decoration을 적용한다.<ul>
<li>직접적으로 순수 함수를 수정하진 않지만, 함수에 실행 시점이나 방식을 조율하는 것을 말한다.</li>
</ul>
</li>
</ul>
<blockquote>
<p>참고사이트</p>
</blockquote>
<ul>
<li><a href="https://velog.io/@thms200/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D">함수형 프로그래밍</a><ul>
<li><a href="https://velog.io/@kyusung/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%9A%94%EC%95%BD">함수형 프로그래밍 요약</a></li>
<li><a href="http://ruaa.me/why-functional-matters/">왜 함수형 프로그래밍이 좋을까?</a></li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 프레임워크]]></title>
            <link>https://velog.io/@nana_kim/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC</link>
            <guid>https://velog.io/@nana_kim/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC</guid>
            <pubDate>Mon, 28 Dec 2020 16:27:49 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>자바스크립트 프레임워크를 써봤는지? 써봤다면 어떤 걸 쓰는지? 만약 쓴다면 쓰는 이유와 썼을 때의 장점?</p>
</blockquote>
<h2 id="1-react-why-what">1. React. Why? What?</h2>
<ul>
<li>Application의 발전</li>
<li>사용자 인터페이스(UI)를 만들기 위한 JavaScript 라이브러리</li>
</ul>
<h2 id="1-why-react">1. Why React?</h2>
<p>애플리케이션의 규모가 커지고 다양한 UI(UI: User Interface),UX(UX: User Experience)를 구현하기 위해서는 이전의 방법(DOM,jQuery)으로는 애플리케이션을 개발하고 코드를 유지보수 하는 것이 어려워졌다. 규모가 커지고 복잡한 애플리케이션을 개발하며 생산성을 향상시키고 많은 데이터 관리와 코드 유지 보수를 더욱 편리하게 하기 위해 다양한 Frontend Framework(Library)가 등장하게 된다.</p>
<h2 id="1-2-frontend-frameworklibrary">1-2. Frontend Framework(Library)</h2>
<p>:: React
MVC(Model(data)-View-Controller) Architecture (ex. Angular, Vue)와는 다르게 <strong>리액트는 오로지 View만 담당</strong>한다. 그만큼 내장되어 있는 기능이 부족해 third-party 라이브러리(ex. React-router, Redux)를 함께 사용한다.
페이스북의 지속적인 관리와 함께 <strong>생태계가 활성화</strong> 되어 있으며 다양한 자료, 그리고 React Native의 사용으로 인해 사용자가 꾸준히 증가한다.</p>
<p>대답:
 html,css,로 개발했을 때는 유지보수가 어렵다는 것을 느꼈고, 프레임워크를 찾던 중,  react의 생태계가 활성화 되어있고 사용자도 많았습니다. 또한 React Native도 같이 할 수있다는 장점으로서 선택하여 공부하게 되었습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Javascript] this 란?]]></title>
            <link>https://velog.io/@nana_kim/Javascript-this-%EB%9E%80</link>
            <guid>https://velog.io/@nana_kim/Javascript-this-%EB%9E%80</guid>
            <pubDate>Mon, 28 Dec 2020 15:46:25 GMT</pubDate>
            <description><![CDATA[<p>지금까지 this를 써주긴했지만 왜 쓰는지? 언제 쓰는지? 적절하게 쓰는 방법을 잘 알지 못하고 썼다. 이번 this를 공부하면서 확실히 알아 this를 적용해야겠다 퐐로퐐로미~~!!!!</p>
<img src="https://app.jjalbang.today/jjv22y.jpg" width="300"/>

<blockquote>
<p>this란?
<strong>this는 일반적으로 메서드를 호출한 객체가 저장되어 있는 속성</strong>입니다. 하지만 this 속성은 <strong>메서드</strong>를 호출할 때뿐 아니라 <strong>일반 함수</strong>를 호출할 때도 만들어지며 <strong>이벤트 리스너가</strong> 호출될 때에도 this 속성이 만들어집니다. 문제는 this 속성에 저장되는 값이 동일한 값이 아니라 각각 다르다는 점입니다.</p>
</blockquote>
<p>this의 이해
this 바인딩을 통해 this가 어떤 값과 연결되는지 확인해볼 수 있습니다. 바인딩이란 this의 호출 방식에 따라 this가 특정 &#39;객체&#39;에 연결되는 것입니다. this 바인딩은 1.일반 함수 내부 2.메서드 내부 3.생성자 함수 내부 4.Call, Apply, Bind를 통한 &#39;호출 방식&#39;으로 나눠서 살펴볼 수 있습니다.</p>
<ol>
<li>일반 함수 호출 시 this는 전역 객체에 바인딩
<img src="https://images.velog.io/images/nana_kim/post/e3edc4d1-4e09-4de6-96e0-b392baf856b4/%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%202020-12-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.03.38.png" alt=""></li>
</ol>
<p>2.메서드 호출시 this는 호출한 객체에 바인딩
<img src="https://images.velog.io/images/nana_kim/post/7381d25b-47eb-4a8a-b2a6-1d2c754d136d/%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%202020-12-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.12.18.png" alt=""></p>
<p>3.New 바인딩
자바스크립트 함수 앞에 new를 붙여서 실행하며 다음과 같은 일이 일어난다.</p>
<ul>
<li>새로운 객체를 반환한다</li>
<li>새로운 객체는 객체의 메소드 호출시 this로 바인딩 된다.</li>
</ul>
<p>new로 반환된 obj 객체를 this 컨택스트와 바인딩 되는 규칙을 따른다.</p>
<p><img src="https://images.velog.io/images/nana_kim/post/6835a63f-dd1a-4915-993e-a54a47088fd5/%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%202020-12-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.24.12.png" alt=""></p>
<p>4.Call, Apply, Bind 메소드 사용시 메서드에 <strong>첫 번째 인수로 전달하는 객체에 바인딩</strong>
<strong>call과 apply 메소드는 기본적으로 함수를 호출</strong>하는 역할을 합니다. 그렇다면 기존 함수 호출고 차이점은? 바로 해당 메소드를 사용해 함수를 &#39;실행&#39;하면, 함수의 첫 번째 인자로 전달하는 객체에 this를 &#39;바인딩&#39; 할 수 있다는 것이다.반면, <strong>bind는 첫 번째 인자를 this에 바인딩하지만 함수를 &#39;실행하지 않으며&#39;, 새로운 함수를 반환</strong>합니다.</p>
<p><strong>call</strong>
call을 사용하면 함수를 실행하고 함수의 첫 번째 인자로 전달하는 값에 this를 바인딩합니다.
call()는 Function.prototype 객체의 프로퍼티 중의 하나다. logName.call() 형태로 사용할 수 있는 이유다.
call() 함수에 this 컨택스와 바인딩할 객체를 명시할 수 있다. logName() 함수가 실행되면 this는 글로벌 컨택스트가 아닌 obj 객체가 된다. this.name은 obj.name과 같다.
<img src="https://images.velog.io/images/nana_kim/post/3edda8fb-8ee9-402b-be37-f9482a4d0dd8/%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%202020-12-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.38.49.png" alt=""></p>
<p><strong>apply</strong>
apply를 사용하면 함수를 실행하고 함수의 첫 번째 인자로 전달하는 값에 this를 바인딩합니다. <strong>call과 차이점이라면 인자를 배열의 형태</strong>로 전달한다는 것입니다. 이때, 인자로 배열 자체가 전달하는 것이 아니라 배열의 요소들이 값으로 전달됩니다.
<img src="https://images.velog.io/images/nana_kim/post/2e87808d-b9ee-4de7-9f5c-ab42c1698b34/%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%202020-12-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.47.51.png" alt=""><img src="https://images.velog.io/images/nana_kim/post/699b8980-1df8-46ba-aebb-c8b54b07ca8e/%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%202020-12-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.48.06.png" alt=""></p>
<p><strong>bind</strong>
bind는 함수의 첫 번째 인자에 this를 바인딩한다는 점은 같지만, 함수를 실행하지 않으며 새로운 함수를 반환합니다. 즉, 반환된 새로운 함수를 실행해야 원본 함수가 실행됩니다. 
<img src="https://images.velog.io/images/nana_kim/post/0e255ee3-6051-4ae3-9886-900bb7a8faf5/%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%202020-12-29%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2012.35.51.png" alt=""></p>
<p><img src="https://images.velog.io/images/nana_kim/post/05ce0bf7-af30-4798-b11f-d979b24dff58/%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%202020-12-29%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%209.05.47.png" alt=""></p>
<h3 id="결론">결론</h3>
<p>이제 네 가지 바인딩의 우선순위를 정리할수 있다.</p>
<p>1) new로 함수를 호출했는가? 그럼 실행결과 반환되는 값이 this다.</p>
<blockquote>
<p>var obj = {}
hello.call(obj) // this === obj
hello.apply(obj) // this === obj
hello.bind(obj)() // this === obj</p>
</blockquote>
<p>3) 객체 프로퍼티로 접근하여 함수를 실행했는가? 그럼 이 객체가 this다.</p>
<blockquote>
<p>obj.hello() // this === obj</p>
</blockquote>
<p>4) 이외의 경우는 this는 전역 객체다.</p>
<p>브라우져의 경우 this는 Window 객체이고 엄격모드에서는 undefined 값이된다.</p>
<p><strong>정리</strong></p>
<p>this는 함수 호출 방식에 따라 동적으로 결정된다. 함수를 일반 함수로 호출할 경우 this는 전역 객체를, 메서드로 호출할 경우 이를 호출한 객체를, 생성자 함수를 호출할 경우 생성자 함수가 생성할 인스턴스를 가르키게 됩니다. call, apply,bind메소드 사용시 메서드에 첫 번째 인수로 전달하는 객체에 바인딩 됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SPA, MPA, CSR, SSR]]></title>
            <link>https://velog.io/@nana_kim/SPA-MPA-CSR-SSR</link>
            <guid>https://velog.io/@nana_kim/SPA-MPA-CSR-SSR</guid>
            <pubDate>Wed, 23 Dec 2020 06:43:08 GMT</pubDate>
            <description><![CDATA[<h2 id="spa-mpa-csr-ssr">SPA, MPA, CSR, SSR</h2>
<p>예전에도 배운적이 있지만, 다시한번 개념을 확실하게 정리하기 위해 글을 써보기로했다. 다른사람에게 촤르르르르! 설명할 수 있게!!</p>
<h2 id="📌about">📌About</h2>
<blockquote>
<p>CSR , SSR 그리고 SPA는 현대 웹개발에서 반드시 집고 넘어가야 할 개념입니다. SPA는 3세대 웹이 등장하면서 기존에 웹이 제공해 주지 못했던 풍부한 UX를 구현할 수 있게 해준 중요한 키워드 입니다. 이 SPA는 CSR과 SSR 이 두가 방법으로 지원할 수 있습니다.</p>
</blockquote>
<h2 id="web-system-architecture-history">Web System Architecture History</h2>
<h4 id="1-1세대-웹---전통적인-web-system-architecture-정적-웹">1. <strong>1세대 웹 - 전통적인 Web System Architecture. 정적 웹.</strong></h4>
<img src="https://images.velog.io/images/nana_kim/post/da3ee5b0-7a07-411c-9566-5ffd15cc8dc1/%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%202020-12-23%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2012.48.13.png" width=500/>
- 웹 서버가 HTML 페이지 전체를 클라이언트(ex. Web browser)에게 전송
- 초창기 웹사이트/서비스에 적합했던 시스템 - 초창기 웹사이트는 단순한 정보 제공 위주였다. 특별히 기능이 많지 않으며, 무엇보다 User Interaction 이 많이 요구되지 않았다.

<ul>
<li>1세대 웹이 정적인 이유? HTML, CSS 자체가 정적<ul>
<li><code>Hyper Text</code> : 링크로 연결된 문서</li>
<li><code>Markup Language</code> : “이렇게 보여줘라” 에 대한 지시</li>
<li><em>- <code>HTML</code> : 웹페이지의 내용을 브라우저에게 어떻게 렌더링(rendering) 해주라고 마크업 해주는 것*</em></li>
</ul>
</li>
<li>어떻게 보여지는가에 대한 것이기 때문에 로직(동적)이 없다. 정적.</li>
</ul>
<h4 id="2-2세대-웹-서비스---user-interaction-증가-동적-웹-javascript">2. 2세대 웹 서비스 - User Interaction 증가. 동적 웹 (JavaScript).</h4>
<img src= "https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F7aa878bd-8b42-4cd2-b36b-2459325f74b4%2Ffirst_version_of_spa_ajax.png?table=block&id=4ab9332d-6421-4d40-b5b3-78978168c92f&width=1540&userId=132fbb5b-0b62-42ca-b914-2abf03a2027c&cache=v2" width=500/>

<ul>
<li><strong>웹서비스들이 점점 발전함에 따라 단순한 정적 페이지가 아닌 다이나믹한 요소들이 요구됨.</strong></li>
<li><strong>웹 기반의 언어인 자바스크립트가 출현.</strong> 자바스크립트의 역할이 커지기 시작함.</li>
<li>참고) 그 이전의 언어들은 사용할 수 없었을까? 왜 자바스크립트가 필요했을까?</li>
<li><em>: 그 이전의 언어는 브라우저에서 동작을 안 함.*</em></li>
<li>이렇게 2세대 웹 서비스가 출현</li>
<li>Web server에서 전체 HTML 페이지 뿐만이 아니라 JavaScript를 통해 서버와 필요한 데이터만 주고 받음으로 dynamic한 user interaction을 구현하게 됨.</li>
<li>그러나 아직 JavaScript 는 일부분에서만 사용되었고, 또한 현재 통용되는 API 의 개념이 아직은 널리 사용 되지 않음 → 동일한 서버에서 HTML, Javascript(프론트 영역) 데이터(백엔드 영역) 둘 다 전송.<ul>
<li>ex. Django Template</li>
</ul>
</li>
</ul>
<h4 id="3-3세대-웹-서비스---spa-구별되기-시작하는-frontend--backend">3. 3세대 웹 서비스 - SPA. 구별되기 시작하는 Frontend / Backend.</h4>
<img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F14254c28-f8e6-47f5-bcdc-ed3af09b0bbf%2Fspa.png?table=block&id=a107600c-1e39-4d24-b47a-799860df4ccd&width=1540&userId=132fbb5b-0b62-42ca-b914-2abf03a2027c&cache=v2" width:500/>

<ul>
<li>동적인 기능이 주가 되버림. → 자바스크립트가 주가 되고 그 안에 일부 HTML, CSS 가 포함.</li>
<li><strong>이게 바로 <code>SPA(Single Page Application)</code> - 하나의 파일로 전체 사이트를 구현</strong></li>
<li>이름 그대로, 단일의 html 페이지에서 전체 웹 사이트/서비스를 구현.</li>
<li><strong>기존의 방식대로 서버가 페이지 구성에 필요한 모든 요소(HTML, JavaScript, Data)를 매번 전송하는 것이 아니라, 파일은 처음 한 번만 송수신. 그 뒤로는 실시간 데이터만 주고 받음.</strong></li>
<li><em>- 제일 처음 전송된 단일 HTML 페이지에 포함되어 있는 JavaScript 에서 필요한 데이터를 API 서버로부터 호출하여 필요한 화면을 dynamic 하게 새롭게 구성해주는 방식.*</em></li>
<li><strong>HTML 태그 자체를 자바스크립트가 동적으로 생성</strong></li>
<li>“명확히 두 개로 나눌 수 있겠다!” → 프론트엔드와 백엔드가 나뉘게 되는 기점.</li>
<li>즉 HTML/JavaScript 부분과 데이터 부분이 구조적으로 분리 되기 시작</li>
<li>→ Frontend 개발과 Backend 개발이 독립적으로 분리 (프론트 - UI UX / 백엔드 - Data)</li>
<li>명확히 나뉘어진 두 개의 시스템으로 웹이 동작하게됨.</li>
<li>기술 스택도 각자에 맞는 스택을 시용하기 시작함. (ex. <code>React</code> 의 출현!)</li>
<li>프론트엔드가 개발의 혁신이 빠른 이유도 이 분야 자체의 역사가 짧음.</li>
<li><strong>Frontend 와 Backend가 구조적으로 분리가 되면서, Frontend 서버와 Backend API 서버도 분리가 되며 그에 따라 Frontend 개발과 Backend 개발 업무가 분리가 되는 구조로 발전된다.</strong></li>
</ul>
<p><strong>&lt;html파일 수&gt;</strong></p>
<h3 id="mpa이란multi-page-application">MPA이란?(Multi Page Application)</h3>
<ul>
<li><p>일견 당연해보이기도 한다</p>
<p>  ⇒ 우리는 이미 여러 페이지를 넘나들며 사용하는 것처럼 보이기 때문</p>
</li>
<li><p>정적 웹사이트로 구성된 html 파일이 <strong>여러 개.</strong></p>
</li>
<li><p>정적 웹사이트?</p>
<ul>
<li>한번 만들어 놓으면 거의 안 바뀌는 페이지</li>
<li>html 자체가 만들어져서 날아오고 그걸 그대로 브라우저에 보여주는 방식</li>
</ul>
</li>
<li><p>페이지 이동 시 화면 깜빡임 O</p>
<img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F053fc833-c5c4-462a-bc38-61c6f74dae4a%2FUntitled.png?table=block&id=36e6ec60-03f3-458b-8321-580372665cdd&width=1000&userId=132fbb5b-0b62-42ca-b914-2abf03a2027c&cache=v2" width=400/>

</li>
</ul>
<h3 id="spa이란single-page-application">SPA이란?(Single Page Application)</h3>
<ul>
<li>html 파일이 한 개.</li>
<li>npm run build ⇒ html 파일 하나 생김 (ex. AWS 배포할 때)</li>
<li>페이지를 이동하려고 하면 자바스크립트 내의 특정 함수를 타서 <code>&lt;div id=&quot;root&quot; /&gt;</code> 의 내용을 싹 교체하는 것.</li>
<li>서버로부터 html 자체를 받아서 페이지를 바꾸는게 아니다.</li>
<li>페이지 이동 시 화면 깜빡임 X</li>
</ul>
<img src ="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Faa021bd9-e3a5-4b19-8be5-f078c6d54645%2FUntitled.png?table=block&id=9707e09f-73e4-444c-8786-b2c749f62f8a&width=880&userId=132fbb5b-0b62-42ca-b914-2abf03a2027c&cache=v2" width=400/>

<ul>
<li><strong>즉, 우리가 지금 얘기해볼 SSR은 SSR for SPA다.</strong><blockquote>
<ul>
<li><strong>또한, SPA(결과물) = CSR, SSR (렌더링 방법)로 나누어 이해하면 좋다.</strong></li>
</ul>
</blockquote>
</li>
</ul>
<h3 id="csr이란clinet-side-rendering">CSR이란?(Clinet Side Rendering)</h3>
<p>Clinet Side Rendering의 약자로써 최초에 1번 서버에서 전체 페이지를 로딩하여 보여주고 이후에는 사용자의 요청이 올 때 마다, 리소스를 서버에서 제공한 후 클라이언트가 해석하고 렌더링을 하는 방식입니다. 
<img src ="https://images.velog.io/images/nana_kim/post/7c2d991a-e2e5-4b22-a64d-e1488c01fae0/%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%202020-12-23%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2012.11.06.png" width=100/></p>
<ul>
<li>웹 페이지의 렌더링이 클라이언트(브라우저) 측에서 일어나는 것을 의미.</li>
<li>브라우저는 최초 요청에서 html, js, css 확장자의 파일을 차례로 다운로드.</li>
<li>최초로 불러온 html의 내용은 비어있음. (html, body 태그만 존재)</li>
<li>js 파일의 다운로드가 완료된 다음, 해당 js 파일이 dom을 빈 html 위에 그리기 시작.</li>
<li><strong>백엔드 호출을 최소화 할 수 있음</strong><ul>
<li>최초 호출 때만 html, js, css를 요청</li>
<li>이후에는 화면에서 변화가 일어나야 하는 만큼의 데이터만 요청 (ex. JSON)</li>
</ul>
</li>
<li><strong>라우팅(새로운 페이지로 이동)을 하더라도 html 자체가 바뀌는 것이 아니라 JavaScript 차원에서 새로운 화면을 그려내는 것!</strong></li>
</ul>
<blockquote>
<h3 id="1-create-react-app-cra-←-only-csr">1. Create React App (CRA) ← Only CSR</h3>
</blockquote>
<ul>
<li>아무런 초기 설정 없이도 CRA를 통해 React 기반의 SPA 사이트를 구현할 수 있게 됨.<ul>
<li>(과장 조금 보태서) 터미널에 <code>npx create-react-app my-app</code>, <code>npm run build</code> 명령어 만으로 사이트 하나를 만드는 것이 가능.</li>
<li>webpack, babel 등 복잡한 세팅을 거치지 않아 React 기반 웹 프로젝트 확산에 큰 기여.</li>
</ul>
</li>
<li>그런데 얼마 간 시간이 지나면서 조금씩 이상한 점이 드러나기 시작.<ul>
<li><strong>🤔: &quot;우리 사이트가 검색에 너무 안 걸리는걸?&quot;</strong></li>
<li>원인) CRA로 build한 프로젝트는 Only CSR(Client Side Render)로 실행되기 때문.</li>
</ul>
</li>
</ul>
<h3 id="ssr이란server-side-rendering">SSR이란?(Server Side Rendering)</h3>
<p>Server Side Rendering의 약자로써 단어 그대로!! <strong>서버에서 렌더링을 작업</strong>합니다. 기존에 존재하던 방식으로 사용자가 웹페이지에 접근할 때, 서버에 페이지에 대한 요청을 하며 서버에서는 html,view와 같은 리소스들을 어떻게 보여질지 해석하고 렌더링하여 사용자에게 반환합니다.</p>
<p>웹에서 제공하는 정보량이 많아지고 데스크탑보다 성능이 다소 떨어지는 스마트폰의 웹에 대한 요구가 커지면서 새로운 기법이 탄생했습니다.
<img src ="https://images.velog.io/images/nana_kim/post/37b7a7ea-8491-45f9-9be9-67c90e28e2c4/%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%202020-12-23%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2012.33.31.png" width=100/><img src ="https://images.velog.io/images/nana_kim/post/d929c1e6-ca19-4280-8f61-fbe3ebcbc9be/%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%202020-12-23%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2012.33.42.png" width=100/></p>
<h3 id="csr과-ssr의-차이점">CSR과 SSR의 차이점</h3>
<img src="https://images.velog.io/images/nana_kim/post/fdee1b04-fa37-41c4-babb-54d4bc8814da/%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%202020-12-23%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%201.09.04.png" width=700/>


<h4 id="1-초기-렌더링-속도">1. 초기 렌더링 속도</h4>
<p>:CSR의 경우, 사용자의 행동에 따라 필요한 부분만 다시 읽어들이기 때문에 서버 측에서 렌더링하여 전체 페이지를 다시 읽어들이는 것보다 빠른 반응속도를 기대할 수 있습니다<strong>.클라이언트 측에서 렌더링을 하게 되면 서버 사이드 렌더링이 따로 필요하지 않기 때문에 일관성 있는 코드를 작성할 수 있습니다.
CSR은 페이지를 읽어들이는 시간, 자바스크립트를 읽어들이는 시간, 그리고 자바스크립트가 화면을 그리는 시간까지 모두 마쳐야 콘텐츠가 사용자에게 보여집니다. 여기서 웹서버에서 콘텐츠 데이터라도 가져와야 한다면 그 시간은 더욱 길어집니다. 즉, **초기 구동속도가 느려집니다. 초기 구동속도를 제외하고는 빠른 반응을 보여줍니다.</strong></p>
<p>이와 반대로 <strong>SSR의 경우 서버에서 view를 렌더링하여 가져오기 때문에 view를 보기까지 초기 구동속도가 빠릅니다.</strong> 물론 JS파일을 전부 다운로드 받기 전까지는 제대로 동작하지 않지만 <strong>사용자 측면에서는 빠르다 느낄 수 있습니다.</strong></p>
<h4 id="2seo">2.SEO</h4>
<p>SEO(Search Engine Optimization(최적화))
<strong>대부분의 웹 크롤러, 봇들이 자바스크립트 파일을 실행시키지 못하고 HTML에서만 컨텐츠를 수집합니다.</strong> 때문에 CSR 방식으로 개발된 페이지를 빈 페이지로 인식하게 됩니다. 검색엔진에 제대로 노출이 되지 않는 다면 웹페이지의 유입이 줄어든다.</p>
<p>그렇다면....그 웹사이트는.....
<img src ="https://images.velog.io/images/nana_kim/post/56aa2ff3-4954-4651-bef6-9b204338c8c8/image.png" width=400/></p>
<ul>
<li><p><strong>🤔 : &quot;SPA의 장점을 살리면서 SEO도 같이 챙길 수는 없을까?&quot;</strong></p>
<p>  <strong>⇒ SSR (Server Side Rendering)</strong></p>
</li>
</ul>
<p><strong>SSR은 view를 서버에서 전부 렌더링하여 내려주므로 HTML에 모든 컨텐츠가 저장되어 있기 때문에 SEO 적용에 큰 문제가 없습니다.</strong></p>
<h4 id="3보안">3.보안</h4>
<p>기존에 SSR에서는 사용자에 대한 정보를 서버 측에서 세션으로 관리를 하지만 CSR방식은 클라이언트 측의 쿠키말고는 사용자에 대한 정보를 저장할 공간이 없습니다.</p>
<blockquote>
<h2 id="csr--ssr-⇒-nextjs-like-cra">CSR + SSR? ⇒ Next.js (like CRA)</h2>
</blockquote>
<ul>
<li>그렇다면 SSR과 CSR을 섞어 쓸 수는 없나요?</li>
<li>사용할 수 있다! ⇒ 생산성을 위해 Next.js가 주로 채택됨</li>
<li>SSR의 CRA, 간단히 구성 가능</li>
<li>원티드, 토스, 배민, 카카오커머스 등 사용 중</li>
</ul>
<p>Next.js는 간단하게 말하면 리액트에서 SSR을 쉽게 적용할 수 있게 해주는 라이브러리이다.
첫 번째, 사용자가 처음 페이지를 접속을 요청 했을때 Next.js 서버는 사용자에게 랜더링될 HTML을 응답 값으로 보내줍니다 ( SSR 방식 ).
두 번째, 그 후 브라우저는 추가적인 자바스크립트 번들을 다운로드 받아 실행합니다.
세 번째, 사용자가 해당 페이지에서 다른 페이지로 이동할때는 Next.js에 서버가 아닌 브라우저에서 처리하여 이동하게 합니다. ( CSR 방식 )</p>
<p><strong>&gt;:: 원리 &amp; 구조</strong></p>
<img src ="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F4facd1e6-f271-46fc-83d4-cb354240f533%2FUntitled.png?table=block&id=7ae4a91e-a497-498d-8e8f-461a95f191f3&width=990&userId=132fbb5b-0b62-42ca-b914-2abf03a2027c&cache=v2"/>

<ul>
<li><strong>SSR은</strong> 다음과 같은 <strong>요소로 구성된다</strong><ul>
<li>node.js로 구성된 FE 서버</li>
<li>pyhton, django로 되어 있는 BE 서버</li>
</ul>
</li>
<li>다음과 같은 과정을 거쳐 SSR이 진행된다<ol>
<li>유저가 브라우저에 <strong><code>/index</code></strong>를 입력.</li>
<li>미리 실행되고 있는 FE 서버가 요청을 받고 서버사이드 렌더링.</li>
<li>만들어진 html 을 브라우저에게 보냄.</li>
<li>브라우저가 응답받은 html 을 그림.</li>
<li>html 에 기능을 부여할 <strong><code>main.js</code></strong>파일을 다운로드 받음. (hydration)</li>
<li>다운로드가 완료된 이후, <strong><code>go to second</code></strong> 링크를 클릭.</li>
<li><strong><code>/second</code></strong>로 라우팅하고 second 페이지 코드를 생성.</li>
</ol>
</li>
</ul>
<h4 id="용어">용어</h4>
<hr>
<p><strong>hydration</strong></p>
<ul>
<li>서버에서 전송한 정적 문서를 데이터 변경에 반응할 수 있는 동적 형태로 변환하는 클라이언트 측 프로세스를 말한다.</li>
<li>render와 동일하지만, dom은 이미 그려져 있는 상태이기 때문에 event listener만 부착하는 식으로 작동.</li>
</ul>
<blockquote>
<p>정리
웹서비스들이 점점 발전하고 User Interaction이 증가함에 따라 단순한 정적 페이지가 아닌 다이나믹한 user interaction을 구현한 동적인 웹으로 발전했다.이에 따라 MPA(Multi Page Application)에서 SPA(Single Page Application)으로 발전되고 SPA의 CSR, SSR 렌더링 방법이 나오게 되었다. CSR은 (Client Side Rendering) 최초에 1번 서버에서 전체페이지를 로딩하여 보여주고 이후에는 사용자의 요청이 오면 클라이언트가 해석하고 렌더링 하는 방식이다. 아무런 초기 설정 없이도 CRA(라이브러리)를 통해 React 기반의 SPA 사이트를 구현할 수 있게 되었다.하지만 CSR 방식으로 개발된 페이지를 빈 페이지로 인식하게되어 검색엔진에 제대로 노출되지 않는 SEO(Search Engine Optimizaion)문제가 발생하게 되었다. SPA의 장점을 살리면서 SEO도 같이 챙길 수는 없을까?&quot;라는 고민끝에 SSR이 나왔다. SSR은 (Server Side Rendering)은 서버에서 렌더링을 작업하는 것을 말한다. SSR은 view를 서버에서 전부 렌더링 하여 내려주므로 HTML에 모든 컨텐츠가 저장되어 있기 때문에 SEO 적용에 큰 문제 가 없다. CSR과 SSR의 장점과 생산성을 위해 사용할 수 있는 Next.js(라이브러리/:프론트 서버에서 백엔드 서버에게 직접 요청 가능함)있는데 SSR의 CRA 으로 간단히 구성이 가능하다. </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[React-Reduxs]]></title>
            <link>https://velog.io/@nana_kim/React-Reduxs</link>
            <guid>https://velog.io/@nana_kim/React-Reduxs</guid>
            <pubDate>Sun, 06 Dec 2020 14:38:16 GMT</pubDate>
            <description><![CDATA[<h2 id="reduxs의-중요한-3가지">reduxs의 중요한 3가지</h2>
<h3 id="store">store</h3>
<ul>
<li>리덕스의 상태를 가지는 단일 객체</li>
</ul>
<blockquote>
<pre><code>import { Provider } from &quot;react-redux&quot;;
import { createStore } from &quot;redux&quot;;
import rootReducer from &quot;./store/reducers&quot;;
const store = createStore(rootReducer);
ReactDOM.render(
  &lt;Provider store={store}&gt;
    &lt;Routes /&gt;
  &lt;/Provider&gt;,
  document.getElementById(&quot;root&quot;)
);</code></pre></blockquote>
<h3 id="action">action</h3>
<ul>
<li>스토어 어떤 값을(payload) 어떻게(type) 업데이트 할 지 적어놓는 객체
액션 생성함수는 그 액션 객체를 생성하는 역할을 하는 함수
액션 객체를 <strong>dispatch</strong> 메서드에 넣어서 호출하면 리듀서를 거쳐 스토어를 업데이트 한다.</li>
</ul>
<blockquote>
<pre><code>export const addCart = (item) =&gt; { // 액션 &quot;생성 함수&quot;
  return {
    type: &quot;ADD_ITEM&quot;, // 액션 &quot;객체&quot;
    payload: item,
  };
};</code></pre></blockquote>
<pre><code>
### reducer
- reducer는 action이 발생했을 때 새로운 상탯값을 만드는 함수

&gt; ```
// store/reducer/index.js
import { combineReducers } from &quot;redux&quot;;
import cartReducer from &quot;./cartReducer&quot;;
export default combineReducers({ cartReducer });
// cartReducers.js
function cartReducer(state = INITIAL_STATE, action) {
  switch (action.type) {
    case &quot;ADD_ITEM&quot;:
      return [...state, action.payload];
        case &quot;DELETE_ITEM&quot;:
            return [...action.payload]
    default:
      return state; 
  }
}</code></pre><h2 id="reduxs-상태-값-사용법">Reduxs 상태 값 사용법</h2>
<h3 id="reduxs-폴더-구조">Reduxs 폴더 구조</h3>
<p>예시) 장바구니 페이지
src
├── Components
│   ├── CartItem.js
│   ├── CartNoti.js
│   ├── ProductCard.js
│   └── Nav.js
├── Pages
│   ├── CartList.js // 상품 리스트 페이지
│   └── ProductList.js // 장바구니 페이지
├── Routes.js
├── index.js
└── store
├── actions
│   └── index.js // 액션 객체들
└── reducers
├── cartReducer.js // 개별 리듀서
└── index.js // 루트 리듀서</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[git ]]></title>
            <link>https://velog.io/@nana_kim/git-pahgv1lb</link>
            <guid>https://velog.io/@nana_kim/git-pahgv1lb</guid>
            <pubDate>Sun, 06 Dec 2020 14:22:46 GMT</pubDate>
            <description><![CDATA[<h2 id="초기세팅후-remote-연동">초기세팅후 remote 연동</h2>
<h3 id="git-초기화">git 초기화</h3>
<blockquote>
<p>git init</p>
</blockquote>
<p>*<em>git으로 관리할 파일을 추가합니다.
*</em></p>
<blockquote>
<p>git add .</p>
</blockquote>
<p><strong>commit</strong></p>
<blockquote>
<p>git commit -m &quot;Add : 초기세팅&quot;</p>
</blockquote>
<p><strong>main branch로 바꿔줍니다.</strong></p>
<blockquote>
<p>git branch -M main</p>
</blockquote>
<p><strong>repo에 연결</strong></p>
<blockquote>
<p>git remote add origin <a href="https://github.com/">https://github.com/</a>(대충 repo주소)</p>
</blockquote>
<p><strong>repo로 push</strong></p>
<blockquote>
<p>git push origin main</p>
</blockquote>
<h2 id="작업">작업</h2>
<p><strong>clone받을 폴더로 이동해서 clone 받습니다.</strong></p>
<blockquote>
<p>git clone origin <a href="https://github.com/">https://github.com/</a>(대충 repo주소)</p>
</blockquote>
<p><strong>브랜치 생성</strong></p>
<blockquote>
<p>git branch feature/login(작업단위 프로잭트 이름)</p>
</blockquote>
<p><strong>작업할 브랜치로 이동</strong></p>
<blockquote>
<p>git checkout feature/login</p>
</blockquote>
<h2 id="작업-후-pr">작업 후 PR</h2>
<blockquote>
<p>git add .
git commit -m &quot;Add : blabla&quot;</p>
</blockquote>
<p><strong>main에 변동사항, 혹은 complict 있을 수 있으니 메인으로 이동 후 pull 당깁니다.</strong></p>
<blockquote>
<p>git checkout main
git pull</p>
</blockquote>
<p><strong>main코드를 내 코드와 merge 해보고 conflict가 났는지 확인하고 수정합니다.</strong></p>
<blockquote>
<p>git checkout feature/login
git merge main</p>
</blockquote>
<p><strong>다시 저장 후 push</strong></p>
<blockquote>
<p>git add .
git commit -m &quot;Add : blabla&quot;
git push origin feature/login</p>
</blockquote>
<blockquote>
<p>github로 이동 후 PR</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[React Styled Components]]></title>
            <link>https://velog.io/@nana_kim/React-Styled-Components-hfzl97ni</link>
            <guid>https://velog.io/@nana_kim/React-Styled-Components-hfzl97ni</guid>
            <pubDate>Sun, 06 Dec 2020 14:14:15 GMT</pubDate>
            <description><![CDATA[<h3 id="styled-components">Styled Components</h3>
<p><img src="https://images.velog.io/images/nana_kim/post/c8e0aa0a-1d65-4ca2-a16d-181ea68497f8/image.png" alt="">
CSS-in-JS 방법으로 문서에 style을 주는 것이 새롭게 적용되고 있는 흐름이 보입니다. 그 중에서도 styled-component 라이브러리가 2018년 이후 폭팔적인 사용을 보이고 있는 것을 볼 수 있습니다.</p>
<p><strong>Styled Components의 장점</strong>
스타일이 컴포넌트와 결합되어 모듈화가 수월하다.
현대 앱은 컴포넌트를 중심으로 개발되어 지고 있기 때문에 매우 강력하다.
Styled Components 사용예
prop에 따른 style변화를 줄 수 있다.</p>
<blockquote>
<pre><code>render(
  &lt;div&gt;
    &lt;Button&gt;Normal&lt;/Button&gt;
    &lt;Button width=&quot;100&quot;&gt;Primary&lt;/Button&gt;
  &lt;/div&gt;
);
const Button = styled.button`
  background: ${props =&gt; props.width &lt; 200 ? &quot;red&quot; : &quot;white&quot;};
`;</code></pre></blockquote>
<pre><code>
**전역 props로 obj 전달**
&gt;```
const App = () =&gt; (
  &lt;React.Fragment&gt;
    &lt;GlobalStyle /&gt;
    &lt;div&gt;Hi, I&#39;m an app!&lt;/div&gt;
  &lt;/React.Fragment&gt;
}</code></pre><p>index.js에 Routes위에 GlobalStyle 넣어주고 걔한테 props로 them.js를 export해서 전달해준다. 그러면 어디서든 props를 불러와서 사용할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[fetch() 함수 사용법(3)]]></title>
            <link>https://velog.io/@nana_kim/fetch-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%EB%B2%953</link>
            <guid>https://velog.io/@nana_kim/fetch-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%EB%B2%953</guid>
            <pubDate>Sun, 29 Nov 2020 13:39:31 GMT</pubDate>
            <description><![CDATA[<h3 id="fetch-함수---method가-get인데-parameter를-전달해야-하는-경우">fetch() 함수 - method가 get인데 parameter를 전달해야 하는 경우</h3>
<p>get 예제에서 3이라는 user id를 path로 넘겨주었습니다. 그런데 path 말고 query string으로 넘겨줘야 할 수도 있습니다.</p>
<blockquote>
<pre><code>설명: 유저 정보를 가져온다.
base url: https://api.google.com
endpoint: /user
method: get
query string: ?id=아이디
응답형태:
    {
        &quot;success&quot;: boolean,
        &quot;user&quot;: {
            &quot;name&quot;: string,
            &quot;batch&quot;: number
        }
    }</code></pre></blockquote>
<blockquote>
<p>fetch(&#39;<a href="https://api.google.com/user?id=3&#39;">https://api.google.com/user?id=3&#39;</a>)
  .then(res =&gt; res.json())
  .then(res =&gt; {
    if (res.success) {
        console.log(<code>${res.user.name}</code> 님 환영합니다);
    }
  });</p>
</blockquote>
<h3 id="fetch-함수---resjson의-의미">fetch() 함수 - res.json()의 의미</h3>
<blockquote>
<pre><code>fetch(&#39;https://api.google.com/user&#39;, {
    method: &#39;post&#39;,
    body: JSON.stringify({
        name: &quot;yeri&quot;,
        batch: 1
    })
  })
  .then(res =&gt; res.json())   // 왜 then이 두개고 res.json() 은 뭔지?
  .then(res =&gt; {
    if (res.success) {
        alert(&quot;저장 완료&quot;);
    }
  })</code></pre></blockquote>
<p>  첫 번째 then 함수에 전달된 인자 res는 http 통신 요청과 응답에서 응답의 정보를 담고 있는 객체입니다. Response Object 라고 합니다.</p>
<p>그런데 console을 확인해보시면 백앤드에서 넘겨주는 응답 body, 즉 실제 데이터는 보이지 않을 것입니다. 즉 { success: true } 라는 JSON 데이터는 위의 코드로는 console에 찍히지 않을 것이라는 말입니다.</p>
<p><strong>응답으로 받는 JSON 데이터를 사용하기 위해서는 Response Object 의 json 함수를 호출하고, return 해야합니다. 그러면 두 번째 then 함수에서 응답 body의 데이터를 받을 수 있습니다.</strong></p>
<blockquote>
<pre><code>fetch(&#39;http://example.com/movies.json&#39;)
  .then(response =&gt; response.json())
  .then(data =&gt; console.log(data));</code></pre></blockquote>
<pre><code>
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[fetch() 함수 사용법_post]]></title>
            <link>https://velog.io/@nana_kim/fetch-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%EB%B2%95post</link>
            <guid>https://velog.io/@nana_kim/fetch-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%EB%B2%95post</guid>
            <pubDate>Sun, 29 Nov 2020 13:31:59 GMT</pubDate>
            <description><![CDATA[<h3 id="fetch-함수---method가-post인-경우">fetch() 함수 - method가 post인 경우</h3>
<p>post인 경우에는 fetch() 함수에 method 정보를 인자로 넘겨주어야 합니다.</p>
<blockquote>
<pre><code>설명: 유저를 저장한다.
base url: https://api.google.com
endpoint: /user
method: post
요청 body:
    {
        &quot;name&quot;: string,
        &quot;batch&quot;: number
    }
응답 body:
    {
        &quot;success&quot;: boolean
    }</code></pre></blockquote>
<pre><code>
&gt; ```
fetch(&#39;https://api.google.com/user&#39;, {
    method: &#39;post&#39;,
    body: JSON.stringify({
        name: &quot;yeri&quot;,
        batch: 1
    })
  })
  .then(res =&gt; res.json())
  .then(res =&gt; {
    if (res.success) {
        alert(&quot;저장 완료&quot;);
    }
  })
</code></pre><p>1.두 번째 인자에 method와 body를 보내주어야 합니다.
2.method는 post
3.body는 JSON형태로 보내기 위해 JSON.stringfy() 함수에 객체를 인자로 전달하여 JSON형태로 변환했습니다.</p>
<p>post로 데이터를 보낼 때 JSON.stringfy를 항상 하다보니 axios는 굳이 감싸주지 않고 객체만 작성해도 되는 편리한 점이 있습니다. 이렇듯 axios는 소소하게 편한한 설정을 제공해주고, 요청과 응답에 대한 확장성 있는 기능을 만들 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[fetch() 함수 사용법_get]]></title>
            <link>https://velog.io/@nana_kim/fetch-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%EB%B2%95get</link>
            <guid>https://velog.io/@nana_kim/fetch-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%EB%B2%95get</guid>
            <pubDate>Sun, 29 Nov 2020 13:26:19 GMT</pubDate>
            <description><![CDATA[<p>백앤드로부터 데이터를 받아오려면 api를 호출하고 데이터를 응답받습니다. 이 때 자바스크립트** Web API fetch() 함수<strong>를 쓰거나</strong> axios 라이브러리**를 사용할 수 있습니다.</p>
<h2 id="fetch-함수-기본">fetch() 함수 기본</h2>
<blockquote>
<pre><code>fetch(&#39;api 주소&#39;)
  .then(res =&gt; res.json())
  .then(res =&gt; {
    // data를 응답 받은 후의 로직
  });</code></pre></blockquote>
<pre><code>
&gt;```
fetch(&#39;api 주소&#39;)
  .then(function(res) {
    return res.json();
  })
  .then(function(res) {
    // data를 응답 받은 후의 로직
  });</code></pre><h3 id="fetch-함수---method가-get인-경우">fetch() 함수 - method가 get인 경우</h3>
<blockquote>
<pre><code>설명: 유저 정보를 가져온다.
base url: https://api.google.com
endpoint: /user/3
method: get
응답형태:
    {
        &quot;success&quot;: boolean,
        &quot;user&quot;: {
            &quot;name&quot;: string,
            &quot;batch&quot;: number
        }
    }</code></pre></blockquote>
<pre><code>
호출하려면 아래와 같이 하면됨.
&gt; ```
fetch(&#39;https://api.google.com/user/3&#39;)
  .then(res =&gt; res.json())
  .then(res =&gt; {
    if (res.success) {
        console.log(`${res.user.name}` 님 환영합니다);
    }
  });

  리액트를 한다고 가정하면, 아래와 같이 구현할 수 있습니다.

&gt;```
import React, { Component } from &#39;react&#39;;
class User extends Component {
  componentDidMount() {
    // user id가 props를 통해 넘어온다고 가정
    const { userId } = this.props;
    fetch(`https://api.google.com/user/${userId}`)
      .then(res =&gt; res.json())
      .then(res =&gt; {
        if (res.success) {
            console.log(`${res.user.name}` 님 환영합니다);
        }
      });
  }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Git Workflow & Rebase]]></title>
            <link>https://velog.io/@nana_kim/Git-Workflow-Rebase</link>
            <guid>https://velog.io/@nana_kim/Git-Workflow-Rebase</guid>
            <pubDate>Sun, 22 Nov 2020 08:52:20 GMT</pubDate>
            <description><![CDATA[<h2 id="til_git에서-rebase써서-commit-횟수를-줄여보자">TIL_Git에서 rebase써서 commit 횟수를 줄여보자!</h2>
<h3 id="rebase란">rebase란</h3>
<p>단어 그대로 기준을 설정한다는 뜻이다. 쪼꼼 바꿔말하면.. 우리가 Git에 commit한 history를 바꿔버릴 수 있는 무시무시한 녀석이다. </p>
<h3 id="백업">백업</h3>
<p>바로 백업이다! 혹시 날릴수도 있으니 미리 백업을 해둔다. 실제로 동기님중에 rebase땜에 파일도 멘탈도 탈탈 털린분이 있다 ㅠㅠ 그냥 복붙해서 다른폴더에 저장해도 좋지만! 우린 개발을 배우는 사람이니까 명령어를 써보자.</p>
<blockquote>
<pre><code>cp -rpv adwards-frontend adwards-frontend2</code></pre></blockquote>
<pre><code>
cp -rpv옆에 왼쪽꺼가 현재의 폴더명, 오른쪽이 새로 생성할 폴더명

이 때 경로를 조심해야 한다! 내 폴더가 속하기 바로 전 단계의 경로에서 저걸 실행해야 한다. (나의 경우는 front-end 폴더) 명령어를 입력하면 이렇게 쌍둥이 폴더가 뙇! 생긴다.

### 다시 이동
&gt;cd adwards-frontend 다시 원본폴더로 이동 

### 중간에 tig 깔아주었음
&gt;apt-get install tig

### gcm
rebase를 하기 전에 우리는 로컬에 있는 master 브랜치를 업데이트 해줘야 한다! 그러기 위해선 체크아웃을 해준다.
</code></pre><blockquote>
<p>git checkout master git pull origin master</p>
</blockquote>
<pre><code>
pull까지 땡겼으면 다시 마스터에서 원래 작업하던 브랜치로 돌아간다. 쳌아웃! 그 전에 git status 명령어를 쳐서 내가 정말로 커밋을 다 끝냈는지 확인한다. rebase는 push 전 단계에서 하는거기 때문에 commit까진 다 해야한다.

### rebase
최근 커밋 리스트 개수 세는 rebase
&gt;git rebase -i HEAD~3

### master 브랜치에 직접 접근하는 방식
&gt;git rebase -i master feature/ad_upload

### 이미 Github에 PR을 날린 상태라면?
위의 과정과 마찬가지로 진행하는데 push 하는 과정에서 force push를 해줘야한다. 
&gt;git push origin -f 브랜치명
이렇게 진행하면 된다!



</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[React] Hooks(2)]]></title>
            <link>https://velog.io/@nana_kim/React-Hooks2</link>
            <guid>https://velog.io/@nana_kim/React-Hooks2</guid>
            <pubDate>Sun, 22 Nov 2020 08:44:40 GMT</pubDate>
            <description><![CDATA[<h2 id="2-2-mentors-tip">2-2 Mentor&#39;s Tip</h2>
<ul>
<li>기존 setState와 마찬가지로 비동기 update</li>
<li>useState 실행 시 state, setState 한 쌍이 부여됨</li>
</ul>
<h2 id="3-effect-hook">3. Effect Hook</h2>
<p>Effect Hook, 즉 useEffect는 함수 컴포넌트 내에서 이런 side effects를 수행할 수 있게 해줍니다. React class의 componentDidMount 나 componentDidUpdate, componentWillUnmount와 같은 목적으로 제공되지만, 하나의 API로 통합된 것입니다.</p>
<blockquote>
<pre><code>useEffect(function);
useEffect(() =&gt; {}, [count]) // 의존성 배열 (배열 안에 담긴 값들을 추적, 그때 마다 업데이트)</code></pre></blockquote>
<pre><code>
# :: How to use useEffect!
&gt;```
useEffect(() =&gt; {
    console.log(&quot;componentDidUpdate&quot;)
})
useEffect(() =&gt; {
    console.log(&quot;componentDidMount&quot;)
    return () =&gt; console.log(&quot;componentWillUnmount&quot;)
}, [])
useEffect(() =&gt; {
    console.log(&quot;componentDidMount&quot;)
    console.log(&quot;componentDidUpdate&quot;) // + shouldComponentUpdate
    return () =&gt; console.log(&quot;???&quot;)
}, [state])
// WRONG!!
useEffect(() =&gt; {
    console.log(&quot;CDM 쓰고 싶어요&quot;)
}, [])
useEffect(() =&gt; {
    console.log(&quot;CDU 쓰고 싶어요&quot;)
}, [state])</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[React] Hooks(1)]]></title>
            <link>https://velog.io/@nana_kim/React-Hooks1</link>
            <guid>https://velog.io/@nana_kim/React-Hooks1</guid>
            <pubDate>Sun, 22 Nov 2020 08:35:29 GMT</pubDate>
            <description><![CDATA[<h3 id="1-1-hooks란">1-1. Hooks란?</h3>
<p><strong>Hook은 함수 컴포넌트에서 React state와 생명주기 기능(lifecycle features)을 “연동(hook into)“ 할 수 있게 해주는 함수입니다.</strong></p>
<ul>
<li>Hook은 class 안에서는 동작하지 않습니다.</li>
<li>대신 class 없이 React를 사용할 수 있게 해주는 것입니다.</li>
</ul>
<h3 id="1-2-왜-사용하나요">1-2. 왜 사용하나요?</h3>
<ul>
<li><strong>컴포넌트 사이에서 상태와 관련된 로직을 재사용하기 어렵습니다.</strong> (HOC, render props)</li>
<li><strong>복잡한 컴포넌트들은 이해하기 어렵습니다.</strong> (관심사의 분리, Lifecycle API)</li>
<li><strong>Class은 사람과 기계를 혼동시킵니다.</strong><ul>
<li>그러나, Class 컴포넌트가 이러한 최적화를 더 느린 경로로 되돌리는 의도하지 않은 패턴을 장려할 수 있다는 것을 발견했습니다. Class는 최근 사용되는 도구에도 많은 문제를 일으킵니다. 예를 들어 Class는 잘 축소되지 않고, 핫 리로딩을 깨지기 쉽고 신뢰할 수 없게 만듭니다. 우리는 코드가 최적화 가능한 경로에서 유지될 가능성이 더 높은 API를 제공하고 싶습니다. (공식 문서)</li>
<li>&quot;클래스는 많은 기능을 한 번에 묶는데는 성공을 했지만, 그 결과 각각을 따로 쓰기 힘들게 만들어버렸습니다. 클래스는 State와 Action(메서드)의 조합이라고 이야기를 했습니다. State와 Action을 각각 따로 분리해서 생각을 할 수는 없습니다.&quot; </li>
</ul>
</li>
</ul>
<h3 id="-클래스에서-클로저closure로">:: 클래스에서 클로저(Closure)로!</h3>
<ul>
<li><strong>리액트에 존재하는 컴포넌트 종류?</strong><ul>
<li><strong>그간 왜 클래스 컴포넌트를 써왔을까?</strong><ul>
<li>state, 라이프 사이클 때문에</li>
<li>마치 생명체처럼 클래스로 부터 한번 인스턴스가 생성이 되고 나면 독립적으로 움직일 수 있어서</li>
<li>반면 함수는 한번 호출되고 메모리 상에서 사라짐 ⇒ <strong>state, 라이프 사이클 불가능</strong></li>
</ul>
</li>
<li><strong>클래스 사용해보니 해결하기 힘든 여러가지 문제 존재</strong></li>
</ul>
</li>
<li><strong>함수 컴포넌트에 날개를 달아줘!</strong><ul>
<li><strong>2018년에 hooks 공개!</strong></li>
<li>그러면 어떻게 state, 라이프사이클을 구현했나?</li>
<li><strong>클로저! (함수 안의 함수!)</strong></li>
</ul>
</li>
</ul>
<h3 id="1-3-hook-사용-규칙">1-3. Hook 사용 규칙</h3>
<p>규칙
1: 최상위(at the top level)에서만 Hook을 호출해야 합니다. 그리고 반복문, 조건문, 중첩된 함수 내에서 Hook을 실행하지 마세요.
규칙 2 : React 함수 컴포넌트 내에서만 Hook을 호출해야 합니다. 일반 JavaScript 함수에서는 Hook을 호출해서는 안 됩니다</p>
<h2 id="2-state-hook">2. State Hook</h2>
<blockquote>
<pre><code>const [state, setState] = useState(initialState);</code></pre></blockquote>
<p>상태 유지 값과 그 값을 갱신하는 함수를 반환합니다. 최초로 렌더링을 하는 동안, 반환된 state(<code>state</code>)는 첫 번째 전달된 인자(<code>initialState</code>)의 값과 같습니다.</p>
<p><code>setState</code> 함수는 state를 갱신할 때 사용합니다. 새 state 값을 받아 컴포넌트 리렌더링을 큐에 등록합니다.</p>
<blockquote>
<pre><code>// 클래스형 컴포넌트
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }
render() {
    return (
      &lt;div&gt;
        &lt;p&gt;You clicked {this.state.count} times&lt;/p&gt;
        &lt;button onClick={() =&gt; this.setState({ count: this.state.count + 1 })}&gt;
          Click me
        &lt;/button&gt;
      &lt;/div&gt;
    );
  }
}</code></pre></blockquote>
<blockquote>
<pre><code>import React, { useState } from &#39;react&#39;;
// 함수 컴포넌트
function Example() {
  // 새로운 state 변수를 선언하고, count라 부르겠습니다.
  const [count, setCount] = useState(0);
    const [isModalActive, setIsModalActive] = useState(false);
    // 안 좋은 예시
    const [state, setState] = useState({
        color: &quot;red&quot;,
        isActive: true,
        name: &quot;jt&quot;.
        password: &quot;sdaf&quot;
    })
    return (
    &lt;div&gt;
      &lt;p&gt;You clicked {count} times&lt;/p&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
        Click me
      &lt;/button&gt;
    &lt;button onClick={() =&gt; setIsModalActive(!isModalActive)}&gt;modal btn&lt;/button&gt;
    &lt;/div&gt;
    );
        }</code></pre></blockquote>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[ [2차 클론 프로젝트]Wanted]]></title>
            <link>https://velog.io/@nana_kim/2%EC%B0%A8-%ED%81%B4%EB%A1%A0-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8Wanted</link>
            <guid>https://velog.io/@nana_kim/2%EC%B0%A8-%ED%81%B4%EB%A1%A0-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8Wanted</guid>
            <pubDate>Sun, 15 Nov 2020 16:03:56 GMT</pubDate>
            <description><![CDATA[<h3 id="🙋🏻♀️-프로젝트-소개">🙋🏻‍♀️ 프로젝트 소개</h3>
<blockquote>
<p>원티드랩이라는 스타트업에서 운영중인 채용 플랫폼. 2015년부터 서비스하기 시작했다. 특징은 추천이라는 기능이 있어 지원할 때 지인의 추천/추천사를 함께 붙일 수 있고, 합격한 경우 합격자와 추천인에게 50만원 이상의 보상금을 지급한다. 국내 다른 구인구직 서비스 대비 깔끔한 UI가 돋보이는 편. 웹과 iOS, Android를 지원한다.</p>
</blockquote>
<h3 id="👨👨👧👦-개발-기간-및-인원">👨‍👨‍👧‍👦 개발 기간 및 인원</h3>
<h3 id="👑-team-winted">👑 Team Winted</h3>
<h3 id="👩👩👧👧frontend">👩‍👩‍👧‍👧FrontEnd</h3>
<p>‣ 김수연
‣ <strong>김한나</strong>
‣ 민지연
‣ 이예린</p>
<h3 id="👨👨-backend">👨‍👨‍ BackEnd</h3>
<p>‣ 김형욱
‣ 박재용</p>
<h3 id="프로젝트-기간">프로젝트 기간</h3>
<p>2020.11.02 ~ 2020.11.13 약 2주간 진행</p>
<h3 id="프로젝트-영상">프로젝트 영상</h3>
<p><a href="https://www.youtube.com/watch?v=--cqt9fAI9w&amp;t=6s">링크텍스트</a></p>
<h3 id="🔧-적용-기술">🔧 적용 기술</h3>
<p><strong>Frontend</strong>
. React / React-Redux / React-Hooks / React-router / Styled Component / Chart.js
. JavaScript(ES6) / Sass / HTML
<strong>BackEnd</strong>
. Python / Django
. CORS Header / Bcrypt / PyJWT / MySQL / REST API / AqueryTool (데이터베이스 모델링)
<strong>공통</strong>: git / github, Postman, Trello</p>
<h3 id="⭐️-구현-기능">⭐️ 구현 기능</h3>
<p>회원가입, 로그인/로그아웃 (소셜로그인)
** &gt; NAV bar**
구직정보 리스트 탐색페이지
** &gt; 구직정보 상세 페이지**
직군별 연봉 페이지
이력서 관리 페이지
회원 추천 페이지</p>
<h3 id="🔥-기억에-남는-코드">🔥 기억에 남는 코드</h3>
<p><img src="https://images.velog.io/images/nana_kim/post/899a0ac5-83b2-4243-98fd-c5603332fbf8/%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%202020-12-05%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%202.25.43.png" alt=""><img src="https://images.velog.io/images/nana_kim/post/46a6376d-2c68-4987-bae0-b25e55abddca/%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%202020-12-05%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%202.33.52.png" alt=""></p>
<p>원티드 기업 위치를 제공하기 위해 구글맵 API 사용했다. 구글맵이 주는 가이드데로만 하면 쉽게 되겠지라 생각했었는데 얼마 지나지 않아 에러와 마주하게 되었다. 백엔드에서 주는 position data가 적용되지 않는 문제가 발생했다.문제는 부모 componet 에서 자식 componet인 MapContent의 data를 원활하게 받아오지 못하는 것이었다. 해결방법은 markerPosition의 조건부 렌더링을 통해 data를 명확하게 받아올 수 있게하여 해결했다.</p>
<h3 id="🦸-느낀점">🦸 느낀점</h3>
<p>1차 프로젝트가 끝나자마자 2차 프로젝트가 시작되었다. 1차프로젝트를 해봤으니 2차 프로젝트는 그보다는 수월하겠지..라는 생각했는데.그건 큰 착각이였다. 2차 프로젝트 기간동안 React hook, styled component, Redux를 배웠고 그것을 코드에 적용해야했다. 2차 프로젝트는 심적으로나 체력적으로도 많이 힘이 들었지만 함께한 팀원들이 할 수 있다! 잘하고 있다는 긍정적에너지에 금새 이겨낼 수 있었다. 프로젝트 발표 날 새벽, git rebase를 잘못해서 코드가 눈앞에서 사라지는 일도 있었고, 팀 발표 직전까지 라이브 코딩을 했었지만 그것 또한 재밌는 에피소드가 되었다. 프로젝트 기간내내 새벽까지 함께 고생한 우리 윈티드 팀! 발표하는 동안 서로의 고생을 알기에 눈시울이 붉어졌고, 발표가 끝난 후 말없이 서로의 손을 잡아주던 장면이 아직도 생생하게 남아있다. 다음에도 이런 설렘과 기대로 또 다른 프로젝트를 시작하고 싶다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Query parameters, URL parameters]]></title>
            <link>https://velog.io/@nana_kim/Query-parameters-URL-parameters</link>
            <guid>https://velog.io/@nana_kim/Query-parameters-URL-parameters</guid>
            <pubDate>Sat, 14 Nov 2020 13:40:00 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/nana_kim/post/6625d844-42cc-4846-a994-d9d27b2656c3/%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%202020-11-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.22.37.png" alt="">
-위의 코드를 보면 현재 리스트 페이지와 디테일 페이지가 각각 컴포넌트로 구현되어 있고, url path로 /list, 혹은 /detail 설정 시 해당 컴포넌트로 이동하도록 되어 있습니다.</p>
<p>-하지만, 상세 페이지로 이동할 경우 화면이 나타나긴 하겠지만 어떤 상품에 대한 상세 페이지를 나타낼지 알 수 있는 방법이 없습니다.</p>
<p>-이번 시간에는 유동 라우터을 통해 리스트 페이지와 디테일 페이지를 연결하는 방법에 대해 알아보도록 하겠습니다.</p>
<p>동적라우팅</p>
<h3 id="동적라우팅이란">동적라우팅이란?</h3>
<p>동적라우팅이란? 위에서 살펴본 경우과 같이 라우트의 경로에 특정 값을 넣어 해당 페이지로 이동할 수 있게 하는 것 (Dynamic Routing)
React Router에서는 두 가지 방법을 통해 유동 라우팅 기능을 구현할 수 있습니다.</p>
<ol>
<li>Query parameters</li>
<li>URL parameters</li>
</ol>
<h3 id="라우트로-설정한-컴포넌트의-3가지-props">라우트로 설정한 컴포넌트의 3가지 props</h3>
<blockquote>
<p><strong>history</strong>
이 객체를 통해 push, replace 를 통해 다른 경로로 이동하거나 앞 뒤 페이지로 전환 할 수 있습니다.
여러분들이 컴포넌트 이동(페이지 전환) 시에 this.props.history.push(&#39;/page&#39;) 를 통해 이동할 수 있었던 이유가 여기 있습니다.
<strong>location</strong>
이 객체는 현재 경로에 대한 정보를 지니고 있고, URL 쿼리 (/company_list?category=3)에 대한 정보도 가지고 있습니다.
<strong>match</strong>
이 객체에는 어떤 라우트에 매칭이 되었는지에 대한 정보가 있고 params (/company_detail/:id) 정보를 가지고있습니다.</p>
</blockquote>
<h3 id="1-로그인-성공-시--리스트-페이지">1. 로그인 성공 시 &gt;&gt;&gt; 리스트 페이지</h3>
<p>로그인 성공시 리스트 페이지로 넘어가게 하는 함수입니다.</p>
<p><img src="https://images.velog.io/images/nana_kim/post/d2159f34-1f2a-4524-be07-30f6cc2ad059/%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%202020-11-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.28.13.png" alt=""></p>
<p>login을 시도하면 API와 통신하고 토큰 유무를 확인합니다.
토큰이 있으면 로컬 스토리지에 저장하고,
/company_list?category=3 주소의 URL로 이동하도록 설정되어 있습니다.
company_list 페이지로 이동하는 건 알겠는데 category=3 은 무엇을 의미하는걸까요?</p>
<p><img src="https://images.velog.io/images/nana_kim/post/f961907a-781c-41dc-96bc-a01c5d1f03b2/%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%202020-11-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.33.50.png" alt="">
그림은 /company_list 페이지 화면입니다.
크게 3가지 카테고리가 있는데, 각각 아래와 같이 설정되어 있습니다.
FrontEnd : category=1 / BackEnd : category=2 / FullStack : category=3
즉, 로그인 성공 시 /company_list?category=3 주소의 URL로 이동하도록 설정되어 있는 것은 처음 리스트 화면 진입 시에 FullStack에 해당하는 데이터를 화면에 보여주겠다는 뜻 입니다.
(참고로 현재는 API가 연결되어 있지 않아 로딩 화면만 계속 보이네요🤭)
여기서 사용한 방법이 Query parameters 입니다!</p>
<h3 id="🔥-query-parameters">🔥 Query parameters</h3>
<p>url의 주소가 /company_list?category=3 인 경우
this.props.location을 통해서 해당 주소의 정보를 가지고 올 수 있습니다.</p>
<blockquote>
<h3 id="location">location</h3>
<p>이 객체는 현재 경로에 대한 정보를 지니고 있고,
URL 쿼리 (/company_list?category=3)에 대한 정보도 가지고 있습니다.</p>
</blockquote>
<ol start="2">
<li>리스트 페이지 진입
해당 코드는 리스트 페이지에서 componentDidMount 함수 안에 작성한 fetch 함수 부분입니다.
<img src="https://images.velog.io/images/nana_kim/post/3760bbb7-091d-4f2f-b95c-193c1964bd28/%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%202020-11-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.36.35.png" alt=""></li>
</ol>
<p>📌 this.props.location.search (코드 31번째 줄)
this.props.location.search에 접근합니다.
this.props.location.search 를 console.log로 확인 시 ?category=3 가 나옵니다. 즉, url 주소에서 /company_list 뒤에 붙은 부분이 나타납니다.
그 중, backend에서 API호출 시 필요한 정보는 숫자 3 입니다.
그래서 this.props.location.search.split(&quot;=&quot;)[1] 을 통해 숫자 3을 찾아 변수 queryId에 저장합니다.</p>
<p>📌 this.props.location.search (코드 31번째 줄)
this.props.location.search에 접근합니다.
this.props.location.search 를 console.log로 확인 시 ?category=3 가 나옵니다. 즉, url 주소에서 /company_list 뒤에 붙은 부분이 나타납니다.
그 중, backend에서 API호출 시 필요한 정보는 숫자 3 입니다.
그래서 this.props.location.search.split(&quot;=&quot;)[1] 을 통해 숫자 3을 찾아 변수 queryId에 저장합니다.
📌 fetch 함수를 통한 API 호출 (코드 36번째 줄)
(이 부분에서는 URL parameters가 사용되었네요. 아래에서 자세히 볼거니깐 &#39;그렇구나! 이렇게 생겼구나!&#39; 하고 넘어가주세요.😬)
fetch 함수를 통한 API 호출 시, API 주소 가장 뒷 부분에 변수에 담은 숫자 3을 포함시키는 것을 확인할 수 있습니다.
즉, &quot;fullstack 데이터를 갖는 API를 호출하려면 주소 뒤에 3을 붙여줘&quot; 라고 프론트와 백이 약속으로 정했기 때문에 프론트에서는 url 주소에서 그 숫자를 찾아 fetch 함수에서 사용하는 것입니다.
그렇다면 FULLSTACK API 호출 결과 받은 해당 데이터, 즉 FullStack에 해당하는 회사 리스트를 화면에 보여줄 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 리액트 라우터]]></title>
            <link>https://velog.io/@nana_kim/React-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%9D%BC%EC%9A%B0%ED%84%B0</link>
            <guid>https://velog.io/@nana_kim/React-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%9D%BC%EC%9A%B0%ED%84%B0</guid>
            <pubDate>Sat, 14 Nov 2020 13:21:08 GMT</pubDate>
            <description><![CDATA[<h3 id="route-와-파라미터">Route 와 파라미터</h3>
<p><img src="https://images.velog.io/images/nana_kim/post/98a44a2c-2981-4df3-b8eb-d9d258c27805/%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%202020-11-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.02.30.png" alt=""></p>
<p>라우트를 설정 할 때에는 Route 컴포넌트를 사용하고, 경로는 path 값으로 설정합니다.</p>
<p>첫번째 라우트 / 의 경우에는 Home 컴포넌트를 보여주게 했고, 두번째 라우트 /about 에서는 About 컴포넌트를 보여주게 했습니다.</p>
<p>첫번째 라우트의 경우엔 exact 가 붙어있지요? 이게 붙어있으면 주어진 경로와 정확히 맞아 떨어져야만 설정한 컴포넌트를 보여줍니다.</p>
<p>먼저 우리의 라우트가 제대로 보여지는지 확인하세요.</p>
<h3 id="라우트-파라미터-읽기">라우트 파라미터 읽기</h3>
<p>라우트의 경로에 특정 값을 넣는 방법을 알아보겠습니다. 방법은 두가지가 있는데요, params 를 사용하는 것 과, query 를 사용하는 것 입니다.</p>
<p>라우트로 설정한 컴포넌트는, 3가지의 props 를 전달받게 됩니다:</p>
<p>history 이 객체를 통해 push, replace 를 통해 다른 경로로 이동하거나 앞 뒤 페이지로 전환 할 수 있습니다.
location 이 객체는 현재 경로에 대한 정보를 지니고 있고 URL 쿼리 (/about?foo=bar 형식) 정보도 가지고있습니다.
match 이 객체에는 어떤 라우트에 매칭이 되었는지에 대한 정보가 있고 params (/about/:name 형식) 정보를 가지고있습니다.</p>
<p><img src="https://images.velog.io/images/nana_kim/post/2d7ccfa2-5f94-47b4-810a-562e998038e9/%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%202020-11-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.08.38.png" alt=""></p>
<p>URL 쿼리의 경우엔 컴포넌트 내에서 동적으로 사용 할 수 있고, params 의 경우엔 사용하기 전에 꼭 라우트에서 지정을 해주어야합니다.</p>
<p>params
그러면, 먼저 params 부터 사용을 해봅시다.</p>
<p>App 컴포넌트에서 다음과 같이 /about/:name 라우트를 추가하세요.</p>
<p><img src="https://images.velog.io/images/nana_kim/post/5cfb0afa-d966-4989-a86e-6dfb45109403/%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%202020-11-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.09.55.png" alt=""></p>
<p>Link 컴포넌트
앱 내에서 다른 라우트로 이동 할 때에는, 일반 <a href...>foo</a> 형식으로 하면 안됩니다. 왜냐하면, 이렇게하면 새로고침을 해버리기 때문이지요.</p>
<p>새로고침을 하기 위해선, 리액트 라우터에 있는 Link 컴포넌트를 사용해야합니다. 이 컴포넌트를 사용하면 페이지를 새로 불러오는걸 막고, 원하는 라우트로 화면 전환을 해줍니다.</p>
<p>그럼, 한번 사용해볼까요?</p>
<p>components 디렉토리에 Menu 라는 컴포넌트를 다음과 같이 만들어보세요:
<img src="https://images.velog.io/images/nana_kim/post/3746de8a-452b-4f5d-a16c-d61f28d11436/%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%202020-11-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.15.56.png" alt=""></p>
<p>페이지가 새로 로딩되지 않으면서 잘 전환이 되나요?</p>
<p>이 컴포넌트에 전달되는 props 들은 컴포넌트 내부의 DOM 에도 전달이 되므로, 일반 DOM 엘리먼트에 설정 하는 것 처럼 className, style 혹은 onClick 등의 이벤트를 전달 해 줄 수 있습니다.</p>
<p>NavLink 컴포넌트
NavLink 컴포넌트는 Link 랑 비슷한데요, 만약에 설정한 URL 이 활성화가 되면, 특정 스타일 혹은 클래스를 지정 할 수 있습니다.</p>
<p><img src="https://images.velog.io/images/nana_kim/post/9fc9afc3-e819-45f7-960d-d4b834625775/%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%202020-11-14%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.20.12.png" alt="">
Route 를 지정 할 때 처럼, 중첩될수도 있는 라우트들은 exact 로 설정을 하셔야 합니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[중간 시험 #2. Git]]></title>
            <link>https://velog.io/@nana_kim/%EC%A4%91%EA%B0%84-%EC%8B%9C%ED%97%98-2.-Git</link>
            <guid>https://velog.io/@nana_kim/%EC%A4%91%EA%B0%84-%EC%8B%9C%ED%97%98-2.-Git</guid>
            <pubDate>Sun, 08 Nov 2020 13:34:58 GMT</pubDate>
            <description><![CDATA[<ol>
<li>git repositiories (사이트에서 만든다)</li>
</ol>
<p>-&gt; 터미널
git init
git remote add origin (주소)
git add .
git commit -m &quot;&quot;
(git branch -M main : push 하기 바로 전에 main branch로 변경 git branch -M main)
git push origin main</p>
<p>2.git branch feature/readme : 브랜치 생성
git checkout feature/readme : 브랜치 이동
git add . 
git commit -m &quot;&quot;
git push origin feature/readme</p>
<p>3.pull request : 사이트 이용/ 요청하기</p>
<p>*cd : (가자!) 이동
ls :  위치에 있는 파일 불러보기</p>
<p>branch : main 옆 가지, main에 올리기전 하위폴더(?)로 작업할 수있다. 작업용파일올리기느낌? branch에서 최종master로...
(대게 페이지나, 기능으로 나뉜다.)</p>
<p>remote : local과 내컴퓨터...연결</p>
]]></description>
        </item>
    </channel>
</rss>