<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>개린이의 개발블로그🧐</title>
        <link>https://velog.io/</link>
        <description>👩🏻‍💻 매일매일이 기대되는 개발자 ^^</description>
        <lastBuildDate>Wed, 27 Apr 2022 02:26:05 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>개린이의 개발블로그🧐</title>
            <url>https://images.velog.io/images/j-jhoo/profile/6f2b7f71-15dd-46c0-93b6-fdaa86f7d91b/velog 프로필.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 개린이의 개발블로그🧐. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/j-jhoo" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[PJ1. jlab_ebook]]></title>
            <link>https://velog.io/@j-jhoo/PJ1.-jlabebook</link>
            <guid>https://velog.io/@j-jhoo/PJ1.-jlabebook</guid>
            <pubDate>Wed, 27 Apr 2022 02:26:05 GMT</pubDate>
            <description><![CDATA[<h3 id="🛎---프로젝트-소개">🛎   <strong>프로젝트 소개</strong></h3>
<blockquote>
<p><strong>✏️</strong>  이번 프로젝트는 사용자가 로그인을 한 후 소설 페이지가 보여지고, 소설을 보다가 랜덤의 확률로 광고 팝업창이 나오게 된다. 이 광고창은 사용자가 종료할 수 없고, 5초 동안 강제 시청이 된 후 5초가 지나면 자동 종료된다. 광고창이 종료 될때 50%로의 확률로 적립금 모달창이 구현되고, 적립금 모달창도 2초가 지나면 자연 종료되는 모바일 버전의 소설 앱이다.</p>
</blockquote>
<hr>
<h3 id="📆--진행-기간"><strong>📆  진행 기간</strong></h3>
<ol start="2022">
<li><ol start="4">
<li>08 ~ 2022. 04. 19
(약 1주간 진행)</li>
</ol>
</li>
</ol>
<hr>
<h3 id="👭--팀-구성">👭  팀 구성</h3>
<p>Design, Publish : 이나영
Front, Back : 정지후</p>
<hr>
<h3 id="💻--기술-스택">💻  기술 스택</h3>
<p>AI문서, 와이어프레임, Figma, html, Css, Javascript, jQuery, php, PDO, SQL</p>
<hr>
<h3 id="🌀--구현-기능">🌀  구현 기능</h3>
<ul>
<li>소설 페이지 아래로 스크롤 되면서, 무한스크롤로 기능 구현<ul>
<li>무한스크롤 될 때 페이지가 변경되면 텍스트의 색상이 변경되도록 구현</li>
</ul>
</li>
<li>모달창 구현<ul>
<li>랜덤 확률로 광고 모달창이 보여지고, 사용자가 종료할 수 없도록 5초동안 강제시청 후 강제 종료</li>
<li>포인트 적립금 모달창이 50%로의 확률로 구현 되고 2초 후 강제 종료 되게 구현</li>
</ul>
</li>
<li>디비 모델링<ul>
<li>프로젝트에 필요한 데이터를 처음 디비 모델링을 통해서 테이블 작성</li>
</ul>
</li>
<li>php , PDO 작성,<ul>
<li>모델링한 데이터들을 php, PDO를 통해서 작성</li>
</ul>
</li>
<li>aJax<ul>
<li>프론트와 백엔드와의 데이터 전송을 aJax로 구현</li>
</ul>
</li>
</ul>
<hr>
<h2 id="프로젝트-시작">프로젝트 시작!!!</h2>
<p>✏️   처음 프로젝트를 시작하면서 노션에 프로젝트 기간별 상세 업무를 작성해서 sprint형식으로 작성해서 구현 상황들을 매일매일 체크했다. </p>
<p><a href="https://www.notion.so/7a4d78c458484a6fb8cc53052edef53c">Project - jlab_eBook</a></p>
<p><img src="https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f51a6a55-2650-4fc7-bdc7-212ad00d1d6d/Untitled.png" alt="Untitled"></p>
<h3 id="😳-어려웠던-부분">😳 어려웠던 부분</h3>
<p>중첩된 기능들을 함수 코드로 구현하는데 꽤 많은 시간이 소요되었다. </p>
<p>무한스크롤링 이벤트가 일어나면서 랜덤 확률료 광고 모달창이 구현되고, 그 모달창은 5초 동안 강제 시청 후 자동 종료 되게 구현해야했다. 또 그 광고창이 종료되면서 50% 확률로 적립금 모달창이 팝업으로 떠오르고, 2초 후 강제 종료. 그 광고 적립창에는 사용자에게 적립된 적립금과 이름, 총 적립금을 보여 줘야 했다. 그 부분을 php PDO로 작성하는데 오류를 접근하는데도 꽤 애를 먹었고 어려웠던 기억이 많이 남는다. ㅠㅠㅠ </p>
<ol>
<li>먼저 무한스크롤링 이벤트에 대한 코드다.</li>
</ol>
<pre><code class="language-jsx">// 스크롤링 이벤트를 구현하는데 필요한 것들을 변수로 선언

let scroll_event_flag = 10; //스크롤 이벤트를 발생시킬 임의의 기준 값
let body_height = document.body.offsetHeight; //현재 문서의 총 높이
let scroll_observe_start = false; //스크롤 이벤트 활성화 여부 (스크롤이 발생하지 않는 컨텐츠를 고려)
let is_modal_show = false; //모달창 중복출력 방지용 플래그 값
const random_color = [&#39;00FF7F&#39;, &#39;    006400&#39;, &#39;7CFC00&#39;, &#39;FF4500&#39;, &#39;FF00FF&#39;,&#39;00FFFF&#39;, &#39;FFFF00&#39;, &#39;0000FF&#39;, &#39;FF0000&#39;];

// 기본적으로 소설 텍스트 1페이지가 보여지도록 구현한 코드 
$(document).ready(function(){
    get_content(1);
  })

//ajax를 통해서 json파일을 불러오도록 구현
  function get_content(page){
    $.ajax({
      url: &quot;./resource/json/data.json&quot;,
      dataType: &quot;json&quot;,
      success: function(res){
        // 인자값으로 받은 페이지 정보와 각 json객체가 보유한 id와 맵핑
        $(&quot;#content_area&quot;).append(res.data[page-1].text);
        // json 데이터 중 소설 내용 Dom객체 바인딩 이후 문서의 총 높이 파악 후 변수에 할당
        body_height= document.body.offsetHeight;
        $(&quot;#page_num&quot;).val(page);
        $(&#39;.av_modal&#39;).css(&#39;height&#39; , body_height); //모달 백그라운드 높이값도 현재 문서 총 높이와 동일하게 설정
        scroll_observe_start = true;
      }
    });
  }

// 윈도우 스크롤 이벤트
  $(window).scroll(function(){
    let down_position = $(&quot;#scroll_page&quot;).offset().top; 
    //스크롤 이동시 작동코드 (scroll_observe_start가 true이고 현재 스크롤위치가 400px이상(임의 초기 값) 일때부터)
    if(scroll_observe_start &amp;&amp; $(this).scrollTop() &gt;= 800){
      let now_scroll_position = $(this).scrollTop();
      if(now_scroll_position%scroll_event_flag == 1){ // 현재 스크롤위치에서 위에서 임의로 설정한 기준치를 나누었을 떄 나머지가 1로 떨어지는 경우(임의설정)에만 모달이벤트 실행 
        // make_modal();
      }
    }
      if($(this).scrollTop() &gt;= body_height-screen.height) {
        let next_page = Number($(&quot;#page_num&quot;).val())+1 
        alert(&#39;next page : &#39;+ next_page);
        get_content(next_page);
        $(&#39;#content_area&#39;).css(&quot;color&quot;, &quot;#&quot; + random_color[Math.floor(Math.random() * random_color.length)]);
        make_modal(); //페이지 전환에 따른 광고 모달창 띄우기
      }
  });</code></pre>
<p>👉   이 코드들은 전부 나 혼자 로직을 구현한 것이 아니라, 많이 물어봤고, 원격으로 코드 알려주시는 걸 보면서 이해했던 코드이다. 무한 스크롤링을 구현하는데 하단부의 지정된 값에 들어가면 다음 페이지가 자동으로 넘어가는 형식으로 구현했다. </p>
<ul>
<li>스크롤을 발생시킬 값</li>
<li>현재 문서의 총 높이 값 - 현재 보여지는 문서의 값</li>
<li>Number() 숫자로 변경해주는 메소드</li>
</ul>
<ol>
<li>모달창 (광고, 포인트 적립금)</li>
</ol>
<pre><code class="language-jsx">function make_modal() {
    if(!is_modal_show){
      const result = Math.floor(Math.random() * videos.length);
      let adv_link = videos[result];
      // console.log(&#39;make_modal : &#39; + adv_link)
      $(&quot;#modal_video&quot;).attr(&#39;src&#39;, adv_link);
      $(&quot;#modal_video&quot;).css(&#39;width&#39;, &#39;280px&#39;);
      $(&quot;#modal_video&quot;).css(&#39;height&#39;, &#39;400px&#39;);

      // modal_call -&gt; 모달 실행해 5초동안 그리고 꺼져.
      control_modal(&#39;ad_modal&#39;, 5000);
    } else if (!is_modal_show) {
      $(&#39;body&#39;).css(&#39;overflow-y&#39;,&#39;auto&#39;);
    }
  };

  // 공통 모달(광고, 적립금 모달)
  function control_modal(selectorClass, close_duration){
    if(selectorClass == &#39;ad_modal&#39;){
      if(Math.floor(Math.random()* 10) &lt; 5){ //위 조건을 모두 충족한다해도 50%확률로 다시 검사하여 출력여부 결정 
        $(&quot;.&quot;+selectorClass).fadeIn();
      }
    }else{
      $(&quot;.&quot;+selectorClass).fadeIn();
    }
    is_modal_show = true;
    $(&#39;body&#39;).css(&#39;overflow-y&#39;,&#39;hidden&#39;);
    setTimeout(function(){
      $(&#39;body&#39;).css(&#39;overflow-y&#39;,&#39;auto&#39;);
        $(&quot;.&quot;+selectorClass).fadeOut();
        is_modal_show = false;
        if(selectorClass == &#39;ad_modal&#39;){
          emoney_check();
        }
      }, close_duration)
    }

// 포인트 적립금 모달창 
function emoney_check(){
    // 50% 확률로 지급 여부결정 
    let able_update = Math.floor(Math.random() * 10) &lt; 5;
    let user_id = 1; //적립할 대상 회원의 고유 아이디 고정
    let value = 500; //적립금액 고정
    if(able_update){
      insert_emoney(user_id, value);
    }else{
    } 
  }</code></pre>
<p>👉   처음 광고 모달창을 구현하는데 까지는 함수를 짰었다. 그런데 포인트 적립금 모달과 광고 모달을 공통 함수로 작성하는 곳에서 헷갈리고 어려움이 있었다. 반복되는 로직 이였으므로 공통 함수로 빼고, 이것이 코드의 가독성과 단순함으로서 좋은 코드를 작성할 수 있는 방법이라는 것을 알게 되었다. </p>
<hr>
<h3 id="✏️--php-pdo">✏️  php PDO</h3>
<p>이번 프로젝트에서 처음으로 백엔드 파트를 진행해보았다. </p>
<p>디비 모델링, 데이터를 생성하는것, 백엔드에서 어떤식으로 코드를 보내주는지도 처음으로 알게 되었다. 😂</p>
<p>먼저 php는 프론트와, 백엔드 두개의 영역을 하나의 언어로 모두 다 만들 수 있는 언어라는 것을 알게 되었다. 이 php에서 PDO라는 <strong>여러 데이터베이스를 제어하는 방법을 표준화시킨 것으로</strong> 아직도 낯설고 생소하지만 계속 공부 중에 있다. </p>
<p>일부 간단한 login.php, 로그인시에 php문서를 정리해보았다. </p>
<pre><code class="language-php">&lt;?php
include_once(&#39;../common.php&#39;);

// ex) 조회의 경우 GET요청만 허용하고 나머지는 POST만 허용하기로 하였을 때
$table_name = &#39;db_user&#39;; //필수적인것은 아니나 오타, 기타 이슈 발생 예방 차원에서 테이블 네임을 글로벌 변수에 담아 사용
$query = &#39;SELECT * FROM &#39;.$table_name.&#39; WHERE email = &quot;&#39;.$_POST[&#39;email&#39;].&#39;&quot; AND name = &quot;&#39;.$_POST[&#39;name&#39;].&#39;&quot; AND pwd = &quot;&#39;.$_POST[&#39;pwd&#39;].&#39;&quot;&#39;;   //띄어쓰기 주의 
$stmt = $db-&gt;query($query);
$result = $stmt-&gt;fetch(PDO::FETCH_ASSOC);
if (isset($result)) {
  $code = 200;
  session_start();
  if ($_SESSION[&#39;name&#39;] = $result[&#39;name&#39;]) {
    $message = &quot;로그인에 성공하셨습니다.&quot;;
    header(&#39;location: http://combinedev.cafe24.com/jlab_eBook/novel.html&#39;);
  }
}

// JSON 응답할때 객체 형태로 클라이언트측에 
echo json_encode(array(
  &#39;code&#39; =&gt; $code,
  &#39;message&#39; =&gt; $message,
  &#39;result&#39; =&gt; $result
)); 

?&gt;</code></pre>
<ul>
<li>SELECT FROM = 어디로부터 조회하다.</li>
<li><ul>
<li>(아스타) = 전체 데이터를 의미한다.</li>
</ul>
</li>
<li>WHERE = 어디에서 (email이라는 위치를 표시해준다)</li>
<li>$db→query($query) = 데이터를 읽어오는 쿼리 실행시, 결과 객체를 반환 해준다(입력, 수정 쿼리 실행시에 성공여부에 따라 true, false로 반환)</li>
<li>fetch(PDO::FETCH_ASSOC) 결과를 반환해준다(key값으로 접근 가능하도록 해준다)<ul>
<li>fetchAll(PDO::FETCH_ASSOC) 일 경우에는 결과를 배열로 한번에 전부 반환해준다.</li>
</ul>
</li>
<li>isset() = 변수가 있는지, 없는지 확인하는 함수</li>
<li>Sessiont_start() = 클라이언트에 값을 저장하지 않고 서버쪽에 값을 저장, 즉 사용자의 값을 서버에 저장해주는 역할</li>
</ul>
<hr>
<h3 id="☀️--프로젝트를-마무리하며">☀️  프로젝트를 마무리하며</h3>
<p>📌  아쉬웠던 점 </p>
<ul>
<li>개인적으로 많은 공부가 필요하고 오류가 났을 때 당황하지 않고 침착하게 오류 메세지를 분석하고 그 오류를 해결 할 수 있는 능력을 키워야겠다는 생각이 많이 들었었다.</li>
<li>PDO, php라는 처음 써본 언어에 대해서 그 언어를 조금 더 빠르게 숙지할 수 있고 빠르게 코드를 응용해 볼 수 있는 공부를 해야겠다는 생각이 들었다.</li>
<li>코드를 짤때도 무조건적으로 바로 찾아보고 힌트를 얻고 이런 것을 반복하기 보다는 처음에는 조금 맨  땅에 스스로 로직을 생각해보고 이 로직을 어떻게 코드화 할 수 있을지에 대한 생각을 해야겠다 라는 생각이 많이 들었다.</li>
</ul>
<p>💛  첫 실무 협업 프로젝트이다보니, 설렘도 컸고, 열정도 더 높았던것 같다. 하지만 아직은 그 열정에 비해 나의 실력이 많이 부족하다는 것을 느끼고 더 많이 공부하고 노력해야겠다는 생각이 들었다. 또한 어떻게 하면 좋은 코드, 어떻게 하면 이 오류를 해결 할 수 있을지(침착하게 디버깅하는 방법), 조금 더 구체적으로 생각 해봐야 할 필요가 있다는 것을 알았다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL _ React]]></title>
            <link>https://velog.io/@j-jhoo/TIL-React</link>
            <guid>https://velog.io/@j-jhoo/TIL-React</guid>
            <pubDate>Wed, 23 Mar 2022 08:52:00 GMT</pubDate>
            <description><![CDATA[<h1 id="01">01.</h1>
<h2 id="👩🏻💻-til---1-react에서-props를-데이터를-전달-받을-때-새로운-변수명을-할당하는-방법">👩🏻‍💻 TIL - 1. React에서 props를 데이터를 전달 받을 때 새로운 변수명을 할당하는 방법</h2>
<h3 id="🧐-기존에-알고-있던-방법">🧐 기존에 알고 있던 방법</h3>
<p>✓ 기존에는 props를 데이터를 전달받고</p>
<ul>
<li>props.명 이렇게 작성했다.</li>
</ul>
<img width="565" alt="스크린샷 2022-03-23 오후 4 58 55" src="https://user-images.githubusercontent.com/89238394/159656461-c96ac3f3-b36a-4743-9020-29059c1601cf.png">


<h3 id="📌-새롭게-알게된-방법">📌 새롭게 알게된 방법</h3>
<p>✓ <b>클론</b>을 이용하는 방법이다.</p>
<ul>
<li><b>:</b> 을 사용하고 원하는 변수명을 작성하면 된다.</li>
</ul>
<img width="588" alt="스크린샷 2022-03-23 오후 4 57 58" src="https://user-images.githubusercontent.com/89238394/159656509-84c2343a-6856-4bde-8d61-0a11901089a6.png">
]]></description>
        </item>
        <item>
            <title><![CDATA[React _ 04. ]]></title>
            <link>https://velog.io/@j-jhoo/React-04</link>
            <guid>https://velog.io/@j-jhoo/React-04</guid>
            <pubDate>Wed, 23 Mar 2022 08:50:44 GMT</pubDate>
            <description><![CDATA[<h2 id="🌈--react--fetch">🌈 &nbsp; React &nbsp; fetch</h2>
<h3 id="🧐-fetch-란">🧐 fetch 란???</h3>
<p>✓ fetch는 브라우저에 내장된 함수이다, API를 불러오고 그에 대한 정보를 내보내주는 함수이다.</p>
<ul>
<li><p>서버와 비동기 요청방식들중에 하나인데, 대표적인 비동기 요청방식중에 하나인 Ajax의 방식 중의 하나이다.</p>
</li>
<li><p>fetch를 사용하기 위해서 method를 이용해서 사용하는데, 대표적으로 4가지의 메소드가 있다.</p>
</li>
</ul>
<ol>
<li>Create</li>
</ol>
<ul>
<li>생성<ul>
<li>POST를 의미한다.</li>
<li>정보를 담아서 보내면 새로운 것을 생성할 수 있다.</li>
</ul>
</li>
</ul>
<ol start="2">
<li>Read</li>
</ol>
<ul>
<li>읽기</li>
<li>GET을 의미한다.<ul>
<li>데이터를 읽는것</li>
</ul>
</li>
</ul>
<ol start="3">
<li>Update</li>
</ol>
<ul>
<li>갱신</li>
<li>PUT을 의미한다.<ul>
<li>테이터를 수정 할 수 있다.</li>
</ul>
</li>
</ul>
<ol start="4">
<li>Delete</li>
</ol>
<ul>
<li>삭제</li>
<li>DELETE를 의미한다.<ul>
<li>데이터를 지울 수 있다.</li>
</ul>
</li>
</ul>
<h3 id="🧐-then-">🧐 &nbsp;.then ??</h3>
<p>👉 &nbsp; fetch를 사용하려고 하면 then이라는 키워드가 나온다. 그럼 이 then은 무엇일까??</p>
<p>✓ 함수 실행이 끝나면 그 다음 할 일을 정해주는 역할이다.
<br>
✓ fetch는 웹에서 &#39;이 서버로 요청 좀!!!&#39;의 의미를 가지고 있다. 다음에 then이 붙는다면 &#39;요청 끝나고 이거 해줘!!!&#39;의 의미를 가진다.</p>
<h3 id="📌-정리">📌 정리</h3>
<ul>
<li><p>API를 이용하여 백엔드 서버로부터 받아온 정보를 사용할 때 .then()함수를 이용한다.</p>
</li>
<li><p>API를 사용하여 백엔드 서버와 비동기 요청을 하는 방식 중에 하나.</p>
</li>
<li><p>비동기 방식으로 요청하기 때문에 API호출하는 과정이 끝나지 않더라도 다음 코드로 넘어가는 경우에 then을 사용한다.</p>
<br>

</li>
</ul>
<h3 id="👩🏻💻-내가-작성한-fetch-함수들이다">👩🏻‍💻 내가 작성한 fetch 함수들이다.</h3>
<p>✓ 메소드 &#39;PUT&#39;을 사용해서 데이터를 수정 할 수 있다. 또 수정한 데이터를 서버에 저장해서 새로고침 이후에도 수정되 데이터가 저장되어있다.
<br>
<img width="571" alt="스크린샷 2022-03-23 오후 5 14 34" src="https://user-images.githubusercontent.com/89238394/159654176-1bd62ba1-eefc-474f-96c9-ea7bd4437221.png"></p>
<br>

<p>✓ 메소드 &#39;DELETE&#39;를 사용해서 데이터를 삭제 할 수 있다.
<br></p>
<img width="546" alt="스크린샷 2022-03-23 오후 5 40 10" src="https://user-images.githubusercontent.com/89238394/159659456-13223771-46b4-412a-8ff9-0757117d9422.png">

<ul>
<li><p>처음에는 단순하게 DELETE만을 이용해서 구현하였다.</p>
<ul>
<li>그 결과 삭제를 한 직후에 view에는 삭제 된 상황이 바로 보이지 않고, 새로고침을 해야지 삭제가 된것이 보였다.</li>
<li>그래서 응답이 왔을 경우의 상황에 조건문을 추가했다.</li>
<li>조건문에 결과가 참일 경우 id값을 0으로 바꾸었다.</li>
<li>새로운 조건문에 그 id 값이 들어올경우 return 값을 null로 주었다.</li>
</ul>
<img width="562" alt="스크린샷 2022-03-23 오후 5 40 16" src="https://user-images.githubusercontent.com/89238394/159659185-1795ac76-4eb0-4ad7-b48e-4b9e57372b2f.png">

</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_03.]]></title>
            <link>https://velog.io/@j-jhoo/React03</link>
            <guid>https://velog.io/@j-jhoo/React03</guid>
            <pubDate>Mon, 21 Mar 2022 12:49:53 GMT</pubDate>
            <description><![CDATA[<h2 id="🌈--react-useeffect">🌈 &nbsp; React useEffect</h2>
<h3 id="🧐-useeffect-란">🧐 useEffect 란???</h3>
<p>✓ 어떤 상태 값이 변경 되었을때 동작하는 함수를 작성할 수 있다.</p>
<ul>
<li>react 컴포넌트가 렌더링 될 때마다 특정 작업을 실행 할 수 있도록 하는 Hook이다.</li>
<li>class형 컴포넌트에서 사용할 수 있었던 생명주기 메소드를 함수형 컴포넌트에서도 사용할 수 있게 되었다.</li>
</ul>
<h3 id="📌-useeffect-사용법">📌 useEffect 사용법</h3>
<ul>
<li>기본 형태<ul>
<li>useEffect(함수,배열)</li>
</ul>
</li>
</ul>
<h4 id="1-useeffect의-첫번째-매개변수로-함수를-넣는다">1. useEffect의 첫번째 매개변수로 함수를 넣는다.</h4>
<ul>
<li>함수가 호출된 타이밍은 렌더링 결과가 실제 DOM에 반영된 직후,</li>
<li>컴포넌트가 사라지기 직전에 호출된다.</li>
</ul>
<h4 id="2-useeffect의-두변째-매개변수로--배열을-넣는다">2. useEffect의 두변째 매개변수로 [ ]배열을 넣는다.</h4>
<ul>
<li>컴포넌트가 화면에 처음 렌더링 될 때 한 번만 실행하고 싶을 때는 빈 배열을 넣는다,<ul>
<li>이것을 의존성 배열이라고 부른다.</li>
</ul>
</li>
<li>만약 배열을 생략하면 리렌더링 될 때 마다 실행된다.</li>
</ul>
<h4 id="3-컴포넌트가-업데이트-될-때-특정-props-state값이-변경-될-때--안에-검사하고-싶은-값을-넣어준다">3. 컴포넌트가 업데이트 될 때 특정 props, state값이 변경 될 때 [ ]안에 검사하고 싶은 값을 넣어준다.</h4>
<ul>
<li>업데이트 될 때만 실행하는 것이 아닌, 마운트 될 때도 실행된다.</li>
<li>배열안에 특정 값을 넣게 되면 컴포넌트가 처음 마운트 될 때 지정한 값이 바뀔 때, 언마운트 될 때, 값이 바뀌기 직전에 모두 호출이 된다.</li>
<li>useEffect 안에서 사용하는 상태나 props가 있을 경우, useEffect의 배열에 넣어주는 규칙이다.<ul>
<li>만약 사용하는 값을 넣어주지 않는다면 useEffect안의 함수가 실행될 때 최신 상태의 props를 가리키지 않는다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[🛎 Study | 개념을 공부하는 스터디]]></title>
            <link>https://velog.io/@j-jhoo/Study-%EA%B0%9C%EB%85%90%EC%9D%84-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%8A%A4%ED%84%B0%EB%94%94</link>
            <guid>https://velog.io/@j-jhoo/Study-%EA%B0%9C%EB%85%90%EC%9D%84-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%8A%A4%ED%84%B0%EB%94%94</guid>
            <pubDate>Sun, 20 Mar 2022 02:25:15 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-학습-목표">📌 학습 목표</h2>
<ul>
<li><b>브라우저와 프로그래밍 언어(Javascript, React, TypeScript)의 개념, 원리를 공부하고 이해하기</b>.</li>
</ul>
<h2 id="📆-학습-기간">📆 학습 기간</h2>
<ul>
<li>기간: ~ing</li>
</ul>
<h2 id="📕-학습-방식">📕 학습 방식</h2>
<ul>
<li>개념 1개씩 공부하고 정리하기</li>
<li>블로그에 올리듯이 작성하기. (github를 나만의 노트라고 생각하고 작성하기)</li>
<li>정리한것을 바탕으로 블로그 작성하기</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_02.]]></title>
            <link>https://velog.io/@j-jhoo/React02</link>
            <guid>https://velog.io/@j-jhoo/React02</guid>
            <pubDate>Sun, 20 Mar 2022 02:23:02 GMT</pubDate>
            <description><![CDATA[<h1 id="02">02.</h1>
<h2 id="🌈-react에서-table태그-사용하기">🌈 React에서 table태그 사용하기</h2>
<h3 id="🧐-table이란">🧐 table이란?</h3>
<ul>
<li>HTML의 DOM중 하나로 행과 열로 이루어진 표를 나타내는 태그</li>
<li>하위 요소로 <br><b>thead<br> tbody<br> tr<br> td<br> th</b> 등이 있다.</li>
</ul>
<hr>
<h3 id="📌-jsx에서-table-사용하기">📌 JSX에서 table 사용하기.</h3>
<h4 id="✓-btbodyb-와-btheadb-를-반드시-사용해야-한다">✓ <b>tbody</b> 와 <b>thead</b> 를 반드시 사용해야 한다.</h4>
<ul>
<li>HTML에서의 table은 tbody를 생략하고 바로 tr과 td를 사용할 수 있지만, <br> ✏️ JSX에서는 반드시 <b>tbody를 선언해야 tr과 td를 사용 할 수 있다</b>.</li>
<li>tbody를 선언하지 않는 경우에는 오류가 발생한다.</li>
</ul>
<p>✓ 마찬가지로 <b>thead를 작성해야 th를 사용할 수 있다</b>.</p>
<h4 id="✅-tbody와-thead를-작성해야되는-이유">✅ tbody와 thead를 작성해야되는 이유</h4>
<ul>
<li>React가 리렌더링을 진행할 때 DOM tree가 예상과는 달리 진행될 수 있으므로 작성을 해야한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_01.]]></title>
            <link>https://velog.io/@j-jhoo/React01</link>
            <guid>https://velog.io/@j-jhoo/React01</guid>
            <pubDate>Sun, 20 Mar 2022 02:22:28 GMT</pubDate>
            <description><![CDATA[<h1 id="01">01.</h1>
<h1 id="🌈-react를-사용하는-이유">🌈 React를 사용하는 이유</h1>
<h3 id="1-spa">1. SPA</h3>
<h3 id="2-csr">2. CSR</h3>
<h3 id="3-가상-돔-virtual-dom">3. 가상 돔 (Virtual Dom)</h3>
<h3 id="4-선언형-간결성">4. 선언형 (간결성)</h3>
<h3 id="6-component-단위-작성">6. Component 단위 작성</h3>
<hr>
<h2 id="1-spa-1">1. SPA</h2>
<h4 id="싱클-페이지-어플리키에션">싱클 페이지 어플리키에션</h4>
<ul>
<li>페이지 이동시 서버에 AJAX로 요청하고 서버는 JSON만 전달해준다,<br> 👉 SPA 방식에서는 페이지 이동시 변경되는 부분만 JSON으로 받아온뒤, 브라우저의 자바스크립트에서 받은 JSON을 토대로 DOM에 변경된 부분만 렌더링 해주기 때문이다.</li>
<li>SPA는 html 렌더링을 서버가 하는게 아닌, 클라이어트가 받은 JSON을 토대로 하기 때문에 CSR 방식으로 렌더링 한다고 말한다.</li>
</ul>
<h4 id="✅-장점">✅ 장점</h4>
<ol>
<li>페이지의 필요한 부분만 업데이트한다.<br>👉 트래픽이 적고, 페이지 이동이 그만큼 빨라진다.</li>
<li>최초접속시 필요한 모든 정적 리소스들을 다운 받고 이미 방문한 페이지도 캐싱한다.</li>
<li>모듈화나 컴포넌트화를 통해 유지보수를 쉽게 만들고 개발 속도를 빠르게 만들어준다.</li>
</ol>
<hr>
<h2 id="2-csr-1">2. CSR</h2>
<ul>
<li>서버로부터 데이터를 받아서 클라이언트에서 렌더링하는 방식이다.</li>
<li>서버로부터 데이터를 받아서 바뀐 부분의 데이터가 있는 화면만 새롭게 랜더링함으로서 사용자 경험을 높여주면서 효율적으로 클라이언트 리소스를 사용하게 한다.</li>
<li>서버가 HTML CSS JS 파일을 렌더링하는 대신 데이터를 보내줄 경우, 안드로이드, IOS, 웹 모바일 등 다양한 플랫폼이 서버를 공유할 수 있게 되어 효율적인 서버를 운영할 수 있게 된다.</li>
</ul>
<hr>
<h2 id="3-가상-돔-virtual-dom-1">3. 가상 돔 (Virtual Dom)</h2>
<p>✓ 리액트의 가장 큰 특징 중 하나로, UI의 이상적인 또는 &#39;가상&#39;적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 실제 DOM과 동기화하는 프로그래밍 기념이다.</p>
<ul>
<li>컴포넌트가 리턴하는 값에 의해 만들어지고 실제 보이는 DOM과 비교해서 달라진 부분만 찾아 바꾸게 된다.</li>
<li>연산비용이 줄어들게 된다.</li>
<li>리액트에서 컴포넌트 단위의 개발이 가능하게 되었다.</li>
</ul>
<h4 id="📌-가상dom-이용-방식">📌 가상DOM 이용 방식</h4>
<ol>
<li>데이터가 변경되면 리액트는 가상 DOM에 우선 적용한다.</li>
<li>이전의 가상 DOM과 비교하여 변경된 부분을 체크하고 변경된 부분만 실제 DOM에 적용한다.</li>
</ol>
<h4 id="✅-장점-1">✅ 장점</h4>
<ul>
<li>리액트의 렌더링 방식은 DOM전체를 매번 리렌더링했던 이전 방식의 비해 빠르다.</li>
<li>애플맄이션의 규모가 클수록, 데이터의 변경이 많을수록 더 큰 힘을 발휘한다.</li>
</ul>
<hr>
<h2 id="4-선언형-간결성-1">4. 선언형 (간결성)</h2>
<p>✓ 코드를 예측 가능하고 디버그하기 쉽게 만들어준다.</p>
<ul>
<li>지역 변수 선언을 줄일 수 있다.</li>
<li>map, filter, reduce, sort 와 같은 함수를 사용해 결과를 바로 알 수 있는 간결하고 명확한 코드를 작성 가능하다.</li>
<li>UI를 구성할 때 선언형 스타일을 이용한다.</li>
</ul>
<h4 id="✅-장점-2">✅ 장점</h4>
<ul>
<li>선언형 스타일과 가상 DOM이 만나면 엄청난 효율성을 발휘한다.</li>
</ul>
<ol>
<li>데이터 변화에 따라 변화된 부분에 영향을 받는 부분의 UI만 자동적으로 변경되게 할 수 있다.</li>
<li>개발자의 실수와 신경 쓸 부분을 줄여줄 수 있다.</li>
<li>코드를 간결하고 직관적으로 만들어준다.</li>
</ol>
<hr>
<h2 id="6-component-단위-작성-1">6. Component 단위 작성</h2>
<p>✓ 컴포넌트는 UI를 구성하는 개별적인 뷰의 단위다.</p>
<ul>
<li>재사용이 가능하다.</li>
<li>생산성과 유지 보수를 용이하게 한다.</li>
<li>컴포넌트가 모여서 하나의 View뷰가 완성된다.</li>
</ul>
<br>
]]></description>
        </item>
        <item>
            <title><![CDATA[Js_01.]]></title>
            <link>https://velog.io/@j-jhoo/Js01</link>
            <guid>https://velog.io/@j-jhoo/Js01</guid>
            <pubDate>Sun, 20 Mar 2022 02:20:56 GMT</pubDate>
            <description><![CDATA[<h2 id="💻-객체지향-프로그래밍">💻 객체지향 프로그래밍</h2>
<ul>
<li>독립된 단위, &#39;vn 객체&#39;들의 모임
👉 객체란?
:: 메세지를 주고 받고 데이터를 처리할 수 있는 것</li>
</ul>
<p><b>📌 장점</b></p>
<ul>
<li>유연하고 변경이 쉽다.</li>
<li>개발과 보수에 용이하다.</li>
<li>클래스를 사용한다.</li>
<li>직관적인 코드분석이 가능하다.</li>
</ul>
<hr>
<h2 id="💻-함수형-프로그래밍">💻 함수형 프로그래밍</h2>
<ul>
<li>자료 처리를 함수의 계한으로 취급, 상태와 가변 데이터를 멀리하는 프로그래밍
:: 주어진 조건에서만 작업이 진행된다.</li>
</ul>
<p><b>📌 장점</b></p>
<ul>
<li>동일한 환경에서 작업하기 때문에 input과 output이 동일하다.</li>
<li>부수적인 요건에 의해서 변경될 오류가 적다.</li>
<li>선언형이다.</li>
<li>고계함수(비동기)를 사용한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML_01. ]]></title>
            <link>https://velog.io/@j-jhoo/HTML01</link>
            <guid>https://velog.io/@j-jhoo/HTML01</guid>
            <pubDate>Sun, 20 Mar 2022 02:19:44 GMT</pubDate>
            <description><![CDATA[<h1 id="01">01.</h1>
<h2 id="🌈-table-태그">🌈 table 태그</h2>
<p>✓ 행과 열로 이루어진 표를 나타낸다.</p>
<h3 id="📌-종류">📌 종류</h3>
<ol>
<li>caption</li>
<li>colgroup</li>
<li>col</li>
<li>table</li>
</ol>
<hr>
<h2 id="1-caption">1. caption</h2>
<p>✓ 표의 설명 또는 제목을 나타낸다.</p>
<ul>
<li>전역 특성만 표함한다.</li>
<li>부모 table 요소의 <b>첫 번째 자식</b>이어야 한다.</li>
<li>caption 요소를 가진 table 요소가 만약 figure태그 요소의 유일한 자식일 경우, <b>figcation</b>을 사용하여야한다.</li>
</ul>
<hr>
<h2 id="2-colgroup">2. colgroup</h2>
<p>✓ 표의 열을 묶는 그룹을 의미한다.</p>
<ul>
<li>전역 특성을 포함한다. <br></li>
</ul>
<h3 id="📌-특징">📌 특징</h3>
<ul>
<li>background-color 속성을 사용할 수 있다.</li>
<li>span 태그 👉 열의 수를 나타내는 양의 정수로 기본값은 1이다. <br>✅ col 요소가 존재하면 사용할 수 없다.</li>
</ul>
<hr>
<h2 id="3-col">3. col</h2>
<p>✓ 표의 열을 나타내며, 열에 속하는 칸에 공통된 의미를 부여 할 때 사용한다.</p>
<ul>
<li>colgroup 태그 안에서 찾을 수 있다.</li>
<li>전역 특성을 포함한다.</li>
<li>col이 차지할 열의 수를 나타내는 양의 정수.</li>
<li>기본값은 1이다.</li>
</ul>
<hr>
<h2 id="4-table">4. table</h2>
<p>✓ 행과 열로 이루어진 표를 나타낸다.</p>
<ul>
<li>선택적인 <b>caption</b> 요소</li>
<li>0개 이상의 <b>colgroup</b> 요소</li>
<li>선택적인 <b>thead</b> 요소</li>
<li>0개 이상의 <b>tbody</b> 요소</li>
<li>0개 이상의 <b>tr</b> 요소</li>
<li>선택적인 <b>tfoot</b> 요소</li>
</ul>
<p>✏️ 예제</p>
<pre><code>&lt;table&gt;
  &lt;tr&gt;
    &lt;td&gt;John&lt;/td&gt;
    &lt;td&gt;Doe&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Jane&lt;/td&gt;
    &lt;td&gt;Doe&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Browser_01.]]></title>
            <link>https://velog.io/@j-jhoo/01</link>
            <guid>https://velog.io/@j-jhoo/01</guid>
            <pubDate>Sun, 20 Mar 2022 02:17:18 GMT</pubDate>
            <description><![CDATA[<h1 id="🌐-저장소">🌐 저장소</h1>
<h2 id="🌈-브라우저-저장소web-storage">🌈 브라우저 저장소(Web Storage)</h2>
<ul>
<li>HTML5부터 제공하는 기능으로, 해당 도메인과 관련된 특정 데이터를 서버가 아니라 클라이언트 웹브라우저에 저장할 수 있도록 제공하는 기능</li>
<li>쿠키와 비슷한 기능, Web Storage의 개념은 키 /값 쌍으로 데이터를 저장하고 키를 기반으로 데이터를 조회하는 패턴이다.</li>
<li>쿠키와 마찬가지로 사이트의 도메인 단위로 접근이 제한된다.</li>
</ul>
<h4 id="📌-특징">📌 특징</h4>
<ol>
<li>서버 전송이 없다. 👉 네트워크 트래픽 비용을 줄일 수 있다. <br></li>
<li>단순 문자열을 넘어 객체정보를 저장할 수 있다. <br></li>
<li>용량의 제한이 없다. <br></li>
<li>영구 데이터 저장이 가능하다. (만료 기간이 없다. )</li>
</ol>
<h4 id="✅-필요한-이유">✅ 필요한 이유</h4>
<ol>
<li>4KB의 데이터 저장 제한 <br></li>
<li>HTTP Request에 암호화 되지 않은 상태로 사용하기 때문에 보안이 취약하다. <br></li>
<li>쿠키는 모든 HTTP Request에 포함되어 있어 웹 서비스 성능에 영향을 줄 수 있다.</li>
</ol>
<hr>
<h2 id="🔈-web-storage의-종류">🔈 Web Storage의 종류</h2>
<ol>
<li>LocalStorage</li>
<li>SessionStorage</li>
</ol>
<h3 id="localstorage">LocalStorage</h3>
<ul>
<li>브라우저를 닫았다가 다시 열어도 계속 유지된다. 저장한 데이터를 <b>지우지 않는 한 영구적으로 보관이 가능하다.</b><br>
👉 도메인마다 별도로 LocalStorage가 생성된다.<br>
👉 도메인만 같으면 전역으로 공유가 가능하다.<br></li>
</ul>
<h3 id="sessionstorage">SessionStorage</h3>
<ul>
<li>브라우저가 열려있는 한 페이지를 Reload해도 유지된다. 하지만 <b>브라우저를 닫으면 삭제된다.</b><br>
👉 WebStorage의 기본 보안처럼 도메인별로 별도로 생성된다. 같은 사이트의 같은 도메인이라도 브라우저가 다르면 서로 다른 영역이 된다. <b>브라우저 컨텍스트가 다르기 때문이다.</b></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[useEffect]]></title>
            <link>https://velog.io/@j-jhoo/useEffect-6q3qe9ru</link>
            <guid>https://velog.io/@j-jhoo/useEffect-6q3qe9ru</guid>
            <pubDate>Fri, 04 Feb 2022 14:01:25 GMT</pubDate>
            <description><![CDATA[<h1 id="useeffect--종속성">useEffect &amp; 종속성</h1>
<ul>
<li>setTimeout =&gt; builtin 메서드</li>
</ul>
<pre><code class="language-jsx">useEffect(() =&gt; {
setTimeout(() =&gt; {
console.log(&quot;Validity::::!!!&quot;);
setFormIsValid(
enteredEmail.includes(&quot;@&quot;) &amp;&amp; enteredPassword.trim().length &gt; 6
);
}, 500);</code></pre>
<ul>
<li>클린업 함수 (익명의 함수 리턴) return () =&gt; {}</li>
<li>useEffect 함수가 작동할 때마다, 작동하기 전에, 돌아가는 아주 첫 번째를 제외하고는 클린업 함수가 돌아간다.</li>
<li>클린업함수 작동 -&gt; 돔에서부터 특정한 컴포넌트가 작동할때마다, 컴포넌트가 다시 사용될 때마다</li>
<li>모든 새로운 사이드 이펙트 함수가 실행되고 컴포넌트가 제거되기 전에 실행된다.</li>
<li>:: 클린업 함수는 사이드 이펙트 함수가 실행되기 전에는 작동하지 않는다. 그다음 모든 사이드 이펙트 함수가 실행되기 전에 작동된다.</li>
</ul>
<pre><code class="language-jsx">return () =&gt; {
console.log(&quot;Cleanup::::!!!&quot;);
};
}, [enteredEmail, enteredPassword]);</code></pre>
<p>하지만 실행해보면</p>
<p><img src="https://images.velog.io/images/j-jhoo/post/cde0ae4d-9279-4e80-b33c-2e394aa33190/image.png" alt="">
cleanup은 뜨지 않는다 . =&gt; useEffect함수가 최초 실행되지 않았기 때문에 (첫번째 사이드 이펙트가 실행되기 전에 작동하지 않는다. )</p>
<p>그래서 한글자라도 입력하게 되면 ???!!</p>
<p><img src="https://images.velog.io/images/j-jhoo/post/b58666f7-d4a7-47b4-9c53-e4212a4af36e/image.png" alt=""></p>
<p>⇒ 이렇게 정상적으로 작동하게 된다.</p>
<pre><code class="language-jsx">useEffect(() =&gt; {
const identifier = setTimeout(() =&gt; {
console.log(&quot;Validity::::!!!&quot;);
setFormIsValid(
enteredEmail.includes(&quot;@&quot;) &amp;&amp; enteredPassword.trim().length &gt; 6
);
}, 500);</code></pre>
<ul>
<li>클린업 함수 (익명의 함수 리턴) return () =&gt; {}</li>
</ul>
<pre><code class="language-jsx">return () =&gt; {
console.log(&quot;Cleanup::::!!!&quot;);
clearTimeout(identifier);</code></pre>
<ul>
<li>클린업 함수가 돌아갈때마다 클린업 함수가 돌아가기 전에 설정된 setTimeout타이머를 클리어할 수 있다.</li>
<li>마지막 사이드 이펙트 함수가 실행되면 다음 사이드 이펙트 함수가 실행될때 타이머를 새로 정할 수 있다.</li>
</ul>
<p>};</p>
<p>}, [enteredEmail, enteredPassword]);</p>
<p><img src="https://images.velog.io/images/j-jhoo/post/4bd97045-7aa2-4da4-913f-025e6f3925cf/image.png" alt=""></p>
<p>setFormIsValid(</p>
<p>enteredEmail.includes(&quot;@&quot;) &amp;&amp; enteredPassword.trim().length &gt; 6</p>
<p>);</p>
<p>}, 500);</p>
<p>이 코드는 한번만 실행된다는 의미 (모든 키스트로크마다)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[useReducer]]></title>
            <link>https://velog.io/@j-jhoo/useReducer</link>
            <guid>https://velog.io/@j-jhoo/useReducer</guid>
            <pubDate>Thu, 03 Feb 2022 13:26:38 GMT</pubDate>
            <description><![CDATA[<h2 id="usereducer">useReducer</h2>
<ul>
<li>또 다른 빌트인 훅</li>
<li>상태 관리를 도와준다.</li>
<li>useState와 비슷하지만, 능력이 더 많고 더 복잡한 상태일 때 유용하다.</li>
</ul>
<p>   👉   복잡한 multiple 상태일 대 useState를 사용하고 관리할 때 에러를 일으킨다, 이건 안좋은 상황이거나 효율적이지 않거나 잠재적인 버그 코드일 수 있다. </p>
<p>🔥 이럴때!!! 대신 사용하는 것이 useReducer!! 이다. </p>
<p>🌀 useReducer 사용방법 </p>
<pre><code class="language-jsx">const [state, dispatchFn] = useReducer(reducerFn, initialState, initFn);</code></pre>
<p><img src="https://images.velog.io/images/j-jhoo/post/ac03d651-03e3-4ed0-a848-6f594defad69/image.png" alt=""></p>
<ul>
<li>useState와 같이 항상 2개의 값이 있는 배열을 반환한다.</li>
<li>useState처럼 배열 구조 분해를 통해 이 값들을 끄집어내서 서로 다른 상수 내에 저장할 수 있다.</li>
<li>반환 되는 두개의 값 중 하나는 최신 상태의 스냅숏이다.</li>
<li>state ⇒ useState처럼 상태 관리를 하는 매커니즘!
dispatchFn ⇒ 상태를 업데이트해주는 함수 반환 → useState와 비슷하지만 상태 업데이트 함수의 작동 방식에서는 차이가 있다. ✔️  새로운 상태 값을 설정하는 대신 하나의 액션을 디스패치 하게 된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[useEffect]]></title>
            <link>https://velog.io/@j-jhoo/useEffect</link>
            <guid>https://velog.io/@j-jhoo/useEffect</guid>
            <pubDate>Fri, 28 Jan 2022 01:35:53 GMT</pubDate>
            <description><![CDATA[<p>검증 추가 및 로직 재설정하기</p>
<p><img src="https://images.velog.io/images/j-jhoo/post/4361542f-1620-46be-99e7-f303354da515/image.png" alt=""></p>
<p>enteredAge앞에 + 를 붙임으로서 숫자인지 확실하게 확인할 수 있게 해준다.</p>
<p> [ useEffect 훅 사용하기 ]</p>
<p>유저가 인증된 상태라면 이 페이지를 리로드 하더라도 유지되어야 한다.  그러나 현재 상태에서 새로고침 시에 인증 상태가 사라지는 이유는</p>
<p>setIsLoggedIn(true);</p>
<ul>
<li>브라우저 스토리지의 이 위치에 정보를 저장,</li>
<li>브라우저에서 가장 보편적으로 사용하는 저장소는 쿠키와 로컬 스토리지</li>
</ul>
<p>:: 얘네는 리액트로부터 완전히 독립적임.</p>
<p>localStorage.setItem(&quot;isLoggedIn&quot;, &quot;1&quot;);</p>
<ul>
<li>localStorage. :: 전역 객체이며 브라우저에서 제공하는 것</li>
<li>(아이템에 적당한 식별자를 부여함. 단 &#39;문자열&#39;, 두번째 인수 또한 저장하는 정보에 대한 &#39;문자열&#39;) -&gt; 1은 로그인되었다는 시그널! 0은 그 반대를 뚯하는 시그널!</li>
<li>함수 안에 넣는 이유는 사용자가 버튼을 눌렀을 때만 실행되는 함수이기 때문</li>
</ul>
<p><img src="https://images.velog.io/images/j-jhoo/post/353d31d6-fbfd-4787-8539-dac6750d029a/image.png" alt=""></p>
<ul>
<li>앱이 재실행될 경우 이 APP 컴포넌트 함수가 재실행된다.</li>
</ul>
<p>const storedUserLoggedInInformation = localStorage.getItem(&quot;isLoggedIn&quot;);</p>
<p> 로컬스토리지에서 getItem을 호출하고 isLoggedIn을 검색하면 저장된 아이템들이 반환됨.</p>
<pre><code class="language-jsx">if (storedUserLoggedInInformation === &quot;1&quot;) {
setIsLoggedIn(&quot;true&quot;);

// 1이 맞다면 setIsLoggedIn을 호출해서 이를 true로 설정한다. -&gt; 유저가 로그인으로 설정된다.
}</code></pre>
<ul>
<li>loginHandler함수가 트리거되지 않더라도 유저가 로그인으로 설정된다.</li>
</ul>
<p><img src="https://images.velog.io/images/j-jhoo/post/5fc55fba-327b-473c-abee-4076b278d00f/image.png" alt=""></p>
<ul>
<li>원래는 useState가 실행된 이후에 실행되는게 맞지만 가장큰 단점은 무한 루프를 만들 수 있다는 것</li>
</ul>
<p><img src="https://images.velog.io/images/j-jhoo/post/87b9f404-6ee7-49ae-b9ae-62d32ae7e898/image.png" alt=""></p>
<ul>
<li>정보가 저장됐는지 확인 한 후 저장이 되었다면 1로 설정, 그리고 상태 설정 함수를 호출할 때마다 App컴포넌트 함수가 재실행된다. === 무한 반복…. :: 이때 useEffect 사용!!!</li>
</ul>
<p><img src="https://images.velog.io/images/j-jhoo/post/c934476a-8fd5-4326-a3c1-f0d2fefce766/image.png" alt=""></p>
<p>:: 그러나 컴포넌트 평가 후에 매번 실행되는 건 아니다. -&gt; 디펜던시들이 바뀌어야만 실행 가능</p>
<ul>
<li>데이터 가져오기는 사이드 이펙트 (UI와 직접적인 관계가 없다. )</li>
</ul>
<p><img src="https://images.velog.io/images/j-jhoo/post/97f5ed04-2e0e-4c0b-86f5-9071b1587b43/image.png" alt=""></p>
<ul>
<li>removeItem을 사용해서 로그아웃 버튼을 눌렀을 때 로컬스토리지의 isLoggedIn키가 지워지게 된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[ref]]></title>
            <link>https://velog.io/@j-jhoo/ref</link>
            <guid>https://velog.io/@j-jhoo/ref</guid>
            <pubDate>Fri, 28 Jan 2022 01:27:37 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>🚨  오늘은 ref에 대해서 공부하기,,,,</p>
</blockquote>
<h2 id="ref-가-하는-일은-">ref 가 하는 일은 ??</h2>
<p>=  ref는 상당히 강력한 아이다. </p>
<p>👉  기본 상태에서의 ref는 다른 DOM요소로 엑세스해서 작업할 수 있게 해주는 역할이다. </p>
<h3 id="🌀-ref를-사용하지-않을-경우">🌀 ref를 사용하지 않을 경우,</h3>
<p>예시) </p>
<pre><code class="language-jsx">import React, { useState } from &quot;react&quot;;

import Card from &quot;../UI/Card&quot;;
import Button from &quot;../UI/Button&quot;;
import ErrorModal from &quot;../UI/ErrorModal&quot;;
import Wrapper from &quot;../Helpers/Wrapper&quot;;
import classes from &quot;./AddUser.module.css&quot;;

const AddUser = (props) =&gt; {
  const [enteredUsername, setEnteredUsername] = useState(&quot;&quot;);
  const [enteredAge, setEnteredAge] = useState(&quot;&quot;);
  const [error, setError] = useState();

  const addUserHandler = (event) =&gt; {
    event.preventDefault();
    if (enteredUsername.trim().length === 0 || enteredAge.trim().length === 0) {
      setError({
        title: &quot;Invalid input&quot;,
        message: &quot;Please enter a valid name and age (non-empty values).&quot;,
      });
      return;
    }
    if (+enteredAge &lt; 1) {
      setError({
        title: &quot;Invalid age&quot;,
        message: &quot;Please enter a valid age (&gt; 0).&quot;,
      });
      return;
    }
    props.onAddUser(enteredUsername, enteredAge);
    setEnteredUsername(&quot;&quot;);
    setEnteredAge(&quot;&quot;);
  };

  const usernameChangeHandler = (event) =&gt; {
    setEnteredUsername(event.target.value);
  };

  const ageChangeHandler = (event) =&gt; {
    setEnteredAge(event.target.value);
  };

  const errorHandler = () =&gt; {
    setError(null);
  };

  return (
    &lt;Wrapper&gt;
      {error &amp;&amp; (
        &lt;ErrorModal
          title={error.title}
          message={error.message}
          onConfirm={errorHandler}
        /&gt;
      )}
      &lt;Card className={classes.input}&gt;
        &lt;form onSubmit={addUserHandler}&gt;
          &lt;label htmlFor=&quot;username&quot;&gt;Username&lt;/label&gt;
          &lt;input
            id=&quot;username&quot;
            type=&quot;text&quot;
            value={enteredUsername}
            onChange={usernameChangeHandler}
          /&gt;
          &lt;label htmlFor=&quot;age&quot;&gt;Age (Years)&lt;/label&gt;
          &lt;input
            id=&quot;age&quot;
            type=&quot;number&quot;
            value={enteredAge}
            onChange={ageChangeHandler}
          /&gt;
          &lt;Button type=&quot;submit&quot;&gt;Add User&lt;/Button&gt;
        &lt;/form&gt;
      &lt;/Card&gt;
    &lt;/Wrapper&gt;
  );
};

export default AddUser;</code></pre>
<pre><code class="language-jsx">                    &lt;input
            id=&quot;age&quot;
            type=&quot;number&quot;
            value={enteredAge}
            onChange={ageChangeHandler}
          /&gt;</code></pre>
<ul>
<li>여기 보이는 코드들 중에서 위와 같이 input 태그에서 유저가 입력하는 바를 추적해서 관리한다.</li>
</ul>
<pre><code class="language-jsx">const AddUser = (props) =&gt; </code></pre>
<ul>
<li>state에서 상태가 존재하며 매 키 입력에 따라 상태가 업데이트 된다.</li>
</ul>
<pre><code class="language-jsx">{
  const [enteredUsername, setEnteredUsername] = useState(&quot;&quot;);
  const [enteredAge, setEnteredAge] = useState(&quot;&quot;);
  const [error, setError] = useState();</code></pre>
<ul>
<li>유저의 키 입력을 따라 값을 업데이트하고 이를 상태에 저장하는 것이다!.</li>
</ul>
<pre><code class="language-jsx">                &lt;input
            id=&quot;age&quot;
            type=&quot;number&quot;
            value={enteredAge}
            onChange={ageChangeHandler}
          /&gt;</code></pre>
<ul>
<li>그리고 그 저장한 상태를 input 으로 피드백하고 나중에 그 상태를 활용해서</li>
</ul>
<pre><code class="language-jsx">props.onAddUser(enteredUsername, enteredAge);
    setEnteredUsername(&quot;&quot;);
    setEnteredAge(&quot;&quot;);
  };</code></pre>
<ul>
<li>input을 리셋하는 한편 데이터가 필요한 곳으로 보내준다.</li>
</ul>
<p>👉   ref를 사용하지 않을 경우에 form만 제출하기만 하면 되는데 키 입력마다 상태를 업데이트하는 건 좀 ... 불편스 할 수있다... (과하다..) 이럴 때 필요한것은 ?!!! ref!!!</p>
<h3 id="🌀-ref를-사용할-경우">🌀 ref를 사용할 경우</h3>
<p>ref를 사용하면 연결을 만들 수 있다. </p>
<p>👉  렌더링 될 HTML요소와 자바스크립트 코드간의 연결이 가능!!</p>
<p>👉  useRef가 반환하는 값이 중요!! 하다. 나중에 활용하게 되면 연결하려는 요소에 작업할 수 있게 해준다. </p>
<p><strong>사용방법</strong> </p>
<p>먼저, ref를 사용하려면 </p>
<pre><code class="language-jsx">import React, { useState, useRef } from &quot;react&quot;;</code></pre>
<ul>
<li>ref를 불러와야 한다.</li>
</ul>
<pre><code class="language-jsx">const AddUser = (props) =&gt; {
  const nameInputRef = useRef();
  const ageInputRef = useRef();

  const [enteredUsername, setEnteredUsername] = useState(&quot;&quot;);
  const [enteredAge, setEnteredAge] = useState(&quot;&quot;);
  const [error, setError] = useState();
</code></pre>
<ul>
<li>코드 안에, 함수형 컴포넌트 안에서 불러와야 한다.</li>
<li>오직 함수형에서만 활용이 가능하다.</li>
<li>ref를 연결하려는 HTML코드로 가서 특별한 prop을 추가한다. ⇒ ref prop</li>
</ul>
<pre><code class="language-jsx">                    &lt;input
            id=&quot;age&quot;
            type=&quot;number&quot;
            value={enteredAge}
            onChange={ageChangeHandler}
                        ref={ageInputRef}
          /&gt;</code></pre>
<ul>
<li>key prop과 마찬가지로 내장 prop이며 어느 HTML요소에도 추가할 수 있다. ⇒ 어떤 HTML요소든 하나의 레퍼런스와 연결 할 수 있기 때문에</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Class]]></title>
            <link>https://velog.io/@j-jhoo/Class</link>
            <guid>https://velog.io/@j-jhoo/Class</guid>
            <pubDate>Sun, 09 Jan 2022 12:25:46 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>🚨 오늘은 class에 대하여 공부해보자,,,,</p>
</blockquote>
<ul>
<li><p>지금까지 비슷한 형태의 객체를 생성하기 위해서 생성자 함수를 사용했었는데 class를 사용해서도 만들 수 있다. </p>
</li>
<li><p>Class는 ES6에 추가된 스펙입니다. </p>
</li>
</ul>
<pre><code class="language-jsx">// 생성자 함수
const User = function (name, age) {
  this.name = name;
  this.age = age;
  this.showName = function () {
    console.log(this.name);
  };
};</code></pre>
<h2 id="🌀-생성자-함수">🌀 생성자 함수</h2>
<p>: 객체를 생성하는 함수를 의미한다. </p>
<ul>
<li><p>생성자 함수 특징</p>
<ul>
<li><strong>대문자</strong>로 시작하게 된다.</li>
<li><strong>new</strong>라는 키워드를 사용해서 객체를 생성할수있다</li>
</ul>
</li>
<li><p>prototype &amp; <strong>proto</strong></p>
<ul>
<li>실제 객채를 만들 때 생성자의 prototype이 <strong>참조</strong>된 모습이다. 생성자의 프로토타입을 참조하기 때문에 <code>_proto_</code>와 prototype은 같다.</li>
</ul>
</li>
<li><p>간략하게 정리</p>
<ul>
<li><p>prototype은 생성자 함수에 정의한 모든 객체가 공유할 원형</p>
</li>
<li><p><code>_proto_</code>는 생성자 함수를 new로 호출할 때, 정의해두었던 prototype을 참조한 객체</p>
</li>
<li><p>prototype은 생성자 함수에 사용자가 직접 넣는 거고, <code>_proto_</code>는 new를 호출할 때 prototype을 참조하여 자동으로 만들어진다.</p>
</li>
<li><p>생성자에는 prototype, 생성자로부터 만들어진 객체에는 <code>_proto_</code></p>
</li>
<li><p>생성자에는 prototype, 생성자로부터 만들어진 객체에는 <code>_proto_</code></p>
<p>👉   prototype이 개발자입장에서 객체에 변화를 주기위해 access해야 될 것이고, <code>_proto_</code>는 생성자로부터 만들어진 객체가 prototype을 참조한 객체이다.</p>
</li>
</ul>
</li>
</ul>
<h3 id="🌀-prototype-_proto_와-constructor의-관계">🌀 Prototype, <code>_proto_</code>와 constructor의 관계</h3>
<ul>
<li>prototype과 constructor는 부모자식 관계라고 생각하면 된다.</li>
</ul>
<p>class를 사용하여 만든 함수 </p>
<pre><code class="language-jsx">class User2 {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  showName() {
    console.log(this.name);
  }
}

const tom = new User2(&quot;hoo&quot;, 26);</code></pre>
<p>🤔  차이점은 ???!!!</p>
<ul>
<li><p>new를 통해서 호출했을 때 내부에서 정의 된 내용으로 객체를 생성하는 것은 동일합니다.</p>
</li>
<li><p>class라는 키워드를 사용하고 내부에 constructor가 있습니다.</p>
<p>  🙄  그럼 constructor가 무엇이냐?!!</p>
<ul>
<li>constructor은 객체를 만들어주는 생성자 메서드입니다. (new를 통해 호출하면 자동으로 실행된다.)</li>
</ul>
</li>
<li><p>👇  객체를 초기화 하는 값은 이곳에서 정해지는데, 인수로 (name, age)를 넘겨 받을 수 있습니다.</p>
<p>  <img src="https://images.velog.io/images/j-jhoo/post/b442a855-8e06-488f-bf9b-2a1aee750369/%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%202022-01-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%201.37.49.png" alt=""></p>
<p>  이렇게 되면 name과 age가 만들어진다. 그리고 이 showName처럼 class내에 정의된 메서드는 user2에 프로토타입에 저장된다. </p>
</li>
</ul>
<p>🤔  그럼 생성자 함수를 class함수와 동일하게 동작하도록 만들려면 어떻게 해야할까??</p>
<pre><code class="language-jsx">// 생성자 함수
const User = function (name, age) {
  this.name = name;
  this.age = age;
  // this.showName = function () {
  //   console.log(this.name);
  // };
};

User.prototype.showName = function () {
  console.log(this.name);
}</code></pre>
<ul>
<li>위에 코드에서 //부분을 지우고 밑에 코드를 새로 추가 했다.</li>
</ul>
<p><img src="https://images.velog.io/images/j-jhoo/post/3961229d-0725-482a-a744-5dbe95bdc945/%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%202022-01-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.27.10.png" alt=""></p>
<ul>
<li>그럼 이렇게 똑같은 결과를 가질 수 있게 된다.</li>
</ul>
<p>🤔  그렇다면 class를 사용하는 이유는 무엇일까???</p>
<pre><code class="language-jsx">const User = function (name, age) {
  this.name = name;
  this.age = age;
  // this.showName = function () {
  //   console.log(this.name);
  // };
};

User.prototype.showName = function () {
  console.log(this.name);
};

const tom = User(&quot;Tom&quot;, 30);</code></pre>
<ul>
<li><p>new를 제거한 후에 실행하면 tom 과 undefined가 뜨게 된다.</p>
</li>
<li><p>class에 똑같이 new를 제거해 보았다. 👇</p>
</li>
</ul>
<pre><code class="language-jsx">class User2 {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  showName() {
    console.log(this.name);
  }
}

const hoo = User2(&quot;Hoo&quot;, 26);</code></pre>
<p>그럼 error가 뜨게 된다. </p>
<p><img src="https://images.velog.io/images/j-jhoo/post/8e89254e-e29c-4e2a-b4ce-8df3374c82a9/%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%202022-01-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.23.51.png" alt=""></p>
<ul>
<li>TypeError ⇒ class는 new 없이 실행되지 않는다.</li>
</ul>
<p><img src="https://images.velog.io/images/j-jhoo/post/dde9c683-b406-4e82-82c1-f5e95714c7c9/%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%202022-01-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.17.04.png" alt=""></p>
<ul>
<li>tom과 hoo를 비교해보았다.<ul>
<li>프로토타입 내부에 있는 constructor를 확인해보면 User2의 constructor는 class라고 명시되어 있다.</li>
<li>constructor가 class라는 것을 알 수 있고, 이 경우에 new없이 호출하면 error가 발생하는 것을 확인 해보았다.</li>
</ul>
</li>
</ul>
<h3 id="🌀-for-in문으로-확인해보기">🌀 for in문으로 확인해보기</h3>
<p><img src="https://images.velog.io/images/j-jhoo/post/353d70e1-8398-4b3e-be48-275c292893ac/%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%202022-01-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.34.21.png" alt=""></p>
<ul>
<li>tom을 for in문을 사용하여 순회해보면 name, age, 프로토타입의 showName까지 다 확인할 수 있다.</li>
<li>반면에 hoo를 for in문으로 확인해보면 name, age만 나오는 것을 확인 할 수 있다.</li>
</ul>
<p>🤔  왜????</p>
<p>⇒ for in문은 프로토타입에 포함된 프로퍼티들은 다 보여주고 객체가 가진 프로퍼티만 판별하기 위해서 hs on 프로퍼티를 사용해야 한다. 그런데 class의 메서드는 for in문에서 제외된다. </p>
<ul>
<li>막간 차이점<ul>
<li>클래스에 정의된 메서드는 열거할 수 없습니다(non-enumerable)</li>
<li><code>for..in</code>으로 객체를 순회할 때, 메서드는 순회 대상에서 제외됩니다.</li>
<li>클래스는 항상 <code>엄격 모드</code>로 실행됩니다(<code>use strict</code>). 클래스 생성자 안 코드 전체엔 자동으로 엄격 모드가 적용됩니다.</li>
</ul>
</li>
</ul>
<h3 id="🌀-상속">🌀 상속</h3>
<p><strong>class의 경우</strong>의 상속은  <strong>extends 키워드</strong>를 사용한다. </p>
<ul>
<li>Car라는 class</li>
</ul>
<pre><code class="language-jsx">class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  drive() {
    console.log(&quot;Drive...&quot;);
  }
  stop() {
    console.log(&quot;STOP!!!&quot;);
  }
}</code></pre>
<ul>
<li>Car를 상속해서 만든 Audi</li>
</ul>
<pre><code class="language-jsx">class Audi extends Car {
  park() {
    console.log(&quot;PARK::&quot;);
  }
}

const A6 = new Audi(&quot;white&quot;);</code></pre>
<ul>
<li>extends키워드를 사용하여 만든다.</li>
</ul>
<p><img src="https://images.velog.io/images/j-jhoo/post/b84085b6-fb54-4f7e-acef-d4044dd63276/%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%202022-01-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.54.42.png" alt=""></p>
<ul>
<li>A6를 검색해보면 Car class에서 선언한 color와 wheels가 안에 들어있다.</li>
<li>prototype에는 park가 들어있다.  class내부에서 선언한 이 메서드는 prototype밑으로 들어간다.</li>
<li>A6.drive()를 찾아보면 A6 객체에서 찾고 없어서 proto에가서 찾고 없으니깐 또 proto에가서 찾아봐서 drive메서드를 사용할 수 있다.</li>
</ul>
<h3 id="🌀--class-메소드-오버라이딩-method-overriding">🌀  class 메소드 오버라이딩 (method overriding)</h3>
<p>🤔  만약 Audi안에 Car에서 정의한 메서드와 동일한 메서드가 존재하면 어떻게 될까유??</p>
<pre><code class="language-jsx">class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  drive() {
    console.log(&quot;Drive...&quot;);
  }
  stop() {
    console.log(&quot;STOP!!!&quot;);
  }
}

class Audi extends Car {
  park() {
    console.log(&quot;PARK::&quot;);
  }
  stop() {
    console.log(&quot;OFF!!&quot;);
  }
}

const A6 = new Audi(&quot;white&quot;);</code></pre>
<ul>
<li>class Audi에 stop을 추가해보았다.</li>
</ul>
<p><img src="https://images.velog.io/images/j-jhoo/post/f14d10ff-a458-4ac1-ba91-3e249561bc2e/%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%202022-01-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.00.16.png" alt=""></p>
<p>→  off가 나오게 된다.</p>
<ul>
<li>이렇게 동일한 이름의 메소드를 정의할 경우 덮어 쓰게 된다.</li>
</ul>
<p>🤔  만약 부모의 메서드를 그대로 사용하고 싶으면서 확장하고 싶을 때는 어떻게 해야될까??</p>
<p>🙈  그때 사용하는 것이 바로 !!! super()!!!!</p>
<pre><code class="language-jsx">class Audi extends Car {
  park() {
    console.log(&quot;PARK::&quot;);
  }
  stop() {
    super.stop();
    console.log(&quot;OFF!!&quot;);
  }
}

const A6 = new Audi(&quot;white&quot;);</code></pre>
<ul>
<li>stop안에 super를 추가했다.</li>
</ul>
<p><img src="https://images.velog.io/images/j-jhoo/post/94edef6f-0dd0-4265-af47-143400d348cd/%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%202022-01-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.02.39.png" alt=""></p>
<p>→ 이렇게 stop이 나오고 off가 나온다. </p>
<ul>
<li>super.메소드명으로  부모 class에 정의된 메소드를 사용할 수 있게 된다.</li>
<li>이 방식을 오버라이딩이라고 한다.</li>
</ul>
<h3 id="🌀-생성자-오버라이딩">🌀 생성자 오버라이딩</h3>
<p>class Audi에 constructor를 사용해서 네비게이션을 추가해보겠습니다. </p>
<pre><code class="language-jsx">class Audi extends Car {
  constructor() {
    this.navigation = 1;
  }
  park() {
    console.log(&quot;PARK::&quot;);
  }
}

const A6 = new Audi(&quot;white&quot;);</code></pre>
<p>이렇게 저장하면 ERROR가 난다. ㅋㅋㅋㅋ</p>
<ul>
<li>constructor에서 this를 사용하기 전에 super constructor 즉, <strong>부모 생성자를 반드시 먼저 호출해야한다.</strong></li>
<li>class에 constructor 은 {} 빈 객체로 만들어주고 this로 이 객체를 가르쳐줘야한다.</li>
<li>반면 extends를 사용하서 만든 자식 class는 빈객체를 만들고 this에 할당해주는 이 과정을 건너 뛸 수 있다.</li>
<li>그래서 항상 <strong>super키워드</strong>로 부모 class의 constructor키워드를 실행해줘야함.</li>
</ul>
<pre><code class="language-jsx">class Audi extends Car {
  super();
  constructor() {
    this.navigation = 1;
  }
  park() {
    console.log(&quot;PARK::&quot;);
  }
}

const A6 = new Audi(&quot;white&quot;);</code></pre>
<p>다시 A6를 콘솔창에 확인해보면 </p>
<p><img src="https://images.velog.io/images/j-jhoo/post/ba872307-27ae-4b35-b42e-21aa5d7a211b/%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%202022-01-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.09.55.png" alt=""></p>
<p>→ navigation 은 1로 잘 뜨지만, color은 undefined가 뜬다. 왜???!!!!</p>
<ul>
<li>자식 class의 constructor에 부모와 동일한 인수를 받는 작업을 해주어야 한다.</li>
</ul>
<pre><code class="language-jsx">class Audi extends Car {
  constructor(color) {
    super(color);
    this.navigation = 1;
  }
  park() {
    console.log(&quot;PARK::&quot;);
  }
}
const A6 = new Audi(&quot;white&quot;);</code></pre>
<p>constructor에 color을 받고 super에 color을 넘겨줘야 한다. </p>
<p><img src="https://images.velog.io/images/j-jhoo/post/a1c79b90-62c0-4bd2-bae6-9dec89a1b66a/%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%202022-01-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.13.28.png" alt=""></p>
<p>→ 그럼 잘 들어가진다.!!!! </p>
<p>정리!! </p>
<pre><code class="language-jsx">class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  drive() {
    console.log(&quot;Drive...&quot;);
  }
  stop() {
    console.log(&quot;STOP!!!&quot;);
  }
}

class Audi extends Car {
  park() {
    console.log(&quot;PARK::&quot;);
  }
}
const A6 = new Audi(&quot;white&quot;);</code></pre>
<ul>
<li>처음에 이 코드였다. 자식 class의 Audi에는 constuctor가 없다. 이럴때 자바스크립트는???!!!</li>
</ul>
<pre><code class="language-jsx">class Car {
  constructor(color) {
    this.color = color;
    this.wheels = 4;
  }
  drive() {
    console.log(&quot;Drive...&quot;);
  }
  stop() {
    console.log(&quot;STOP!!!&quot;);
  }
}

class Audi extends Car {
    constructor(...args){
        super(...args);
}
  park() {
    console.log(&quot;PARK::&quot;);
  }
}

const A6 = new Audi(&quot;white&quot;);</code></pre>
<ul>
<li>constructor가 없으면 constructor가 있는척 행동한다. 그렇기 때문에 자식 생성자는 무조건 부모 생성자를 호출해야한다.</li>
<li>constructor만 사용하면 처리되지 않기 때문에 항상 super를 사용해서 호출해줘야 한다.</li>
<li>그 후에 this.property로 할당해줘야 한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTML] Semantic Markup]]></title>
            <link>https://velog.io/@j-jhoo/HTML-Semantic-Markup</link>
            <guid>https://velog.io/@j-jhoo/HTML-Semantic-Markup</guid>
            <pubDate>Fri, 07 Jan 2022 00:44:00 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>*<em>🚨 시맨틱 마크업에 대해서,,, *</em></p>
</blockquote>
<ul>
<li>Semantic : 의미론적인 </li>
<li>Markup : HTML태그로 문서를 작성하는 것
👉 즉 Semantic Markup 이란 <strong>의미를 잘 전달하도록 문서를 작성하는 것</strong>을 말합니다.</li>
</ul>
<h2 id="작성-방법">작성 방법</h2>
<p>*<em>태그를 각각에 용도에 맞게 사용해야 합니다. *</em></p>
<ul>
<li>헤더 : header 사용</li>
<li>네비게이션 : nav</li>
<li>푸터 : footer 사용</li>
<li>메인 부분 : main 사용</li>
<li>컨텐츠를 나눌때 가장 큰 카테코리 : section 사용</li>
<li>최상위 제목 : h1 사용</li>
<li>순서가 없는 목록 : ul과 li 사용</li>
<li>순서가 있는 목록 : ol과 li 사용</li>
<li>표를 나눌 때 : tr과 td 사용</li>
</ul>
<h2 id="특징">특징</h2>
<ul>
<li>검색엔진이 시맨틱 태그를 중요한 키워드로 간주해서 <strong>검색엔진 최적화에 유리</strong>합니다. </li>
<li><strong>웹 접근성</strong> 측면에서 시각장애가 있는ㄴ 사용자로 하여금 그 의미를 훨씬 잘 파악할 수 있습니다. </li>
<li>div, span으로만 구성되어 있는 것보다 코드를 볼 때 <strong>가독성</strong>이 더 좋습니다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL - Styled-components]]]></title>
            <link>https://velog.io/@j-jhoo/TIL-Styled-components</link>
            <guid>https://velog.io/@j-jhoo/TIL-Styled-components</guid>
            <pubDate>Tue, 04 Jan 2022 08:08:23 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>🚨 Styled-components에 대해서 알아보자,,,,</p>
</blockquote>
<blockquote>
<h2 id="🌀-styled-components를-사용하는-이유">🌀 Styled-components를 사용하는 이유</h2>
</blockquote>
<ul>
<li>자동 중요 Css : styled-components는 페이지에서 렌더링되는 구성 요소를 추적하고 완전히 자동으로 해당 스타일만 삽입합니다. 코드 분할과 함께 이는 사용자가 필요한 최소한의 코드를 로드함을 의미합니다.</li>
<li>class 이름 버그 없음 : styled-components는 스타일에 대한 고유한 클래스 이름을 생성합니다. 중복, 중복 또는 철자 오류에 대해 걱정할 필요가 없습니다.</li>
<li>Css의 더 쉬운 삭제 : 클래스 이름이 코드베이스의 어딘가에서 사용되는지 여부를 알기 어려울 수 있습니다. styled-components는 스타일의 모든 비트가 특정 구성 요소에 연결되어 있기 때문에 이를 분명히 합니다. 구성 요소가 사용되지 않고(도구가 감지할 수 있음) 삭제되면 해당 구성 요소의 모든 스타일도 함께 삭제됩니다.</li>
<li>단순 동적 스타일링 : 수십 개의 클래스를 수동으로 관리할 필요 없이 props 또는 전역 테마를 기반으로 구성 요소의 스타일을 적용하는 것이 간단하고 직관적입니다.</li>
<li>손쉬운 유지 관리 : 구성 요소에 영향을 주는 스타일을 찾기 위해 다른 파일을 검색할 필요가 없으므로 코드베이스가 아무리 크더라도 유지 관리는 케이크 조각입니다.</li>
<li>자동 공급업체 접두사 : Css를 현재 표준으로 작성하고 나머지는 styled-components가 처리하도록 합니다.</li>
</ul>
<blockquote>
<h2 id="🌀-styled-components-설치-방법">🌀 styled-components 설치 방법</h2>
<p> $ with npm
npm install --save styled-components
$ with yarn
yarn add styled-components</p>
</blockquote>
<blockquote>
<p>설치한 후에는 
{
  &quot;resolutions&quot;: {
    &quot;styled-components&quot;: &quot;^5&quot;
  }
}
package.json 파일에 적용되어 있는 것을 확인 할 수 있다. </p>
</blockquote>
<blockquote>
<h2 id="🌀-작성-방법">🌀 작성 방법</h2>
</blockquote>
<pre><code>render(
  &lt;Wrapper&gt;
    &lt;Title&gt;
      Hello World!
    &lt;/Title&gt;
  &lt;/Wrapper&gt;
);
const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;
const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]_React native 초기세팅]]></title>
            <link>https://velog.io/@j-jhoo/TILReact-native-%EC%B4%88%EA%B8%B0%EC%84%B8%ED%8C%85</link>
            <guid>https://velog.io/@j-jhoo/TILReact-native-%EC%B4%88%EA%B8%B0%EC%84%B8%ED%8C%85</guid>
            <pubDate>Wed, 22 Dec 2021 14:46:48 GMT</pubDate>
            <description><![CDATA[<h1 id="📱react-native-시작🧐">📱react-native 시작!!🧐</h1>
<hr>
<blockquote>
<p>React - native</p>
</blockquote>
<ul>
<li>Homebrew 설치</li>
<li>Nodejs 설치</li>
<li>Watchman 설치</li>
<li>React Native CLI 설치</li>
<li>Xcode 설치 
Cocoapods 설치</li>
<li>JDK 설치</li>
<li>Android studio 설치
Android studio 설정
Android studio SDK 설치
Android studio 환경 변수 설정</li>
<li>react-native 프로젝트 생성 및 확인
IOS에서 확인
Android에서 확인 </li>
</ul>
<hr>
<h3 id="✏️-험난했던-react-native-초기세팅-과정">✏️ 험난했던 react-native 초기세팅 과정,,,</h3>
<h4 id="👉-homebrew는-맥에서-필요한-패키지를-관리하는-패키지다">👉 Homebrew는 맥에서 필요한 패키지를 관리하는 패키지!!다.</h4>
<h4 id="👉-nodejs-react-native가-javascript이므로-javascript-런타임인-nodejs를-설치해야한다">👉 Nodejs (react-native가 javascript이므로) javascript 런타임인 nodejs를 설치해야한다.</h4>
<pre><code class="language-javascript">brew install node
node -–version</code></pre>
<h4 id="👉-watchman은-소스코드의-추가-변경이-발생하면-다시-빌드하기-위해-사용">👉 Watchman은 소스코드의 추가, 변경이 발생하면 다시 빌드하기 위해 사용!!.</h4>
<pre><code class="language-javascript">brew install watchman
watchman –version</code></pre>
<h4 id="👉-react-native-cli-설치">👉 React Native CLI 설치</h4>
<pre><code class="language-javascript">npm install -g react-native-cli
npx react-native --version</code></pre>
<h4 id="👉-대망의-xcode-ios-앱을-개발하기-위해서는-xcode가-필요하다-appstore에서-xcode를-다운-받을-수-있다-설치-완료-후에는">👉 대망의 Xcode!! ios 앱을 개발하기 위해서는 Xcode가 필요하다. AppStore에서 Xcode를 다운 받을 수 있다. 설치 완료 후에는</h4>
<p><img src="https://images.velog.io/images/j-jhoo/post/974050d9-3f11-4c61-84ef-d9f2d9b50f10/image.png" alt="">
 ✅ <strong>Command Line Tools가 설정</strong>되어 있는지 확인한다. </p>
<h4 id="👉-cocoapods는-ios-개발에-사용되는-의존성-관리자로-react-native개발에-필요하다">👉 Cocoapods는 ios 개발에 사용되는 의존성 관리자로 react-native개발에 필요하다!.</h4>
<pre><code class="language-javascript">sudo npm install cocoapods
pod --version</code></pre>
<h4 id="여기까지가-ios개발에-필요한-설치를-끝냈다-이제안드로이드로-가즈아-🤖">여기까지가 ios개발에 필요한 설치를 끝냈다!!! 이제...안드로이드로..... 가즈아!! 🤖</h4>
<h4 id="👉-jdk-설치-homebrew-명령어로-jdk를-설치">👉 JDK 설치 (homebrew 명령어로 JDK를 설치!!)</h4>
<pre><code>brew tap AdoptOpenJDK/openjdk
brew cask install adoptopenjdk8
java -version</code></pre><p>✅ <strong>Java컴파일러도 같이 설치되어 있는지 확인</strong></p>
<h4 id="👉--안드로이드-스튜디오-httpsdeveloperandroidcomstudio-설치">👉  [안드로이드 스튜디오] (<a href="https://developer.android.com/studio">https://developer.android.com/studio</a>) 설치!!</h4>
<h4 id="👉-안드로이드-스튜디오-sdk-설정">👉 안드로이드 스튜디오 SDK 설정</h4>
<h4 id="👉-안드로이드-스튜디오-환경-변수-설정">👉 안드로이드 스튜디오 환경 변수 설정</h4>
<p><img src="https://images.velog.io/images/j-jhoo/post/a2118de6-df47-4057-8e45-3a402f235714/%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-12-20%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.45.37.png" alt=""></p>
<h4 id="환경변수-설정-후">환경변수 설정 후</h4>
<pre><code>adb</code></pre><h4 id="를-입력할-경우-아래와-같은-결과를-확인할-수-있다">를 입력할 경우 아래와 같은 결과를 확인할 수 있다.</h4>
<pre><code>Android Debug Bridge version 1.0.41
Version 29.0.1-5644136
Installed as /자신의 안드로이드SDK 위치/platform-tools/adb</code></pre><p><a href="https://dev-yakuza.posstree.com/ko/react-native/install-on-mac/">블로그 참조 링크</a></p>
<h3 id="🤞-그럼-초기셋팅은-완료">🤞 그럼 초기셋팅은 완료!!</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[[project] Holla - 회고록]]></title>
            <link>https://velog.io/@j-jhoo/2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@j-jhoo/2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Mon, 29 Nov 2021 02:17:26 GMT</pubDate>
            <description><![CDATA[<h1 id="🌈-홀라-팀프로젝트">🌈 홀라 팀프로젝트!!</h1>
<p><img src="https://images.velog.io/images/j-jhoo/post/9bb087b4-91ab-4955-a2db-b3d6f612efb7/image.png" alt=""></p>
<ul>
<li>윌라 clone coding</li>
<li>기간 : 2021.11.15 ~ 2021.11.26(총 12일간)</li>
<li>레퍼런스 페이지 : <a href="https://www.welaaa.com/audio">윌라페이지바로가기</a>
👉 책 구독, 책에 대한 평점을 줄 수 있는 사이트 </li>
<li>팀명 : HOLLA(홀라)</li>
<li>팀원구성 : [FE]: 설혜린, 이수경, 장세영, 정지후 &nbsp;&nbsp; [BE] : 김봉철, 유병문</li>
<li>영상링크 : <a href="https://drive.google.com/file/d/1bLdBu8gRKcWSNu3r1vyPwUhUobkm4Qt-/view">홀라 시연 영상</a></li>
</ul>
<hr>
<h2 id="🌀-프로젝트-진행방식">🌀 프로젝트 진행방식</h2>
<p>👉 이번 프로젝트 또한 scrum방식으로 진행하였다. 매일 아침에 스탠드업 미팅을 하며 어제한일, 오늘 할일, 현재 블로커가 뭔지에 대하여 서로의 상황과 진행사항을 공유하였고 아이디어 회의도 하였다. Trello를 이용하여 미팅시간이 아니어도 서로의 진행사항을 공유하고 소통하였다. 또 git을 이용하여 서로 맡은 부분에 대해서 branch를 나누고 프로젝트를 진행하였다. 
<a href="https://trello.com/b/uYUclNXp/26-holla">Holla Trello</a>
<img src="https://images.velog.io/images/j-jhoo/post/2d18d74e-3a40-49f5-a8ac-99c6aeaa2b8f/image.png" alt=""></p>
<hr>
<h2 id="🌀-적용-기술">🌀 적용 기술</h2>
<p>👉 React 
👉 Sass
👉 HTML/JSX
👉 Git ( branch를 맡은 부분으로 나누어서 관리하였다. )
👉 Git ( rebase를 사용하여 commit을 관리하였다. )</p>
<hr>
<h2 id="🌀-main-page-내가-맡은-부분">🌀 Main page (내가 맡은 부분)</h2>
<p>👉 윌라의 메인페이지는 다른 메인에 비해서 simple하다고 생각하였다. 대신 react component분리가 아직 미숙한 나는 이번 메인 슬라이드에서 component를 확실하게 분리해서 슬라이드를 만들때 이용할 수 있다라는 생각을 했고 이것에 초첨을 잡았다. 또 처음 기능 구현을 해보는 슬라이드가 생각보다 많이 어려웠고.... 로직을 생각하는 부분에 있어서와, 내가 생각해낸 로직을 어떻게 함수화 해야될지에 많은 시간이 소요되었다. </p>
<p><strong>[Banner Slide]</strong></p>
<p><img src="https://images.velog.io/images/j-jhoo/post/c07d9c92-358f-4f70-85b9-4e34fe0a9d11/%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-11-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.20.10.png" alt=""><img src="https://images.velog.io/images/j-jhoo/post/4e8a3d0c-3c11-4c35-8ca0-84fb0e83c66e/%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-11-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.21.05.png" alt=""></p>
<p><img src="https://images.velog.io/images/j-jhoo/post/d5190dea-ed1e-457e-b693-cf78edb7968b/BeforeLogin.gif" alt="">
<img src="https://images.velog.io/images/j-jhoo/post/78515820-ae04-4e23-aa24-394e3d5fbe07/Nov-28-2021%2020-00-34.gif" alt=""></p>
<p>✏️ 처음 로직을 생각할때 든 생각은 하나였다. 왼쪽 버튼을 눌렀을때 이미지가 오른쪽으로 이동, 오른쪽 버튼을 눌렀을 경우에는 이미지들이 왼쪽으로 이동하게 하는 것이었다. 이 로직을 생각하고 나서 멘토님들한테 현재 내 경우에는 로직을 구현을 했지만, 이것을 함수화 하기까지 너무 어렵다라고 찡찡되었지만... 이걸 생각했으면 한번 더 생각해보라고 할 수 있다라고 말씀해주셨고...고민....고민....계소옥 고민... 했다.... 그결과?! 슬라이드 구현!!! 🔥근데 문제는 윌라 홈페이지 베너 슬라이드의 경우 가운데 이미지가 고정적인 width값을 가지고 양 옆의 이전, 다음 이미니가 살짝씩 보여지는데 이것을 구현하는데 시간이 꽤나 많이 소용되었다. ㅠㅠㅠ 그래서 생각해낸 결과는???!!!😱 변수에 360px이라는 width값을 정해주고 transform: translateX 속성을 이용해서 양 옆에 이미지를 붙이는데 구현 성공하였다!!! </p>
<hr>
<p><strong>[Slick Slide]</strong></p>
<p><img src="https://images.velog.io/images/j-jhoo/post/0883542b-6697-485a-9a4a-6448430d5887/%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-11-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%207.55.59.png" alt=""></p>
<p><img src="https://images.velog.io/images/j-jhoo/post/a2762169-ec4f-47ec-86ec-ced90385791b/Nov-28-2021%2020-05-10.gif" alt="">
✏️ React.slick을 사용해서 슬라이드를 구현하였다. 저번 프로젝트에서 사용하지 않았던 slick이라는 라이브러리를 사용해보는 좋은 경험을 해 보았다. Slick공식문서를 보면서 사용해보았는데 처음엔 쉽다라고 생각했지만... ui를 변경하거나 css속성을 변경하려면 많이 까다롭다는 것을 알게 되었다. 그렇지만 만족!!! 기본 틀을 짜놓은 상태에서 백엔드에서 API를 이용하여 서버와 통신을 해서 데이터를 받아왔다. 
🔥 한꺼번에 데이터를 받아와서 필요한 슬라이드나 필요한곳마다 데이터를 분리해서 불러오는것이 처음에 조금 어려웠지만 이번 프로젝트를 통해서 확실히 알게되었다. </p>
<hr>
<p><strong>[Detail Page]</strong>
✏️ Main page에 있는 추천 슬라이드를 클릭할 경우 디테일 페이지로 이동할 수있도록 동적 Routing을 이용하여 구현하였다. 동적 routing의 개념에 약간 헷갈렸던 부분이 있어서 처음에 적용할 때 조금 고민을 많이 했었지만 routing 개념에 대해서 확실히 알게 되었다!!</p>
<hr>
<h2 id="🔆🔆🔆-2차-프로젝트를-마무리하며-👇">🔆🔆🔆 2차 프로젝트를 마무리하며 👇</h2>
<p>이번 프로젝트를 진행하면서 많을 것들을 느끼게 되었다. 
✅ 백엔드 분들과 <strong>많은 소통</strong>을 하였고, 백엔드에서 데이터가 어떤 방법으로 보내주는지, 프론트에서는 그 데이터를 어떻게 사용하는지에 대해서 확실히 알게 되는 시간이었다. 
✅ 스탠드업 미팅을 매일 매일 진행하면서 프론트끼리도 많은 소통을 하였고, 백엔드와도 많은 소통을 했다. 또 부분부분 문제들이 생길 경우에는 그 자리에서 바로 바로 소통하면서 하나하나 차근히 해결해나가는 부분들에 있어서 <strong>이번 프로젝트에서는 많은 소통을 했다!!</strong>라고 생각든다. 
✅ 1차 프로젝트 때 구현하지 않았던 slide기능 구현을 하면서 어려웠지만 재밌었다(내가 생각한 로직을 구현한다는 것이 굉장히 재밌게 다가왔다,, <strong>이것이 개발자의 매력인가?!!</strong>). 또 slick 라이브러리를 사용해보면서 라이브러리에 대한 장.단점을 확실하게 알게 되었다. 
✅ 개념이 많이 어렵게 느껴졌던 <strong>동적 routing</strong>을 구현하면서 <strong>확실하게 개념을 이해하고 적용</strong>시켜서 좋았다. </p>
<hr>
<h2 id="😱🔥-아쉬웠던-점">😱🔥 아쉬웠던 점</h2>
<p>👉 이번 프로젝트를 하면서 많이 아쉬웠던 점은... 슬라이드 기능 구현에 있어서 생각보다 너무 많은 시간이 소요되어서 다른 기능 구현에 있어서 조금 더 욕심내지 않았던 부분이 많이 아쉬웠다. ㅠㅠ <strong>내 스르로 조금 더 자신감을 가지고 하고 싶은 것에 있어서 욕심도 내서 목표치를 올려봐야겠다라는 생각을 했다!</strong>
👉 프로젝트를 진행하면 여러번 백엔드와 통신하는데 오류가 있었다ㅠㅠ 분명히 많은 소통을 했지만, 문제는 나 또한 <strong>&#39;백엔드에 대해서 어느정도의 사전 지식이 있어야된다&#39;</strong> 라는 생각이 많이 들었다. 그래서 백엔드에 많은 관심을 가지게 되었다.
👉 이번 프로젝트에서 가장 아쉬웠던 점은!!! 기획방향성이다. 처음 잡았던 기획은 중간에 틀려고 하니까 너무 복잡해지고, 힘든 점들이 많구나라는 생각을 했다. 그래서 처음 기획이 얼마나 중요한지에 대해서 느끼게 되었다. </p>
<hr>
<h2 id="👩👩👧👧👩👩👦👦-홀라팀">👩‍👩‍👧‍👧👩‍👩‍👦‍👦 홀라팀!!</h2>
<p>*<em>😆 정말 재밌고, 너무 소통도 잘 되었던 팀 HOLLA!! 프론트, 백엔드 할 것 없이 너무 많은 소통을 했고, 힘든 기간에 그 누구도 짜증한번 내지 않고 챙겨주고 항상 웃어주고 대화도 많이 한 우리팀이 너무 자랑스럽다. 서로 힘든 얘기들, 좋은 얘기들 모두 공유하면서 진짜 가족 같았던 우리 HOLLA... 심지어 멘토님도 너무너무 많은 도움을 주셨던 이번 프로젝트.... 정말 나중에 성공해서 다시 프로젝트 한번 더해여ㅠㅠ ❤️
*</em></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL_ Git 명령어]]]></title>
            <link>https://velog.io/@j-jhoo/TIL-Git-%EB%AA%85%EB%A0%B9%EC%96%B4</link>
            <guid>https://velog.io/@j-jhoo/TIL-Git-%EB%AA%85%EB%A0%B9%EC%96%B4</guid>
            <pubDate>Sun, 28 Nov 2021 11:37:33 GMT</pubDate>
            <description><![CDATA[<h2 id="🌀-git-명령어-정리">🌀 Git 명령어 정리</h2>
<hr>
<p>$ git clone (remote repository url)</p>
<ul>
<li>터미널 내에서 git clone (내 repository 주소)을 통해 remote repository안에 있는 파일을 내 local repository로 가져오는 것.</li>
</ul>
<hr>
<p>$ git status</p>
<ul>
<li>git status를 입력하면 현재 작업중인 프로젝트의 staging area, untracked file의 목록을 주고 add, restore할 수 있는 명령어를 보여준다.</li>
</ul>
<hr>
<p>$ git restore (파일명)</p>
<ul>
<li>commit 되지 않은 local repository내에 있는 파일의 변경사항을 취소할 수 있다.</li>
</ul>
<hr>
<p>$ git add . (파일명)</p>
<ul>
<li>staging area에 변경사항이 있는 파일을 staged 되도록 추가하는 명령</li>
</ul>
<hr>
<p>$ git commit -m (파일명)
staging area에 있는 파일을 내 local repository로 옮기는 명령어</p>
<hr>
<p>$ git reset (파일명)</p>
<ul>
<li>commit된 파일의 commit을 취소하는 명령어</li>
</ul>
<hr>
<p>$ git log
해당 repository의 commit history를 보여주는 명령어</p>
<hr>
<p>$ git (short name) (branch name)</p>
<ul>
<li>페어의 작업 내용을 내 local repository로 가져오는 명령어</li>
<li>변경사항은 자동 병합</li>
</ul>
<hr>
<p>$ git push (파일명)</p>
<ul>
<li>내 local repository에 commit된 파일을 내 remote repository로 옮겨주는 명령어</li>
</ul>
<hr>
<p>$ git init</p>
<ul>
<li><p>해당 디렉토리를 local repository로 만들고 .git 이라는 하위 디렉토리를 만든다.</p>
</li>
<li><p>새로운 remote repository의 기준이 될 디렉토리
remote repository는 github에서 만들 수 있다.</p>
</li>
</ul>
<hr>
<p>$ git remote add (remote name) (remote url)</p>
<ul>
<li><p>새로운 remote repository를 추가하는 명령어</p>
</li>
<li><p>init 명령어를 통해 local repository를 설정하고 remote 명령어를 통해 remote repository와 연결해줄 수 있다.</p>
</li>
<li><p>협업하는 사람의 remote repository에서 pull해오거나
push할 때도 사용
remote name은 재량에 따라 변경</p>
</li>
</ul>
<hr>
<p>$ git remote -v</p>
<ul>
<li>현재 적용된 remote repository의 단축이름과 url을 보여주는 명령어</li>
</ul>
<hr>
<p>$ git branch -d <branchname></p>
<ul>
<li>branch 삭제하는 명령어</li>
</ul>
<hr>
<p>$ git commit --amend -m &quot;컷밋 메세지&quot;</p>
<ul>
<li>마지막 커밋에 커밋 수정, 추가 하였을 때 커밋 메세지 수정하능 방법
$ git commit --amend --no-edit</li>
<li>커밋 메세지를 변경하고 싶지 않을 때 사용</li>
</ul>
<hr>
<p>$ git stash </p>
<ul>
<li>커밋을 임시저장하는 명령어 
$ git stash list </li>
<li>stash 목록 확인 
$ git stash apply</li>
<li>가장 최근의 stash를 가져와서 적용한다. 
$ git stash apply [stash 이름]</li>
<li>해당 stash를 가져와서 작업할 수 있다. 
$ git stash apply --index</li>
<li>staged상태까지 복원된다. =&gt; 원래 작업하던 파일의 상태로 돌아올 수 있다. </li>
</ul>
<hr>
<p>$ git reset --hard [메세지 이름]</p>
<ul>
<li>마지막 커밋 메세지 삭제 (무조건 삭제)</li>
<li>개인 브랜치에서 사용할 것 
$ git reset --mixed </li>
<li>이력을 돌릴 수 있음 </li>
</ul>
<hr>
<p>$ git revert [커밋 아디]</p>
<ul>
<li>특정 커밋을 되돌리는 경우 사용 </li>
</ul>
<hr>
<p>$ git cherry-pick [커밋 아디]</p>
<ul>
<li>다른 브랜치에 적용된 커밋을 내 브랜치에 적용하고 싶을 때 사용
$ git cherry-pick [커밋 아디 커밋 아디]</li>
<li>커밋 여러개를 한꺼번에 내 브랜치에 적용할 수 있다. 
$ git cherry-pick [커밋 아디..커밋아디]</li>
<li>첫번째 커밋 과 두번째 커밋 사이의 모든 커밋을 가져올 수 있다. </li>
</ul>
<hr>
<p>fork한 프로젝트 내에서 git remote -v 명령어를 치면, fork 한 본인의 저장소만 등록되어 있다.</p>
<p>git remote add upstream &quot;original 저장소 주소&quot; 명령어로 original 저장소의 주소를 등록해준다.(upstream은 원하는 이름으로 변경해도 된다)</p>
<p>git fetch upstream 명령어를 통해 original 저장소의 코드를 가져온다.</p>
<p>가져온 코드를 내 로컬 저장소와 merge 시켜주기 위하여 아래의 명령어를 입력한다.
git merge upstream/master</p>
<p>그 후 내 github에도 올리려면 git push origin master 명령어를 입력시켜주면 된다.</p>
]]></description>
        </item>
    </channel>
</rss>