<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>park_kyo_su.log</title>
        <link>https://velog.io/</link>
        <description>이사중 ! https://dpark-log.tistory.com/14</description>
        <lastBuildDate>Sun, 22 Jun 2025 08:28:47 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. park_kyo_su.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/park_kyo_su" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[React Query의 queryKey, 어떻게 잘 써야 할까?]]></title>
            <link>https://velog.io/@park_kyo_su/React-Query%EC%9D%98-queryKey-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9E%98-%EC%8D%A8%EC%95%BC-%ED%95%A0%EA%B9%8C</link>
            <guid>https://velog.io/@park_kyo_su/React-Query%EC%9D%98-queryKey-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9E%98-%EC%8D%A8%EC%95%BC-%ED%95%A0%EA%B9%8C</guid>
            <pubDate>Sun, 22 Jun 2025 08:28:47 GMT</pubDate>
            <description><![CDATA[<p>React Query는 서버 상태를 쉽게 관리할 수 있도록 도와주는 라이브러리입니다.<br>API 요청 결과를 캐싱하고, 자동으로 동기화도 해주니까 정말 편리하죠.</p>
<p>하지만 이 모든 기능의 중심에는 <code>queryKey</code>가 있다는 사실, 알고 계셨나요?<br>이번 글에서는 <code>queryKey</code>가 왜 중요한지, 그리고 실무에서 어떻게 효과적으로 관리하면 좋을지 이야기해보려고 해요.</p>
<hr>
<h2 id="querykey가-중요한-이유">queryKey가 중요한 이유</h2>
<p>React Query는 내부적으로 <code>queryKey</code>를 기준으로 데이터를 구분해요.  </p>
<ul>
<li>키가 같으면 같은 데이터를 보고,</li>
<li>키가 다르면 완전히 새로운 데이터로 인식합니다.</li>
</ul>
<p>즉, queryKey는 <strong>캐싱, 무효화, refetch</strong>의 기준이 됩니다.<br>그래서 신중하게 설계하는 게 정말 중요해요.</p>
<hr>
<h2 id="어떤-querykey가-좋은-key일까">어떤 queryKey가 좋은 key일까?</h2>
<h3 id="1-명확하고-고유하게">1. 명확하고 고유하게</h3>
<p>어떤 데이터를 가져오는지 한눈에 알 수 있어야 해요.</p>
<pre><code class="language-ts">[&#39;todos&#39;, userId]
[&#39;users&#39;, userId]</code></pre>
<p>키만 봐도 &quot;아, 이건 userId로 특정한 todos나 users 데이터를 가져오는구나&quot;라고 알 수 있죠.</p>
<hr>
<h3 id="2-객체의-순서를-항상-고정하기">2. 객체의 순서를 항상 고정하기</h3>
<p>React Query는 내부적으로 <code>JSON.stringify</code>를 이용해서 키를 비교하는데요,<br>객체 안의 속성 순서가 다르면 <strong>다른 키</strong>로 인식돼요.</p>
<pre><code class="language-ts">[&#39;posts&#39;, { authorId: 5, page: 1 }] // ✅ OK
[&#39;posts&#39;, { page: 1, authorId: 5 }] // ❌ 완전히 다른 키로 처리됨</code></pre>
<p>따라서 queryKey에 객체를 넣을 때는 속성 순서를 <strong>일관되게</strong> 유지해야 합니다.</p>
<hr>
<h3 id="3-계층-구조는-배열로-표현하기">3. 계층 구조는 배열로 표현하기</h3>
<p>복잡한 데이터는 배열로 표현하는 게 좋아요.<br>예를 들어, 유저의 게시글을 가져오는 경우에는 다음처럼요:</p>
<pre><code class="language-ts">[&#39;users&#39;, userId, &#39;posts&#39;]</code></pre>
<p>중첩된 관계를 명확하게 보여줄 수 있어서 나중에 invalidate나 refetch할 때도 유용합니다.</p>
<hr>
<h2 id="querykey-팩토리-함수로-관리하기">queryKey 팩토리 함수로 관리하기</h2>
<p>쿼리가 많아지면 키를 실수하기도 쉽고, 일관성도 깨질 수 있어요.<br>그래서 저는 보통 queryKey를 <strong>함수로 만들어서</strong> 관리합니다.</p>
<pre><code class="language-ts">// queryKeys.ts
export const queryKeys = {
  all: [&#39;todos&#39;],
  lists: () =&gt; [...queryKeys.all, &#39;list&#39;],
  list: (filters) =&gt; [...queryKeys.lists(), { filters }],
  details: () =&gt; [...queryKeys.all, &#39;detail&#39;],
  detail: (id) =&gt; [...queryKeys.details(), id],
};</code></pre>
<p>이런 식으로 팩토리 함수를 만들어두면,</p>
<ul>
<li>오타를 줄일 수 있고</li>
<li>자동완성도 되고</li>
<li>invalidate할 때도 간편해요</li>
</ul>
<hr>
<h2 id="invalidatequeries는-정확하게-써주기">invalidateQueries는 정확하게 써주기</h2>
<p>예를 들어 어떤 필터로 리스트를 가져오고 있었다면, 해당 필터에 맞는 리스트만 invalidate하는 게 좋겠죠?</p>
<pre><code class="language-ts">queryClient.invalidateQueries(queryKeys.list({ filter: &#39;active&#39; }));</code></pre>
<p>괜히 <code>[&#39;todos&#39;]</code>처럼 뭉뚱그려 invalidate하면 캐시가 다 날아가버릴 수 있어요.<br><strong>불필요한 리패치 방지</strong>를 위해서라도 정확한 queryKey를 사용하는 게 중요합니다.</p>
<hr>
<h2 id="조건부-쿼리에는-null과-enabled를-같이-쓰자">조건부 쿼리에는 null과 enabled를 같이 쓰자</h2>
<p><code>userId</code>가 있을 때만 유저 정보를 가져오고 싶다면? 아래처럼 처리할 수 있어요.</p>
<pre><code class="language-ts">const queryKey = userId ? [&#39;user&#39;, userId] : null;

useQuery({
  queryKey,
  queryFn: fetchUser,
  enabled: !!queryKey,
});</code></pre>
<p>이렇게 하면 <code>userId</code>가 없을 땐 쿼리를 아예 실행하지 않아서,<br>불필요한 요청이나 <code>[&#39;user&#39;, undefined]</code> 같은 애매한 캐시 키도 방지할 수 있습니다.</p>
<hr>
<h2 id="정리">정리</h2>
<p>queryKey 잘 쓰는 법, 요약하면 이렇게 정리할 수 있어요 👇</p>
<ul>
<li>명확하고 구체적인 key를 만든다</li>
<li>객체를 쓸 땐 속성 순서를 항상 고정한다</li>
<li>계층 구조는 배열로 표현한다</li>
<li>반복되는 key는 팩토리 함수로 관리한다</li>
<li>조건부 쿼리는 null과 enabled를 활용한다</li>
</ul>
<hr>
<h2 id="참고-링크">참고 링크</h2>
<ul>
<li>원문: <a href="https://tkdodo.eu/blog/effective-react-query-keys">Effective React Query Keys by TkDodo</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Project - 2 - Clone - KREAM]]></title>
            <link>https://velog.io/@park_kyo_su/Project-2-Clone-KREAM</link>
            <guid>https://velog.io/@park_kyo_su/Project-2-Clone-KREAM</guid>
            <pubDate>Sun, 01 Aug 2021 09:20:11 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>부트캠프 2차 팀프로젝트로 팀원 6명이 한 팀으로 구성되어 신발 경매 사이트인 KREAM를 클론 코딩 하였다. 이번 2차 프로젝트는 팀원들이 각자 구현해보고 싶은 기능이 명확하여 이에 중점을 두고 진행을 하였다.</p>
</blockquote>
<h3 id="kream-웹페이지-클론-프로젝트-회고">KREAM 웹페이지 클론 프로젝트 회고</h3>
<p>이번 2차 프로젝트에서는 감사하게도 PM역할을 맡게 되어 팀원들과의 적극적인 소통을 리드하였다. 중간에 blocker로는 백과의 대화시 서로 이해가 어려운 점이였는데, 서로 이해할려고 노력을 하다보니 2주차부터는 원할하게 소통이 되었다.</p>
<h4 id="kream-웹페이지-선정이유"><a href="https://kream.co.kr">KREAM</a> 웹페이지 선정이유</h4>
<p><img src="https://images.velog.io/images/park_kyo_su/post/fdcec154-fae8-483c-b725-e0fcac3c03b1/Aug-01-2021%2016-46-04.gif" alt=""></p>
<ul>
<li>모던한 디자인</li>
<li>2차 프로젝트로서의 적합한 기능<ul>
<li>판매&amp;구매 입찰 시스템</li>
<li>필터링 &amp; 소트</li>
<li>페이지 네이션</li>
<li>회원가입 및 로그인/로그아웃</li>
</ul>
</li>
</ul>
<h4 id="웹페이지-ideation">웹페이지 Ideation</h4>
<ul>
<li>기존 경매 시스템을 활용할 수 있도록 포스터를 경매하는 사이트로 전환</li>
<li><strong>GREAM+</strong>으로 네이밍 / <em>&#39;그림&#39;단어에서 영감, 실제 영어 단어 <strong>&#39;몽환적으로 빛나는..&#39;</strong></em></li>
</ul>
<blockquote>
<h4 id="작업기간">작업기간</h4>
<p>2021.7.5 - 2021.7.16</p>
</blockquote>
<h4 id="기술스택">기술스택</h4>
<p>Front-End : React, Styled Component, Fuctional Component
Back-End : Python, Django web framework, PyJWT, MySQL, s3transfer
Common : KAKAO social login, AWS(EC2, RDS, S3), RESTful API</p>
<h4 id="project-tool">Project Tool</h4>
<ul>
<li>Trello</li>
<li>Notion</li>
<li>POSTMAN</li>
</ul>
<blockquote>
<h4 id="주요-구현-사항-_-내가-맡은-구현사항--🎨">주요 구현 사항 _ <del>내가 맡은 구현사항 = 🎨</del></h4>
<p><strong>Shop 레이아웃🎨
Shop 필터링(중복 필터링)🎨
Shop Sort (가격, 판매순)🎨
Shop Pagination</strong>🎨
Detail 체결 거래 그래프
Detail 카러셀
Detail 최근 거래가
Login/Logout 인증/인가
Login/Logout 소셜 로그인(카카오)
입찰페이지 주문</p>
</blockquote>
<h3 id="project-flow">Project Flow</h3>
<p><img src="https://images.velog.io/images/park_kyo_su/post/fa81de2f-908c-4918-ac09-f37457b2e886/image.png" alt=""></p>
<h4 id="1주차">1주차</h4>
<p>1주차에는 <code>trello</code>를 사용하여 구현할 기능들에 대해 카트를 세분화 하고 역할을 분담하였다. 1차 프로젝트 때와는 달리 팀원별로 각자 구현하고 싶은 기능을 선택하였고 추가 기능구현보다 제대로 하나를 구현하는 것에 집중하였다. </p>
<p><img src="https://images.velog.io/images/park_kyo_su/post/c3f82c97-29c1-434e-8269-30852da2007d/image.png" alt=""></p>
<h4 id="2주차">2주차</h4>
<p>2주차 부터는 1주차에 짜여진 틀을 바탕으로 front/Back간의 연결에 집중을 하였다. 서로 주고받는 데이터의 종류와 양이 많아졌다 보니 서로의 대화가 중요했었다. 이를 위해 별도의<code>notion</code>페이지를 생성하여 각각 담당 파트 front/back간의 자료구조에 대해 조율하였다.
<img src="https://images.velog.io/images/park_kyo_su/post/cae2543a-70a1-42ed-8d57-a7a81bc3d80c/image.png" alt="">
또한 <code>POSTMAN</code>을 적극 활용하여 미리 백앤들와 데이터 구조를 맞춰 서버를 통신해 볼때의 오류를 최소화하였다.</p>
<h3 id="output👍">OUTPUT👍</h3>
<blockquote>
<p><a href="https://github.com/Junghoon-P/KREAM-Clone-Project">front-end repository</a>
<a href="https://github.com/wecode-bootcamp-korea/22-2nd-GREAM-backend">back-end repository</a>
<a href="https://youtu.be/Mvr7map6Y2M">전체 기능 구현 영상 -Youtube</a></p>
</blockquote>
<h3 id="detail">Detail</h3>
<p><img src="https://images.velog.io/images/park_kyo_su/post/57c57868-b876-4faa-94a3-47bf9af54ed7/Aug-01-2021%2017-58-45.gif" alt=""></p>
<h4 id="1-중복-필터링-pagination">1. 중복 필터링, Pagination</h4>
<blockquote>
<p><strong>1주차 중복 필터링</strong></p>
</blockquote>
<ul>
<li>중복 선택을 위한 데이터 컨트롤</li>
<li>Mock data 연동 및 백앤드 통신 test</li>
</ul>
<blockquote>
<p><strong>2주차 Pagination</strong></p>
</blockquote>
<ul>
<li>들어오는 data의 양에 따라 자동으로 페이지 넘버 증가 및 감소</li>
<li>1페이지가 아닌 페이지에서 필터링 선택시 필터링된 카드 수가 1페이지 양을 넘지 않으면 자동으로 1페이지로<ul>
<li>초기에 3페이지에서 필터링 선택시 자료수가 1페이지를 넘지 않아 1페지에 자료가 있는데, 사용자는 3페이지에 남는 문제 발생(페이지 버튼도 1페이지만 나와서 1페이지로 이동도 불가능</li>
<li>solution / 필터링 체크박스 클릭시 1페이지로 이동하는 함수 추가<blockquote>
<blockquote>
<p><strong>tmi</strong>
중복필터링을 처음 구현할때 체크박스를 선택했을때 그 해당 박스가 어느 카테고리의 몇번째인지를 알려주는 과정이 blocker였다. 자료들을 back end에서 어떤 형태로 주든 잘 받아먹는게 실력이라는 것을 다시한번 느꼈다.</p>
</blockquote>
</blockquote>
</li>
</ul>
</li>
</ul>
<br>


<p><img src="https://images.velog.io/images/park_kyo_su/post/a80bac8b-598e-4a45-aaa2-27e25597d7fd/Aug-01-2021%2018-09-01.gif" alt=""></p>
<h4 id="2-중복-필터링-sort">2. 중복 필터링, Sort</h4>
<blockquote>
<p><strong>2주차 Sort</strong></p>
</blockquote>
<ul>
<li>중복필터를 만들고 나니 비교적 수월하게 Sort기능을 구현했다.<blockquote>
<blockquote>
<p><strong>tmi</strong>
비교적 빠르게 제작하였지만, 쿼리문을 만드는 함수가 너무 많아 리팩토링의 필요성이 느껴졌다.</p>
</blockquote>
</blockquote>
</li>
</ul>
<h3 id="project-review">Project Review</h3>
<p>2차 프로젝트를 하며 내가 구현해보고 싶었던 기능들을 구현하여 뜻깊었다. 또한 blocker에 봉착해도 코드카타를 푼다는 마음가짐으로 하나씩 헤쳐나가니 결국에는 만들어낼 수 있었다.</p>
<p>PM역할을 하며 처음에는 부담감도 있었지만 팀원들과의 적극적인 소통을 통해 유쾌한 분위기에서 이번 프로젝트를 마무리할 수 있었다. 2주동안 함께한 팀원들에게 너무 감사하게 생각한다.</p>
<p>남은 기업협업에서도 이런 분위기를 유지해 나가야겠다.</p>
<h4 id="to-do-list--refactoring">To-do List / refactoring</h4>
<blockquote>
<ul>
<li>query문 함수 리팩토링 <code>Urlsearchparams</code> 사용</li>
</ul>
</blockquote>
<ul>
<li><code>filter</code>사용한 부분 <code>find</code>로 다시 만들어보기</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 22 - React.js - LifeCycle]]></title>
            <link>https://velog.io/@park_kyo_su/TIL-20-React.js-LifeCycle</link>
            <guid>https://velog.io/@park_kyo_su/TIL-20-React.js-LifeCycle</guid>
            <pubDate>Sun, 25 Jul 2021 16:53:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>리액트를 사용할수록 자주 발생하는 에러가 Lifecycle 관련이다. 부모 컴포넌트와 자식 컴포넌트의 Lifecycle에 대해 알아보고 관련된 에러를 해결하는 방법을 정리해보고자 한다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/park_kyo_su/post/39121fb1-7f0d-4ee5-b265-8461b5ea9b87/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-07-26%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.20.28.png" alt=""></p>
<p><strong>LifeCycle 기본 순서</strong></p>
<ol>
<li>constructor</li>
<li>render</li>
<li>componentDidMount</li>
<li>(fetch 완료)</li>
<li>(setState)</li>
<li>render</li>
<li>componentDidUpdate (5번에서 setState 되었기 때문에 컴포넌트 업데이트 발생)</li>
<li>componentWillUnmount</li>
</ol>
<p><strong>Sibiling Lifecycle 순서</strong></p>
<ol>
<li>부모 constructor</li>
<li>부모 render (부모 render 안에 있는 자식 컴포넌트로 넘어감)</li>
<li>자식 constructor</li>
<li>자식 render</li>
<li>자식 componentDidMount (여기까지 하고 부모 컴포넌트로 다시 넘어감)</li>
<li>부모 componentDidMount</li>
<li>부모 fetch 완료 (setState 발생 &gt; 업데이트 발생 &gt; 다시 render)</li>
<li>부모 render (부모 render 안에 있는 자식 컴포넌트로 넘어감)</li>
<li>자식 render</li>
<li>자식 componentDidUpdate<ul>
<li>(componentDidMount는 최초 렌더 시 한 번만 실행되기 때문에 componentDidUpdate 발생. 여기까지 하고 다시 부모로 넘어감.)</li>
</ul>
</li>
<li>부모 componentDidUpdate<ul>
<li>(componentDidMount는 최초 렌더 시 한 번만 실행되기 때문에 componentDidUpdate 발생)</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 21 -  Rebase]]></title>
            <link>https://velog.io/@park_kyo_su/Git-Workflow-Rebase</link>
            <guid>https://velog.io/@park_kyo_su/Git-Workflow-Rebase</guid>
            <pubDate>Wed, 21 Jul 2021 02:49:44 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>지금까지 <code>git merge</code> 명령어를 사용했지만 2차 프로젝트부터는 <code>git rebase</code>로 대체할 것이다.</p>
</blockquote>
<h2 id="rebase">Rebase</h2>
<ul>
<li>머지커밋이 남지 않고 linear한 이력관리가 가능해진다 = 불필요한 커밋을 하나로 squash <del>(정상적인 경우 PR / 브랜치 당 커밋이 하나여야 한다)</del></li>
</ul>
<h4 id="명령어">명령어</h4>
<blockquote>
<ul>
<li><code>git rebase -i main</code> : 명령어를 통해 중간 중간 브랜치에 쌓인 커밋을 하나로 정리</li>
</ul>
</blockquote>
<ul>
<li>해당 브랜치의 base commit을 확인하는 방법 : <code>git merge-base main feature/sign-in</code> <del>(필수 아님)</del></li>
</ul>
<h4 id="커밋-합치기">커밋 합치기</h4>
<blockquote>
<ol>
<li>작업브랜치에서 git rebase -i master</li>
<li>pick =&gt; squash로 커밋 합치기</li>
<li>[Add]메세지 정리</li>
</ol>
</blockquote>
<h4 id="rebase-conflict-해결"><code>rebase</code> Conflict 해결</h4>
<ul>
<li><code>rebase</code> 도중 충돌이 일어날 경우 마치 코드가 날아간 것 처럼 보일 수 있다. 코드가 사라진 것이 아니라 코드를 합치던 도중 중단된 것이다. 충돌을 해결하고 남은 과정을 끝까지 진행하면 모든 코드가 다 들어와 있게 된다. 혹 잘못 리베이스를 했다면, <code>git rebase —-abort</code> (리베이스 도중) 혹은 <code>git reflog</code> 로 돌아갈 지점을 찾은 후 <code>git reset --hard 돌아갈지점</code> (리베이스 완료 후) 명령어로 복구할 수 있다.</li>
</ul>
<blockquote>
<ol>
<li>master 브랜치로 checkout</li>
<li>git pull</li>
<li>작업 브랜치로 checkout</li>
<li>git rebase -i master</li>
<li>conflict 발생/ conflict 해결</li>
<li>git add .</li>
<li>git rebase --continue</li>
</ol>
</blockquote>
<h4 id="포스푸쉬-불가피하게-추가-수정하여-push를-다시-할-경우">포스푸쉬 <del>(불가피하게 추가 수정하여 push를 다시 할 경우)</del></h4>
<p>이미 올라간 commit이 있기 때문에 <code>push</code>가 불가능하다고 나온다.
그럴때는 이미 작업자가 앞에 commit 내용을 알고 있으므로 force push를 진행한다.</p>
<blockquote>
<ol>
<li>작업한 파일 커밋 합친 후</li>
<li>git push origin featre -f</li>
<li>squash</li>
</ol>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 20 - 인증과 인가]]></title>
            <link>https://velog.io/@park_kyo_su/%EC%9D%B8%EC%A6%9D%EA%B3%BC-%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@park_kyo_su/%EC%9D%B8%EC%A6%9D%EA%B3%BC-%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Sun, 18 Jul 2021 16:27:13 GMT</pubDate>
            <description><![CDATA[<h3 id="인증은-무엇이고-왜-해야할까">인증은 무엇이고 왜 해야할까?</h3>
<p>Authentication</p>
<ul>
<li>인증은 회원가입과 로그인을 말한다.<ul>
<li>인증은 왜 필요할까?</li>
</ul>
</li>
<li>해당 서비스를 누가 쓰는지, 어떻게 사용하는지 등 추적이 가능하도록 하기 위해</li>
<li>인증에 필요한 것?<ul>
<li>아이디, 이메일주소, 비밀번호 등..</li>
</ul>
</li>
</ul>
<p>비밀번호는 어떻게 관리해야 할까?</p>
<ul>
<li>Database에 저장 시 개인정보를 해싱하여 복원할 수 없도록 한다.<ul>
<li>해싱 = 난독화</li>
</ul>
</li>
<li>통신 시 개인 정보를 주고받을 때 SSL을 적용하여 암호화 (HTTPS)</li>
</ul>
<p>암호화는 어떻게 할까?</p>
<ul>
<li>단방향 해쉬</li>
<li>원래 해쉬(hash)함수는 자료구조에서 빠른 자료의 검색, 데이터 위변조 체크를 위해서 쓴다.<ul>
<li>복원이 불가능한 단방향 해쉬함수는 암호학적 용도로도 사용한다.</li>
</ul>
</li>
<li>결과만 봐서는 식별 불가</li>
</ul>
<p>JSON Web Token
<img src="https://images.velog.io/images/park_kyo_su/post/d691af07-e376-4161-9bb2-6a4d0be9300d/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-06-28%20%EC%98%A4%ED%9B%84%202.25.03.png" alt=""></p>
<ul>
<li>JWT 구조이다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Project - 1 - Clone - Dr.Jart++]]></title>
            <link>https://velog.io/@park_kyo_su/Project-1-Clone-Dr.Jart</link>
            <guid>https://velog.io/@park_kyo_su/Project-1-Clone-Dr.Jart</guid>
            <pubDate>Sun, 18 Jul 2021 15:38:42 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>부트캠프 1차 팀프로젝트로 팀원 6명이 한 팀으로 구성되어 화장품 사이트인 Dr.Jart+를 클론 코딩 하였다. 처음으로 실무처럼 진행한 프로젝트로 프로젝트 시작 전부터 회고에서 말했듯이 걱정만 하고 있었지만, 감사하게도 팀원 모두가 적극적으로 서로 도우며 2주동안 프로젝트를 진행한 덕분에 목표한 바를 이룰 수 있었다.</p>
</blockquote>
<h3 id="drjart-웹페이지-클론-프로젝트-회고">Dr.Jart+ 웹페이지 클론 프로젝트 회고</h3>
<p>처음 프로젝트 시작전 내가 선정한 사이트 2개가 모두 후보에 올라 있어 기분이 좋았다. 그 중에 하나인 Dr.Jart+가 최종 선정이 되었고 조사했던 사이트인 만큼 최선을 다하고자 했다. </p>
<h4 id="drjart-웹페이지-선정이유"><a href="https://us.drjart.com">Dr.Jart+</a> 웹페이지 선정이유</h4>
<p><img src="https://images.velog.io/images/park_kyo_su/post/eb68bc89-629b-4844-b2ba-24e0a3be9819/Jul-19-2021%2000-01-57.gif" alt=""></p>
<ul>
<li>Dr.Jart+ 특유의 모던함으로 구성된 웹페이지가 1차 프로젝트로서 적합</li>
<li>다양한 기능(필터링, 카러셀, 장바구니, 인증인가 등..) </li>
<li>다양한 카테고리로 백앤드와의 통신에서도 적합하다고 판단</li>
</ul>
<h4 id="웹페이지-ideation">웹페이지 Ideation</h4>
<ul>
<li>화장품의 다양한 카테고리를 활용할 수 있는 <code>치즈</code>를 주제로 선정</li>
<li>한국사이트의 과한 에니메이션을 배제 미국사이트 레이아웃 채택</li>
<li><strong>Dr.Mozza+</strong>로 네이밍 / <del>치즈 Mozzarella에서 영감🧀</del></li>
</ul>
<blockquote>
<h4 id="작업기간">작업기간</h4>
<p>2021.7.5 - 2021.7.16</p>
</blockquote>
<h4 id="기술스택">기술스택</h4>
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript(ES6+)</li>
<li>React</li>
<li>SASS</li>
<li>Git<h4 id="project-tool">Project Tool</h4>
</li>
<li>Trello</li>
<li>Notion</li>
<li>POSTMAN</li>
</ul>
<blockquote>
<h4 id="주요-구현-사항">주요 구현 사항</h4>
<p>🧀내가 맡은 구현사항
<strong>Nav bar 레이아웃 및 기능 구현🧀
메인페이지 슬라이더 기능 구현🧀
메인페이지 기본 레이아웃 구현🧀
공용 컴포넌트 레이아웃 및 기능 구현🧀
상품 카드 컴포넌트 레이아웃 구현</strong>🧀
상품 카드 컴포넌트 기능 구현
제품 상세 페이지 레이아웃 및 기능 구현
제품 리스트 페이지 레이아웃 및 기능구현
제품 리스트 페이지 filtering 기능 구현
로그인, 회원가입 레이아웃 및 기능 구현
장바구니 페이지 레이아웃 및 기능 구현</p>
</blockquote>
<h3 id="project-flow">Project Flow</h3>
<p><img src="https://images.velog.io/images/park_kyo_su/post/b6d8dfdf-ec0a-433d-8751-0d7ff9ee1357/%EA%B7%B8%EB%A6%BC1.png" alt=""></p>
<h4 id="1주차">1주차</h4>
<p>1주차에는 <code>trello</code>를 사용하여 구현할 기능들에 대해 카트를 세분화 하고 역할을 분담하였다. 하지만 프로젝트를 진행할수록 처음에 카드 세분화 했다고 생각한게 부족하였는지 계속 자가번식하여 관리하기가 어려워지기 시작했다. </p>
<p><img src="https://images.velog.io/images/park_kyo_su/post/80b1b0da-3236-43c9-87ba-8ab6419b417d/%EA%B7%B8%EB%A6%BC2.png" alt=""></p>
<h4 id="2주차">2주차</h4>
<p>2주차 부터는 <code>notion</code>의 <code>roadmap</code>을 적극 활용하여 회의록도 노션에 적기 시작하였으며 그때부터 뭔가 front/Back간의 명확한 소통과 연결이 이루어지기 시작했다.
<img src="https://images.velog.io/images/park_kyo_su/post/b7502b7d-cf47-4de0-8bea-b9d3cf40f232/%EA%B7%B8%EB%A6%BC3.png" alt="">
또한 <code>POSTMAN</code>을 적극 활용하여 미리 백앤들와 데이터 구조를 맞춰 서버를 통신해 볼때의 오류를 최소화하였다.</p>
<h3 id="output👍">OUTPUT👍</h3>
<p><img src="https://images.velog.io/images/park_kyo_su/post/67489ddf-99a9-4b12-8a01-2854cdc18188/Jul-19-2021%2000-20-09.gif" alt=""></p>
<blockquote>
<p><a href="https://github.com/Junghoon-P/Dr.Jart-Clone-Project.git">front-end repository</a>
<a href="https://github.com/wecode-bootcamp-korea/22-1st-DrMozzarella-backend">back-end repository</a>
<a href="https://youtu.be/lqHxD3Zq770">전체 기능 구현 영상 -Youtube</a></p>
</blockquote>
<h3 id="detail">Detail</h3>
<h4 id="1-carousel">1. Carousel</h4>
<p><img src="https://images.velog.io/images/park_kyo_su/post/339d43c2-9ad0-4aa0-b716-207b76353bbe/ezgif.com-video-to-gif-2.gif" alt=""></p>
<blockquote>
<p><strong>1주차 Carousel</strong></p>
</blockquote>
<ul>
<li>카러셀 기능 구현 / Potential blockers: 접근방식의 헷갈림, map, fetch 위치 정리<ul>
<li>슬라이드 끝에서 멈추는 기능 구현 필요</li>
<li>transition 구현</li>
</ul>
</li>
<li>Mock data 연동 및 백앤드 통신 test<blockquote>
<blockquote>
<p><strong>tmi</strong>
처음 카러셀 기능을 구현할때 검색하지 않고 만들고 싶어 이것저것 시도를 해보았다. 그러다 다른 팀원분의 약간의 팁을 받고 구현해낼 수 있었다. 사실 알고보면 단순한 로직인데 처음에 알아차리는게 어려운 것 같다.</p>
</blockquote>
</blockquote>
</li>
</ul>
<br>

<p><img src="https://images.velog.io/images/park_kyo_su/post/6263b6cb-6468-4b78-b086-c0487f0eb7eb/ezgif.com-video-to-gif.gif" alt="">
<strong>반응형을 고려한 재설계</strong>
<br></p>
<p><img src="https://images.velog.io/images/park_kyo_su/post/53ff4f8b-4bd6-450f-92be-ac00b9b8653a/Jul-19-2021%2001-57-37.gif" alt="">
<img src="https://images.velog.io/images/park_kyo_su/post/a6144680-24de-4559-8be0-5f5853d523fe/Jul-19-2021%2002-03-49.gif" alt=""></p>
<blockquote>
<p><strong>2주차 Carousel</strong></p>
</blockquote>
<ul>
<li>카러셀 기능 구현 / blokers 해결 및 최적화 <ul>
<li>슬라이드 끝에서 멈춤</li>
<li>transition 구현</li>
<li>반응형 구현</li>
<li>카드 컴포넌트를 활용한 카러셀 추가</li>
</ul>
</li>
<li>백앤드 통신 및 데이터 추가</li>
</ul>
<h4 id="2-nav">2. Nav</h4>
<p><img src="https://images.velog.io/images/park_kyo_su/post/955c74f7-4a4e-47f7-befa-bc425705fc22/Jul-19-2021%2002-13-58.gif" alt=""></p>
<blockquote>
<p><strong>2주차 Nav</strong></p>
</blockquote>
<ul>
<li>드롭다운 기능구현</li>
<li>동적라우팅 연결</li>
<li>반응형 구현<blockquote>
<blockquote>
<p>tmi
Carousel을 한번 구현하고 나서 감을 잡아서 구현하는데 성공을 하였다. 지금 만들어진 코드로는 단순히 마우스가 hover시 작동하는 조건인데 프로젝트 마지막쯤에 다른분들의 코드를 보며 얻은 팁인 <code>classname</code>을 삼항연산자로 활용하여 조건을 부여하는 방식으로 리팩토링을 해봐야겠다.</p>
</blockquote>
</blockquote>
</li>
</ul>
<h4 id="pr-리뷰중-기억남는-사소한-🍯팁">Pr 리뷰중 기억남는 사소한 🍯팁!</h4>
<pre><code class="language-js">//ex
handleClickPrev() {            //지양

handleClickPrev = () =&gt; {.     //권장</code></pre>
<p>이벤트에 콜백 함수로 넘겼을 때 this가 동적으로 바뀌면서 문제가 될 수 있다.<br>따라서 class 컴포넌트에서는 가급적 화살표 함수로 써주는걸 권장한다.
+@ 바인드와 같은 원리라 .bind()를 써주는 것도 가능하지만 굳이 쓸 이유는 없다.</p>
<pre><code class="language-js">&lt;i className=&quot;fas fa-chevron-left fa-4x&quot; 
        onClick={() =&gt; this.handleClickPrev()} /&gt;

&lt;i className=&quot;fas fa-chevron-left fa-4x&quot;
    onClick={this.handleClickPrev} /&gt;</code></pre>
<p>새로 함수 인스턴스를 만들지 않고 함수를 직접 넘겨주는 것이 좋다.
<strong>why?</strong>🧐
해당 부분이 실행될 때마다 기존에 <strong>생성해놓은 함수를 호출</strong>하는것이 아니라 
<strong>새로운 함수를 생성해서 실행하는 방식</strong>이라서 비효율적이라고 할 수 있다.</p>
<h3 id="project-review">Project Review</h3>
<p>1차 프로젝트를 하며 지난 한달간 배운 것들을 활용해보며 내게 부족한 부분이 정확히 알게 되었다. 앞서 작성했던 한달 회고록에서 말한 것처럼 내가 모르는 부분을 부끄러워 하기보다 알게된 것을 기뻐하며 해결하는 태도 또한 갖게 되었다.</p>
<p>사실 내가 구현한 기능들은 뭔가 나 스스로 완벽히 마음에 드는 결과물은 아니다. 추가 구현사항들이 남아 있지만 그것은 추후 리펙토링을 위해 따로 리스트를 작성해 두었다. </p>
<p>욕심부리지 않고 내가 소화할 수 있는 기능들을 구현하며, 팀프로젝트에서 맡은 사항을 해결하는데 초점을 두었다. 또한 이번 프로젝트를 통해 가장 중요한 <code>개발자</code>로써의 태도와 자세를 깨닫게 되었으며 가장 중요한 깨달음이라고 생각한다.</p>
<p>팀원들과 함께 프로젝트를 진행하는 2주 매순간마다 <strong>소통이 즐거웠으며</strong> 다들 유쾌한 분위기에서 프로젝트를 진행해서인지, 중간에 고비가 있어도 팀원들이 있었기에 극복해낼 수 있었다. 이런게 개발자 문화 아닐까? 또한 팀원들처럼 같이 있는게 즐거운 사람들과 일하는게 축복이라는걸 느꼈다. 2주동안 팀원들에게 함께 해줘서 너무 고맙게 생각한다.🙏 </p>
<p>앞으로 진행할 프로젝트 또한 이번처럼 다같이 긍정적인 분위기로 진행할 수 있도록 노력해야겠다. 화이링💪  </p>
<h4 id="to-do-list--refactoring">To-do List / refactoring</h4>
<blockquote>
<ul>
<li>carousel 자동 재생 및 드래그 기능</li>
</ul>
</blockquote>
<ul>
<li>carousel 페이지 끝에 갔을때 기능이 정지(구현완료) + 버튼 사라짐(추가!)</li>
<li>카트 컴포넌트 기능 재구현 (복습)</li>
<li>로그인/로그아웃 시 토큰을 인지하여 상태 변경 / 리덕스 학습 후 추가 예정</li>
<li><code>classname</code>을 삼항연산자로 활용한 리팩토링</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[ All | RESTful API]]></title>
            <link>https://velog.io/@park_kyo_su/All-RESTful-API</link>
            <guid>https://velog.io/@park_kyo_su/All-RESTful-API</guid>
            <pubDate>Thu, 08 Jul 2021 06:03:42 GMT</pubDate>
            <description><![CDATA[<h2 id="restful-apiapplication-program-interface">RESTful API(Application Program Interface)</h2>
<ul>
<li>API 시스템을 구현하기 위한 아키텍처 중에 가장 널리 사용되는 형식</li>
</ul>
<h3 id=""></h3>
<p>URI / HTTP Method / Payload</p>
<ul>
<li>URI (Uniform Resorce Identifier)</li>
<li>해당 사이트의 특정 자원의 위치를 나타내는 유일한 주소 - 리소스</li>
<li><a href="https://finance.naver.com/login">https://finance.naver.com/login</a></li>
<li><a href="https://finance.naver.com/main">https://finance.naver.com/main</a></li>
</ul>
<h3 id="http-method">HTTP Method</h3>
<ul>
<li>HTTOP request가 의도하는 action을 정의하는 것</li>
</ul>
<h3 id="payload">Payload</h3>
<ul>
<li>HTTP request에서 server로 보내는 데이터 (body)</li>
</ul>
<h3 id="representational-state-transfer">Representational State Transfer</h3>
<ul>
<li>리소스(HTTOP URI로 정의된)를 어떻게 한다(HTTP Method + Payload)를 구조적으로 깔끔하게 표현</li>
<li>Rest 방식이 적용된 RESTful API<ul>
<li>삼성전자 주식 정보를 받기 위한 HTTP 요청<ul>
<li>HTTP GET <a href="https://api.treushort.com/stock/005930">https://api.treushort.com/stock/005930</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="self-descriptiveness">Self-descriptiveness</h3>
<ul>
<li>여러 장점들이 있지만, 사실 그중 가장 명확한 장점은 self-descriptiveness 이다.</li>
<li>RESTful API는 그 자체만으로도 API의 목적이 쉽게 이해가 된다.</li>
</ul>
<h3 id="restful-api-설계-규칙">RESTful API 설계 규칙</h3>
<ul>
<li><p>URI 정보를 명확하게 표시한다. resouce는 명사를 사용한다.
ex)GET/user/1 -&gt; GET/users/1</p>
</li>
<li><p>resouce에 대한 행위를 HTTP Method(GET, POST, PUT, DELETE)로 표현한다.</p>
<ul>
<li>URI에 HTTP Method가 포함되서는 안된다.
ex)GET delete/user/1 -&gt; DELETE/users/1</li>
<li>URI에 동사가 포함되서는 안된다.
ex)GET/user/show/1 -&gt; GET/users/1</li>
</ul>
</li>
<li><p>resource 사이에 연관 관계가 있는 경우</p>
<ul>
<li>/리소스/고유ID/관계 있는 리소스
ex)GET/users/{user_id}/profile</li>
</ul>
</li>
<li><p>URI는<code>/</code> 구분자를 사용하여 자원의 계층 관계를 나타내는데 사용한다.</p>
</li>
<li><p>URI 마지막 문자로 <code>/</code>를 포함하지 않는다.</p>
</li>
<li><p>불가피하게 URI가 길어지는 경우 <code>-</code>를 사용하여 가독성을 높인다.</p>
</li>
<li><p><code>_</code>는 사용하지 않는다.</p>
</li>
<li><p>URI 경로에는 대문자 사용을 피하도록 규정하고 있다.</p>
</li>
<li><p>파일의 경우 payload의 호맷을 나타내기 위한 파일 확장자를 URI에 포함시키지 않는다.</p>
</li>
</ul>
<h3 id="restful-api-설계-예시--path-parameter">RESTful API 설계 예시 -Path parameter</h3>
<p><img src="https://images.velog.io/images/park_kyo_su/post/35fb4505-1d7e-4570-b4eb-0a4533d1776c/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-07-08%20%EC%98%A4%ED%9B%84%202.40.49.png" alt=""><img src="https://images.velog.io/images/park_kyo_su/post/dba42d73-15ba-4d38-992b-d0530444b91d/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-07-08%20%EC%98%A4%ED%9B%84%203.01.49.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 19 - React.js - Router & Sass]]></title>
            <link>https://velog.io/@park_kyo_su/TIL-16-React.js-Router-Sass</link>
            <guid>https://velog.io/@park_kyo_su/TIL-16-React.js-Router-Sass</guid>
            <pubDate>Mon, 05 Jul 2021 00:42:01 GMT</pubDate>
            <description><![CDATA[<h2 id="1-react-router">1. React Router</h2>
<h3 id="1-1-spa-single-page-application">1-1. SPA (Single Page Application)</h3>
<ul>
<li>SPA (Single Page Application) - 페이지가 한 개인 어플리케이션</li>
<li>원래는 제작하고자 하는 페이지 수만큼 <code>.html</code> 파일이 존재한다.<ul>
<li>하지만 리액트 프로젝트에서는 <code>.html</code>파일의 개수는 1개다.👍 =&gt; <strong>SPA (Single Page Application)</strong></li>
</ul>
</li>
<li>한 개의 <code>.html</code>에서 여러 개의 페이지를 보여주는 방법? =&gt; <code>Routing</code></li>
</ul>
<h3 id="2-2-routing">2-2. Routing</h3>
<p><img src="https://images.velog.io/images/park_kyo_su/post/a8019c07-0e7d-424b-8e67-8f044043e673/Screen_Shot_2020-09-01_at_1.04.52_PM.png" alt=""></p>
<ul>
<li>라우팅이란 <strong>다른 경로(URL)에 따른 View(화면)을 보여주는 것이다.</strong></li>
<li>리엑트 자체 기능이 아니다. 리액트는 프론트엔드 라이브러리인 만큼 UI이외의 라우트, 상태관리 기능이 내장되어 있지 않다.</li>
<li>리액트가 프레임워크가 아닌 라이브러리로 분류되는 이유이다.</li>
<li><code>React-router</code> 리액트의 라우팅을 기능을 위해 가장 많이 사용하는 라이브러리이다.</li>
</ul>
<h3 id="2-3-route-이동하기">2-3. Route 이동하기</h3>
<h4 id="1-link">1. <strong><code>&lt;Link&gt;</code></strong></h4>
<ul>
<li>클릭 시 바로 이동하는 로직 구현 시에 사용합니다.</li>
<li>ex. Nav Bar, Aside Menu, 아이템 리스트 페이지에서 아이템 클릭 시 &gt; 상세 페이지로 이동</li>
</ul>
<h4 id="2-thispropshistorypush">2. <strong><code>this.props.history.push()</code></strong></h4>
<ul>
<li>페이지 전환 시 추가로 처리해야 하는 로직이 있는 경우 this.props.history.push() 방법으로 구현합니다.<ul>
<li>ex. 로그인 버튼 클릭 시<ul>
<li>Backend API로 데이터(User Info) 전송</li>
<li>User Data 인증 / 인가</li>
<li>response message</li>
<li>Case 1 : 회원 가입되어 있는 사용자 &gt; Main 페이지로 이동</li>
<li>Case 2 : 회원 가입이 되어 있지 않은 사용자 &gt; Signup 페이지로 이동</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="2-sass">2. Sass</h2>
<ul>
<li><code>.scss</code> =&gt; Sass의 모든 기능을 지원하는 CSS의 상위집합이다.</li>
<li><code>nesting</code>이라는 멋진 기능이 있다. JSX 최상위 요소의 <code>className</code>을 컴포넌트 이름과 동일하게 설정해주고, <code>.scss</code>파일에서도 최상위 요소 안 쪽에서 하위 요소의 스타일 속성을 정의할 수 있도록 해야 한다. </li>
</ul>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://velopert.com/3417">https://velopert.com/3417</a></li>
<li><a href="https://heropy.blog/2018/01/31/sass/">https://heropy.blog/2018/01/31/sass/</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 18 - React.js - Component & JSX]]></title>
            <link>https://velog.io/@park_kyo_su/TIL-17-React.js-Component-JSX</link>
            <guid>https://velog.io/@park_kyo_su/TIL-17-React.js-Component-JSX</guid>
            <pubDate>Wed, 30 Jun 2021 10:55:54 GMT</pubDate>
            <description><![CDATA[<h2 id="1-component">1. Component</h2>
<p>Component(컴포넌트) : 재활용 가능할 UI 구성 단위</p>
<ul>
<li>재활용성</li>
<li>유지보수 편리</li>
<li>해당 페이지 구성은 한눈에 파악하기 용이</li>
<li>컴포넌트는 또 다른 컴포넌트를 포함할 수 있다.<ul>
<li>부모 컴포넌트 - 자식 컴포넌트</li>
</ul>
</li>
</ul>
<h2 id="2-class-vs-functional-component">2. Class vs Functional Component</h2>
<p>컴포넌트를 선언하는 방식에는 두 가지가 있다. 함수형 컴포넌트를 쓰는게 요즘 추세이긴 하나 나중에 Class형 컴포넌트를 사용한 코드를 만나면 할줄 알아야 하니 둘다 알아야 한다.</p>
<ul>
<li>Class형 컴포넌트(Class Component)</li>
<li>함수형 컴포넌트(Functional Component)</li>
</ul>
<h3 id="2-1-class-component">2-1. Class Component</h3>
<pre><code class="language-js">import React from &#39;react&#39;

class Component extends React.Component {
  render() {
    return (
            &lt;div&gt;
                &lt;h1&gt;This is Class Component!&lt;/h1&gt;
            &lt;/div&gt;
        )
  }
}

export default Component</code></pre>
<p>클래스형 컴포넌트는 <code>render</code>함수가 필수로 있어야한다. <strong>이를 통해 안에 보여 주어야 할 JSX를 반환한다.</strong></p>
<h3 id="2-2-functional-component">2-2. Functional Component</h3>
<pre><code class="language-js">import React from &#39;react&#39;

const Component = () =&gt; {
  return (
            &lt;div&gt;
                &lt;h1&gt;This is Functional Component!&lt;/h1&gt;
            &lt;/div&gt;
        )
};

export default Component</code></pre>
<ul>
<li>클래스 컴포넌트에 비해 간단하고 작성하기 편리하다.</li>
</ul>
<h2 id="3jsx">3.JSX</h2>
<p>JSX : JavaScript Syntax Extension</p>
<ul>
<li>자바스크립트 표현 : { ... javascript... }</li>
<li><code>class</code>를 <code>className</code>이라고 작성한다.</li>
<li>Inline Styling : <code>&lt;div style={{color : &quot;red&quot;}}&gt;Hello React&lt;/div&gt;</code></li>
<li>Self Closing tag : <code>&lt;div&gt;&lt;/div&gt;</code> vs. <code>&lt;div /&gt;</code></li>
<li>모든 요소를 감싸는 최상위 요소 (cf. React Fragments : <code>&lt;&gt; ... &lt;/&gt;</code>)</li>
</ul>
<blockquote>
<pre><code>: JSX의 큰 특징 중 하나는 내부 요소들을 감싸는 최상위 요소가 있어야 한. Fragments는 DOM에 별도의 노드를 추가하지 않고 하나의 컴포넌트 안에 여러 요소(자식)들을 간단하게 그룹화 할 수 있는 기능이다. 요소들을 감싸는 `div` 태그의 불필요한 생성을 막을 수 있어 유용하게 사용된다.</code></pre></blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 17 - React.js - 로그인 & 회원가입]]></title>
            <link>https://velog.io/@park_kyo_su/TIL-17-React.js-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85</link>
            <guid>https://velog.io/@park_kyo_su/TIL-17-React.js-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85</guid>
            <pubDate>Wed, 30 Jun 2021 10:38:03 GMT</pubDate>
            <description><![CDATA[<h2 id="1-인증인가">1. 인증/인가</h2>
<h4 id="인증은-무엇이고-왜-해야할까authentication">인증은 무엇이고 왜 해야할까?<code>Authentication</code></h4>
<ul>
<li>인증은 회원가입과 로그인을 말한다.<ul>
<li>인증은 왜 필요할까?</li>
</ul>
</li>
<li>해당 서비스를 누가 쓰는지, 어떻게 사용하는지 등 추적이 가능하도록 하기 위해</li>
<li>인증에 필요한 것?<ul>
<li>아이디, 이메일주소, 비밀번호 등..</li>
</ul>
</li>
</ul>
<h4 id="비밀번호는-어떻게-관리해야-할까">비밀번호는 어떻게 관리해야 할까?</h4>
<ul>
<li>Database에 저장 시 개인정보를 해싱하여 복원할 수 없도록 한다.<ul>
<li>해싱 = 난독화</li>
</ul>
</li>
<li>통신 시 개인 정보를 주고받을 때 SSL을 적용하여 암호화 (HTTPS)</li>
</ul>
<h4 id="암호화는-어떻게-할까">암호화는 어떻게 할까?</h4>
<ul>
<li>단방향 해쉬</li>
<li>원래 해쉬(hash)함수는 자료구조에서 빠른 자료의 검색, 데이터 위변조 체크를 위해서 쓴다.<ul>
<li>복원이 불가능한 단방향 해쉬함수는 암호학적 용도로도 사용한다.</li>
</ul>
</li>
<li>결과만 봐서는 식별 불가</li>
</ul>
<p><strong>JSON Web Token</strong>
<img src="https://images.velog.io/images/park_kyo_su/post/d691af07-e376-4161-9bb2-6a4d0be9300d/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-06-28%20%EC%98%A4%ED%9B%84%202.25.03.png" alt=""></p>
<ul>
<li>JWT 구조이다.</li>
</ul>
<h2 id="2-전체-flow-💫">2. 전체 flow 💫</h2>
<p><img src="https://images.velog.io/images/park_kyo_su/post/ead42369-a6f8-436c-a5f0-88b7afa524d2/_2020-09-07__10.00.53.png" alt=""></p>
<ol>
<li>사용자가 이메일을 입력하면 이메일 <code>input</code>의 <code>onchange</code>함수가 실행된다.</li>
<li><code>onchange</code>함수가 실행되면 <code>input</code>의 <code>value</code>를 <code>setState</code>를 통해 <code>state</code>f를 업데이트 한다.</li>
<li>사용자가 비밀번호을 입력하면 이메일 <code>input</code>의 <code>onchange</code>함수가 실행된다.</li>
<li><code>onchange</code>함수가 실행되면 <code>input</code>의 <code>value</code>를 <code>setState</code>를 통해 <code>state</code>f를 업데이트 한다.</li>
<li>버튼을 클릭하면 <code>onClick</code>함수가 실행된다.</li>
<li><code>onClick</code>함수 안에서 <code>fetch</code>함수가 실행면서 서버를 통해 <code>request</code>를 보낸다.</li>
<li>서버에서 사용자가 보낸 정보를 가지고 인증/인가 과정을 거친 후 <code>response</code>를 보내준다.</li>
<li><code>response</code>에 따라 이동을 하던가 에러 메세지를 보여준다.</li>
</ol>
<h3 id="fetch-함수-설명">fetch 함수 설명</h3>
<pre><code class="language-js">fetch(&quot;api주소&quot;, {
  method: &quot;POST&quot;,
  body: JSON.stringify({
    email: this.state.id,
    password: this.state.pw,
  }),
})

    .then((request) =&gt; response.json()
        .then((result) =&gt; console.log(&quot;결과: &quot;, result)); // 콘솔 위치가 로직 위치 
                    //button onclik 시 Fetch 함수 실행</code></pre>
<p>첫 번째 인자는 api 주소, 두 번째 인자는 http 통신에 관한 내용이다.두 번째 인자는</p>
<ul>
<li>method는 <code>GET</code>, <code>POST</code>, <code>PATCH</code> 등 <code>http method</code>를 입력한다.</li>
<li>get vs post<ul>
<li>get 정보를 얻는 것, post 백앤드에도 전달해줘야 할 정보가 있을 때🧐</li>
</ul>
</li>
<li>JSON 형태로 데이터를 주고 받는데 이 데이터를 body에 넣는다.<ul>
<li>통신을 할 때는 <code>string</code> 형태의 JSON으로 보내야 하기 때문에  <code>JSON.stringify()</code>라는 메서드를 활용해서 포맷을 기존의 Object에서 String으로 변환해준다.</li>
</ul>
</li>
<li>통신은 다른 로직에 비해 오래 걸리기 때문에 비동기 처리돼서 then 메서드를 사용한다.</li>
</ul>
<pre><code class="language-jsx">.then((response) =&gt; response.json())</code></pre>
<p>첫 번째 then에서는 server에서 보내준 response를 Object 형태로 변환한다.</p>
<pre><code class="language-jsx">.then((result) =&gt; console.log(&quot;결과: &quot;, result));</code></pre>
<p>두 번째 then에서는 object로 변환한 response를 console.log로 확인합니다.
여기서 원하는 로직을 구현한다.
예를 들어</p>
<ul>
<li>로그인 성공하면 main 페이지로 이동</li>
<li>로그인 실패하면 alert 창에 &quot;아이디나 비밀번호를 확인해주세요.&quot; 띄우기<br>
<br>
<br>

</li>
</ul>
<p><img src="https://images.velog.io/images/park_kyo_su/post/f2d9c9cc-bdb9-4cbc-bb9c-97f872d77d2b/images.jpeg" alt=""></p>
<h4 id="실제구현🎉">실제구현🎉</h4>
<p><img src="https://images.velog.io/images/park_kyo_su/post/dfd2f4f1-940f-4554-9120-54ac5593dc42/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-06-30%20%EC%98%A4%ED%9B%84%207.41.55.png" alt=""><img src="https://images.velog.io/images/park_kyo_su/post/a4fba7ed-1cd0-4bf6-b25d-193853c5bd42/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-06-30%20%EC%98%A4%ED%9B%84%207.40.07.png" alt=""><img src="https://images.velog.io/images/park_kyo_su/post/cfd457c2-f38f-41e4-8704-740a961eb50e/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-06-30%20%EC%98%A4%ED%9B%84%207.40.19.png" alt=""><img src="https://images.velog.io/images/park_kyo_su/post/ba7298f0-9a3b-487a-b7f6-b83dabdcaa25/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-06-30%20%EC%98%A4%ED%9B%84%207.40.25.png" alt=""></p>
<p>코딩을 시작한뒤 처음으로 백앤드와 합치는 작업을 해봤다. 물론 아직 실무에 비해서는 미미한 부분이지만 뭔가 작게나마 성취감을 느낄 수 있는 기회였다. mockdata를 만들어서 API연결전에 혼자서 작업해보는 것과는 달랐다.👏 앞으로 할 프로젝트를 생각하니 가슴이 웅장해진다🔥</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Code Kata - 5~6]]></title>
            <link>https://velog.io/@park_kyo_su/Code-Kata-56</link>
            <guid>https://velog.io/@park_kyo_su/Code-Kata-56</guid>
            <pubDate>Tue, 29 Jun 2021 04:11:07 GMT</pubDate>
            <description><![CDATA[<h2 id="code-kata---quiz-5">Code Kata - Quiz 5</h2>
<h2 id="code-kata---quiz-6">Code Kata - Quiz 6</h2>
<blockquote>
<p>문제
숫자로 이루어진 배열인 nums를 인자로 전달합니다. 숫자중에서 과반수(majority, more than a half)가 넘은 숫자를 반환해주세요.</p>
</blockquote>
<pre><code>예를 들어,
nums = [3,2,3]
return 3
nums = [2,2,1,1,1,2,2]
return 2
nums = [3,2,3]
return 3
nums = [2,2,1,1,1,2,2]
return 2
가정
nums 배열의 길이는 무조건 2개 이상</code></pre><h4 id="내-솔루션🧐">내 솔루션🧐</h4>
<pre><code class="language-js">function moreThanHalf(nums) {
  // 여기에 코드를 작성해주세요.
  let newArray = [];
  let a = 0; //최대값을 담는 변수
  let result; //최대값을 가지고 있는 변수의 length가 아닌 실제 요소

  for(let i = 0; i &lt; nums.length; i++){
    let newLength = nums.filter(element =&gt; nums[i] === element).length;
    if (newLength &gt; a) {
      a = newLength;
      result = nums[i];
    }
  } return result
}</code></pre>
<h4 id="생각한-순서">생각한 순서</h4>
<ol>
<li>숫자중에서 과반수가 넘는 숫자를 어떤 방식으로 구할 것인가?</li>
<li>숫자가 과반수가 넘는다면 들어온 <code>nums</code> 배열에서 각각 해당 index값을 추출해서 비교해본다.</li>
<li><code>filter</code>를 비교해서 <code>nums</code>의 index를 다 비교해본다.</li>
<li><code>let newLength = nums.filter(element =&gt; nums[i] === element).length;</code>여기 아래에 콘솔을 찍어보면 각각 index값이 중복되는 길이가 나온다. ex) nums[3,1,4,3] =&gt; 2,1,1,2</li>
<li>i번째 인덱스가 a보다 크면 a에 그 값을 넣어준다. =&gt; 최대값을 구하는 중</li>
<li>그렇게 나온 최대값의 실제 요소를 (result)를 반환한다.</li>
</ol>
<h4 id="지수님-솔루션👏">지수님 솔루션👏</h4>
<pre><code class="language-js">function moreThanHalf(nums) {
  if (nums.length &gt;= 2) {
    const major = {}
    nums.filter((el, index) =&gt; {
      major[el] = (major[el])? (major[el]+1) : 1;
    });
    const keys = Object.keys(major);
    const values = Object.values(major);
    const maxValues = Math.max(...values);
    for (let i in keys) {
      if (major[keys[i]] === maxValues) {
      return keys[i];
     }
    }
  }else{
    return 0;
  }
}</code></pre>
<p><img src="https://images.velog.io/images/park_kyo_su/post/627c41d9-af72-4674-91b9-8479af9c58c5/mblogthumb-phinf.pstatic.net.gif" alt=""></p>
<h4 id="배운점">배운점</h4>
<ul>
<li>이번 코드카타를 <code>filter</code>를 최대한 사용할려고 해보았다. 그러나 아직 <code>filter</code>에 들어가는 키값을 활용한 자유로운 로직을 짜는데 버퍼링이 있다. 좀더 친해져야겠다.</li>
<li>다른분들이 적은 코드가 정말 다 제각각이지만 <code>filter</code>를 기준으로 로직을 맥락은 같았다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Code Kata - 3~4]]></title>
            <link>https://velog.io/@park_kyo_su/Code-Kata-4</link>
            <guid>https://velog.io/@park_kyo_su/Code-Kata-4</guid>
            <pubDate>Thu, 24 Jun 2021 02:05:54 GMT</pubDate>
            <description><![CDATA[<h2 id="code-kata---quiz-3">Code Kata - Quiz 3</h2>
<blockquote>
<p>String 형인 str 인자에서 중복되지 않은 알파벳으로 이루어진 제일 긴 단어의 길이를 반환해주세요.</p>
</blockquote>
<pre><code>str: 텍스트 return: 중복되지 않은 알파벳 길이 (숫자 반환)
예를 들어, str = &quot;abcabcabc&quot; return 은 3 =&gt; &#39;abc&#39; 가 제일 길기 때문
str = &quot;aaaaa&quot; return 은 1 =&gt; &#39;a&#39; 가 제일 길기 때문
str = &quot;sttrg&quot; return 은 3 =&gt; &#39;trg&#39; 가 제일 길기 때문</code></pre><h4 id="내-솔루션">내 솔루션</h4>
<pre><code class="language-js">const getLengthOfStr = str =&gt; {
  let arr = []; // filter 메서드 대단하다, includes 메서드

  str.split(&#39;&#39;).filter(word =&gt; {
    //console.log(word);
    if(arr.length === 0){
      arr.push(word)
      //console.log()
    }else if(arr.includes(word)){

    }
  })
}</code></pre>
<ol>
<li>split(&#39;&#39;)으로 배열로 변환</li>
<li>let contiuntiyWord = {} 하나 만들기</li>
<li>for문으로 돌다가 같은거 나오면 그</li>
<li>그 후에 join(&#39;&#39;)으로 리턴</li>
</ol>
<p>이런식으로 계속 접근하면 메소드를 달리 해볼까 고민하다가 결국에는 해결을 하지 못했다.🥲
그 후 계속 고민하다가 다음날 다른 분들의 풀이를 참고를 했는데 그중 재상님의 솔루션을 소개하고자 한다.</p>
<h4 id="재상님-솔루션-👀"><a href="https://higher77.tistory.com/69?category=976814">재상님</a> 솔루션 👀</h4>
<pre><code class="language-js">function getLengthOfStr(s){
  let strArr = [];
  let strArr2 = [];

  for(let i = 0; i &lt; s.length; i++){
    let ss = s.slice(i, i+1);
    for(let j = 0; j&lt;strArr.length; j++){
      if(ss === strArr[j]){
        if(strArr2.length &lt; strArr.length){
           strArr2 = strArr.slice();
        }
        strArr = strArr.slice();
        break;
      }
    }
    strArr.push(ss)
  }
  return Math.max(strArr.elngth, strArr2.length;)
}</code></pre>
<p><img src="https://images.velog.io/images/park_kyo_su/post/9ac8d17a-5593-4204-91f9-e8ffeeba030e/R800x0.gif" alt="">
사실 아직 완벽하게 나만의 코드로 작성을 못해 리팩토링한 내 코드를 적지는 않았다. 현재로서는 재상님의 친절한 설명으로 따라치기에 불과해서..다시 하나하나 구현해야 할 기능을 나눠서 작성해보는 시간을 갖도록 해야겠다.</p>
<h2 id="code-kata---quiz-4">Code Kata - Quiz 4</h2>
<blockquote>
<p>숫자인 num을 인자로 넘겨주면, 뒤집은 모양이 num과 똑같은지 여부를 반환해주세요.
num: 숫자 return: true or false (뒤집은 모양이 num와 똑같은지 여부)</p>
</blockquote>
<pre><code>예를 들어, 
num = 123 return false =&gt; 뒤집은 모양이 321 이기 때문
num = 1221 return true =&gt; 뒤집은 모양이 1221 이기 때문
num = -121 return false =&gt; 뒤집은 모양이 121- 이기 때문
num = 10 return false =&gt; 뒤집은 모양이 01 이기 때문</code></pre><h4 id="내-솔루션-1">내 솔루션</h4>
<pre><code class="language-js">const sameReverse = num =&gt; {

  let numToString = num.toString();
  let reverseToString = numToString.split(&#39;&#39;).reverse().join(&#39;&#39;);

  if(numToString === reverseToString){
    return true;
  }else {
    return false;
  }
}</code></pre>
<h4 id="생각한-순서🧐">생각한 순서🧐</h4>
<ul>
<li>숫자가 인자로 들어와 비교를 할려면 우선 배열로 바꿔야겠다.<ul>
<li><code>.toString()</code>로 문자열로 -&gt; <code>.split(&#39;&#39;)</code>으로 배열로</li>
</ul>
</li>
<li><code>arrayToString</code> : 배열로 바꾸는 변수를 미리 선언</li>
<li><code>numToArray</code> : 배열을 다시 문자열로 by.<code>join(&#39;&#39;)</code></li>
<li><code>reverseToString</code> : 배열을 뒤집은 것을 문자열로 by.<code>join(&#39;&#39;)</code>,<code>reverse()</code></li>
<li>if문으로 모양이 똑같은면 <code>true</code>, 다르면 <code>false</code></li>
</ul>
<p><strong>지수님 솔루션👀</strong></p>
<pre><code class="language-js">  let a = num.toString().split(&#39;&#39;).reverse().join(&#39;&#39;);
  let result = (num.toString() === a ? true : false);
  return result;</code></pre>
<p><strong>종민님 솔루션👀</strong></p>
<pre><code class="language-js">return num.toString() === num.toString().split(&#39;&#39;).reverse().join(&#39;&#39;)</code></pre>
<p><strong>다시 정리한 솔루션👏</strong></p>
<pre><code class="language-js">let numToString = num.toString();
let reverseToString = numToString.split(&#39;&#39;).reverse().join(&#39;&#39;);
return numToString === reverseToString;</code></pre>
<p><strong>배운점</strong>
<img src="https://images.velog.io/images/park_kyo_su/post/050eae33-f096-481f-88d6-6627326e9421/bcfdd95ed00841f99433cfa08ae0a33d_1565669761.gif" alt=""></p>
<ul>
<li>이번 코드카타는 코드카타2에서 고칠점을 반영했지만 리팩토링 관점에서 접근하는 것이 부족했다.</li>
<li>지수님이 사용하신 <code>삼항연산자</code>를 사용하는 습관을 들여야겠다.<ul>
<li>if문의 조건이 길지 않다면 <code>삼항연산자</code>를 사용해야겠다.</li>
</ul>
</li>
<li>종민님은 한줄로 바로 적으셨다.(이게 니꼴라스가 말하는 자바스크립트의 <code>sexy🔥</code>라는 것인가..</li>
<li>다시 정리한 솔루션은 유지보수도 고려하여 적절히 혼합했다!</li>
<li>앞으로 플로우를 생각하면 적는 것을 계속하고 작성하고 다시 보며 리팩토링을 해봐야겠다.🤸‍♀️</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Code Kata - 2]]></title>
            <link>https://velog.io/@park_kyo_su/Code-Kata-2</link>
            <guid>https://velog.io/@park_kyo_su/Code-Kata-2</guid>
            <pubDate>Tue, 22 Jun 2021 15:51:46 GMT</pubDate>
            <description><![CDATA[<h2 id="code-kata---quiz-2">Code Kata - Quiz 2</h2>
<blockquote>
<p>reverse 함수에 정수인 숫자를 인자로 받습니다. 그 숫자를 뒤집어서 return해주세요.
x: 숫자 return: 뒤집어진 숫자를 반환!
예들 들어, </p>
</blockquote>
<pre><code>x: 1234 return: 4321
x: -1234 return: -4321
x: 1230 return: 321</code></pre><h4 id="내-솔루션">내 솔루션</h4>
<pre><code class="language-js">const reverse = x =&gt; {

  let reverseArray; //또 빼먹었었다..

  if(x&gt;0){  // x가 양수일 때
    reverseArray = x.toString().split(&#39;&#39;).reverse().join(&#39;&#39;);
    return Number(reverseArray);
  } else if(x&lt;0){ // x가 음수일 때
    reverseX = x * -1
    reverseArrayX = reverseX.toString().split(&#39;&#39;).reverse().join(&#39;&#39;);
    return Number(reverseArrayX)*-1;
  } else{ // x가 0일 때
    return x;
  }
}

</code></pre>
<h4 id="생각한-순서">생각한 순서</h4>
<ul>
<li>숫자를 뒤집어서 return</li>
<li>(숫자 -&gt; 배열)로 만들어 뒤집어서 반환 후 다시(배열 -&gt; 숫자)</li>
<li>(숫자 -&gt; string -&gt; 배열)로 정리 // <code>split</code>,<code>reverse</code> 를 사용하기 위해</li>
<li>x가 음수, 양수, 0일 경우를 생각하지 않고 테스트를 돌려보니 error가 나왔다.</li>
<li>x의 조건들을 if문을 활용하여 작성하니 통과!</li>
</ul>
<h4 id="고칠점">고칠점</h4>
<p>오늘도 변수를 미리 선언하는 습관을 지키지 못했다. 앞으로 더욱 복잡한 코드를 작성하게 될텐데 미리미리 이러한 습관을 들여야 겠다. 이렇게 미리 쓰일 변수들을 선언하고 진행하는 방식이 어찌보면 <code>React</code>의 <code>component</code>를 구성하는데에도 나중에 도움이 될 것 같다.</p>
<h4 id="수종님-솔루션👍">수종님 솔루션👍</h4>
<pre><code class="language-js">const reverse = x =&gt; {
  let reverseString = String(x).split(&#39;&#39;).reverse().join(&#39;&#39;);
  return parseInt(reverseString) * Math.sign(x);
}</code></pre>
<p><code>Math.sign</code>메서드를 사용한 풀이 방식이다. 아는 메서드만 사용하는 것이 아닌 검색을 잘해서 적절한 메서드를 찾아보는 접근도 해봐야겠다.</p>
<blockquote>
<p><code>Mathi.sign()</code> : 어떤 수가 양수, 음수, 0인지를 반환한다.</p>
</blockquote>
<ul>
<li>음수 = -1</li>
<li>양수 = 1</li>
<li>0 = 0</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Code Kata - 1]]></title>
            <link>https://velog.io/@park_kyo_su/Code-Kata-1</link>
            <guid>https://velog.io/@park_kyo_su/Code-Kata-1</guid>
            <pubDate>Tue, 22 Jun 2021 15:33:20 GMT</pubDate>
            <description><![CDATA[<p>앞으로 다양한 알고리즘을 만나게될 코드카타를 시작하였다.
계속 코드를 작성하면서 이런 로직이 맞을가 라는 의문이 들고 확신이 없을때가 있는데 코드카타를 꾸준히 진행해 나의 개발 근육을 💪벌크업!! 시켜야겠다.</p>
<p>코트카타를 진행함에 있어 목표는 다음과 같다.</p>
<p>✔️ 대화를 통한 문제 해결 능력을 기릅니다.
✔️ 컴퓨터 공학의 기본 자료구조 및 알고리즘을 익힙니다.
✔️ 자바스크립트에 대한 이해도를 높입니다.
✔️ 수료 후 취업 준비 기간 중 있을 실제 코딩테스트의 수준을 체험한다.</p>
<p>알고리즘을 보고 무조건 코드를 치는데에만 몰두하지 말고,
하나 하나 구현해야 하는 <code>ToDoList</code>를 작성 해야겠다.
이를 바탕으로 팀원과 어떠한 방식으로 접근할지 대화를 해야겠다.</p>
<ol>
<li>풀지 못하겠다고 조급하지 않기</li>
<li>문제를 받았을때 구현해야 할 조건들을 리스트로 작성할 것</li>
<li>다른 동기들의 코드를 보며 부족한 점이 있다면 <code>refactoring</code>!</li>
</ol>
<h2 id="code-kata---quiz-1">Code Kata - Quiz 1</h2>
<blockquote>
<p>twoSum함수에 숫자배열과 &#39;특정 수&#39;를 인자로 넘기면, 더해서 &#39;특정 수&#39;가 나오는 index를 배열에 담아 return해 주세요.</p>
</blockquote>
<pre><code>nums: 숫자 배열
target: 두 수를 더해서 나올 수 있는 합계
return: 두 수의 index를 가진 숫자 배열</code></pre><p>예를 들어,
nums은 [4, 9, 11, 14] target은 13
nums[0] + nums[1] = 4 + 9 = 13 이죠?
그러면 [0, 1]이 return 되어야 합니다.</p>
<blockquote>
<blockquote>
<p>#가정
target으로 보내는 합계의 조합은 배열 전체 중에 2개 밖에 없다고 가정하겠습니다.</p>
</blockquote>
</blockquote>
<h2 id="soluntion🐳">Soluntion🐳</h2>
<p><strong>내 솔루션</strong></p>
<pre><code class="language-js">const twoSum = (nums, target) =&gt; {
  let newArr = [];
  for (let i = 0; i &lt; nums.length; i++) {
    for (let j = i+1; j &lt; nums.length; j++) {
      if (nums[i] + nums[j] === target) {
        newArr.push(i);
        newArr.push(j);
      }
    }
  }

  return newArr;
}</code></pre>
<p><strong>재현님 솔루션!</strong></p>
<pre><code class="language-js">const twoSum = (nums, target) =&gt; {
  for (i = 0; i &lt; nums.length; i++) {
    if(nums.indexOf(target-nums[i]) != -1) {
      return [i, nums.indexOf(target-nums[i])];
    }
  }
}</code></pre>
<h4 id="배운점🤸">배운점🤸</h4>
<p>처음에 내가 접근했던 방식은 빈배열에 <code>push</code>하는 것이 아닌 
단순히 <code>for</code>문을 돌면서 풀려고 했었다. 하지만 너무 코드가 길어지고 
해결하지 못하다가 지수님의 팁으로 
빈 배열에 <code>push</code>하는 방식으로 진행하여 해결하였다. 
처음 사고방식의 스타트가 중요하다는 것을 느겼다. </p>
<p>재현님 코드는 처음 봤을때 감탄만 했다. 
<code>indexOf</code>를 활용한 접근을 생각도 못했는데 정말 적절한 메서드를 활용한 풀이였다.</p>
<blockquote>
<p><code>indexOf</code>
stringValue에서 특정한 문자열의 위치(index)를 반환한다.
탐색하려는 문자열이 존재하지 않는다면 -1을 반환한다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 16 - React.js - Intro]]></title>
            <link>https://velog.io/@park_kyo_su/TIL-16-React.js-Intro</link>
            <guid>https://velog.io/@park_kyo_su/TIL-16-React.js-Intro</guid>
            <pubDate>Tue, 22 Jun 2021 14:59:10 GMT</pubDate>
            <description><![CDATA[<h2 id="1-why-react🧐">1. Why React?🧐</h2>
<blockquote>
<p><strong>React ** = 
*<em>JavaScript 라이브러리 *</em>for 사용자 인터페이스(UI)+ **가상돔</strong>(불필요한 랜더링 없에고 성능 향상)</p>
</blockquote>
<p>리액트는 페이스북에서 개발하고 관리하는 사용자 인터페이스(UI)를 만들기 위한 JavaScript 라이브러리이다. 리액트와 같은 프론트엔드 라이브러리 혹은 프레임워크를 사용하는 가장 큰 이유는 <strong>UI를 자동으로 업데이트 해준다는 점이다.</strong> 리액트는 가상 돔(Virtual Dom)을 통해 UI를 빠르게 업데이트한다. <strong>가상 돔은 이전 UI 상태를 메모리에 유지해서, 변경될 UI의 최소 집합을 계산하는 기술이다.</strong> 이 기술 덕분에 불필요한 UI 업데이트는 줄고, 성능은 좋아진다. <strong>또한 리액트는 프레임워크가 아닌 라이브러리이기 때문에 다른 프레임워크와 함께 사용할 수 있다.</strong></p>
<blockquote>
<p>현실적인? 이유로는 페이스북의 지속적인 관리와 함께 생태계가 활성화 되어 있으며 다양한 자료, react native의 사용으로 인해 사용자가 꾸준히 증가이다. 즉, 지속적인 관리가 되며 많은 사람들이 사용하기 때문에 방대한 자료들에 쉽게 접근할 수 있다.</p>
<blockquote>
<p>또한 리액트의 컴포넌트는 가독성, 재사용성을 높여 유지보수를 쉽게 만들어 준다. 효과적으로 웹 어플리케이션을 제작할 수 있고, 개인 컴포넌트를 만드는 것 뿐만이 아닌 타인이 만든 수많은 컴포넌트도 사용할 수 있다.</p>
</blockquote>
</blockquote>
<h2 id="2-jsxjavascript-xml">2. JSX(JavaScript XML)</h2>
<pre><code class="language-jsx">const hi = &lt;p&gt;Hi&lt;/p&gt;;</code></pre>
<p>위의 문법은 <strong>자바스크립트의 확장버전</strong>인 <code>JSX</code>(syntax extension for JavaScript)이다. HTML과 유사하게 생겼으며 자바스크립트 파일 내에서 작성할 수 있다.
하지만 자바스크립트 문법과는 다르기 때문에 .js파일내에 JSX문법이 있으면 브라우저가 해석하지 못해 오류가 난다. <code>React.js</code>를 사용하기 위해 JSX 문법이 포함되어 있으면, 해당 파일을 정규 javascript 문법으로 변환시키는 컴파일 과정이 필요하다.</p>
<h3 id="2-1-jsx-element">2-1. JSX element</h3>
<pre><code class="language-html">const hi = &lt;p&gt;Hi&lt;/p&gt;;

const myFavorite = {
    food: &lt;li&gt;샐러드&lt;/li&gt;,
    animal: &lt;li&gt;dog&lt;/li&gt;,
    hobby: &lt;li&gt;programming&lt;/li&gt;
};</code></pre>
<p>위에 보이는 코드처럼 자바스크립트 코드 내부에 HTML문법을 써주면 그것이 JSX다. <code>.js</code>파일 어디서나 필요한 곳에 작성할 수 있다. 변수에 저장할 수도 있고, 함수의 인자로 넘길 수 도 있다.</p>
<h3 id="2-2-jsx-attribute">2-2. JSX attribute</h3>
<p>태그에 attribute(속성)을 주고 싶을 때는 항상 <code>&quot;&quot;</code>쌍따옴표로 감싸줘야 한다. attribute를 추가하고 싶을때는 HTML에서 쓰는 attribute name(속성명)과 다를 수있어 <a href="https://reactjs.org/docs/dom-elements.html#all-supported-html-attributes">react 공식문서</a>를 참고해야 한다.</p>
<p>가장 대표적인 예로 <code>class</code>를 주고 싶을 때는 원래 속성명은 <code>class</code>이지만 JSX에서는 <code>className</code>을 사용해야 한다.</p>
<h3 id="2-3-self-closing-tag"><a href="https://zhenyong.github.io/react/tips/self-closing-tag.html">2-3. Self-Closing Tag</a></h3>
<p>JSX에서는 어떤 태그라도 <code>self closing tag</code>가 가능하다. <code>input</code>과 같이 하나의 태그가 요소인 경우에는 <code>&lt;input /&gt;</code>과 같이 항상 <code>/</code>로 끝내줘야 한다.</p>
<p><code>div /</code>와 <code>&lt;div&gt;``&lt;/div&gt;</code>는 같은 표현이다.</p>
<h4 id="jsx-특징">JSX 특징</h4>
<ul>
<li>모든 요소를 감싸는 최상위 요소가 있어야 한다. =&gt; 항상 하나의 태그로 시작
  (cf. React Fragments : <code>&lt;&gt; ... &lt;/&gt;</code>)</li>
<li>자바스크립트로 표현한다. : { ... javascript... }</li>
<li><code>class</code>가 아닌 <code>className</code>이라 적는다.</li>
<li>Inline Styling : <code>&lt;div style={{color : &quot;red&quot;}}&gt;Hello React&lt;/div&gt;</code></li>
<li>Self Closing tag : <code>&lt;div&gt;&lt;/div&gt;</code> = <code>&lt;div /&gt;</code></li>
</ul>
<h3 id="2-4-nexted-jsx">2-4. Nexted JSX</h3>
<ol>
<li>(필수!)중첩된 요소를 만들려면 무조건 <code>()</code>소괄호로 감싸야 한다.<pre><code class="language-js">const good = (
&lt;div&gt;
 &lt;p&gt;hi&lt;/p&gt;
&lt;/div&gt;
);</code></pre>
</li>
<li>(필수!)항상 하나의 태그로 시작한다.<pre><code class="language-js">const wrong = (
&lt;p&gt;list1&lt;/p&gt;
&lt;p&gt;list2&lt;/p&gt;
);//eror</code></pre>
위에 코드처럼 처음 요소가 <code>sibling</code>이면 안되고, 무조건 하나의 태그로 감싸야 한다.<pre><code class="language-js">const right = (
&lt;div&gt;
 &lt;p&gt;list1&lt;/p&gt;
 &lt;p&gt;list2&lt;/p&gt;
&lt;/div&gt; //good!
);</code></pre>
<h3 id="2-5-rendering">2-5. Rendering</h3>
<blockquote>
<p>사전적 의미 : <a href="https://en.dict.naver.com/#/search?range=all&amp;query=rendering">rendering</a> = 구현</p>
</blockquote>
</li>
</ol>
<p>html요소(element), 또는 React요소 등의 코드가 눈으로 볼 수 있도록 그려지는, 구현되는 것을 렌더링이라고 한다.</p>
<pre><code class="language-js">ReactDOM.render(
  &lt;h1&gt;Hello, world!&lt;/h1&gt;,
  document.getElementById(&#39;root&#39;)
);</code></pre>
<p>React 요소가 DOM node에 추가되어 화면에 렌더되려면 ReactDOM.render 함수를 사용해야 한다. 첫 번째 인자에는 JSX로 React 요소를 인자로 넘기고, 두 번째 인자는 해당 요소를 렌더하고 싶은 container(부모요소)를 전달한다.</p>
<p>작성 필수 요소</p>
<ul>
<li>소괄호 감싸기</li>
<li>항상 하나의 태그로 시작</li>
<li>랜더링 = ReactDOM.render<h3 id="componet--재사용-가능한-ui단위">componet = 재사용 가능한 UI단위</h3>
컴포넌트는 독립적으로, 재사용가능한 코드로 관리할 수 있습니다. 하나의 컴포넌트에 필요한 html, css, js(validation check)를 모두 합쳐서 만들 수 있습니다.</li>
</ul>
<p>React 컴포넌트에서는 input을 props라고 말하고 return은 화면에 보여져야할 React요소가 return됩니다.</p>
<h4 id="함수로-컴포넌트-만들기">함수로 컴포넌트 만들기</h4>
<pre><code class="language-js">function Welcome(props) {
  return &lt;h1&gt;Hello, {props.name}&lt;/h1&gt;;
}</code></pre>
<h4 id="class로-컴포넌트-만들기">Class로 컴포넌트 만들기</h4>
<p>class로 컴포넌트를 만드려면 React.Component 를 extend해서 생성합니다. 컴포넌트를 생성할 때 render() 메서드는 무조건 정의해야하고, return도 해주어야 합니다. render() 메서드는 무조건 정의해야한다는 말은, component를 만들 때 필요한 메서드가 원래 더 있다는 말입니다. 그런데 그 중에서 render() 만 필수입니다.</p>
<p>class를 주고 싶을 때 원래 속성명은 class이지만 JSX에서는 className을 사용해야 합니다.</p>
<pre><code class="language-js">class Welcome extends React.Component {
  render() {
    return &lt;h1&gt;Hello, {this.props.name}&lt;/h1&gt;;
  }
}</code></pre>
<h4 id="오늘의-한줄-✏️">오늘의 한줄 ✏️</h4>
<p><img src="https://images.velog.io/images/park_kyo_su/post/eafdc705-0ba5-47f2-8a6b-cb177867fbd8/simon.gif" alt="">
리액트를 시작하는데 처음에 지레 겁먹었던 것보다 흥미로운 부분이 많았다.
앞으로 컴포넌트를 활용하여 더욱 가독성, 재사용성을 보완해야겠다.
물론 틈틈이 Js공부도 유지하면서...React.js 즉, js기반이니까!</p>
<h4 id="참고">참고</h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 15 - JavaScript - Object(1)]]></title>
            <link>https://velog.io/@park_kyo_su/TIL-15-JavaScript-Class</link>
            <guid>https://velog.io/@park_kyo_su/TIL-15-JavaScript-Class</guid>
            <pubDate>Tue, 22 Jun 2021 08:04:58 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>리액트를 공부하며 객체지향 프로그래밍의 핵심 공부를 다시하고자 자바스크립트의 Object와 Class를 정리해보고자 한다. 이번 TIL은 그 중에서 Class를 적고자 한다! 📝</p>
</blockquote>
<h2 id="1-object객체">1. Object(객체)</h2>
<p><img src="https://images.velog.io/images/park_kyo_su/post/d2c82fb9-4c89-482e-981c-c85c4a81d7d0/image.png" alt="">
위와 같은 데이터를 자바스크립트로 구현을 할려면 아래와 같이 데이터를 저장해야한다.</p>
<pre><code class="language-js">let plan1Name = &quot;Basic&quot;;
let plan1Price = 3.99;
let plan1Space = 100;
let plan1Data = 1000;
let plan1Pages = 10;
let plan2Name = &quot;Professional&quot;;
let plan2Price = 5.99;
let plan2Space = 500;
let plan2Data = 5000;
let plan2Pages = 50;
let plan3Name = &quot;Ultimate&quot;;
let plan3Price = 9.99;
let plan3Space = 2000;
let plan3Data = 20000;
let plan3Pages = 500;</code></pre>
<p>이 중에서 하나의 plan을 선택하면 아래와 같이 <code>alert</code>를 띄워주게 하였다.</p>
<pre><code class="language-js">alert(plan2Name + &quot;플랜 가격은 한 달에 &quot; + plan2Price + &quot;달러입니다.&quot;)

//만약에 자세하게 설명까지 할려면..
alert(&quot;용량은 &quot; + plan2Space + &quot;GB이고, ...&quot;);</code></pre>
<p>이런식으로 해당 플랜에 대한 변수 나열이 필요하다. 데이터가 늘어나면 늘어날수록 유지보수 및 가시성 관점에서 비효율적이다. 이럴때 <code>Object(객체)</code>로 표현하는 것이다!</p>
<p>위의 내용을 <code>object</code>에 맞게 다시 표현해보면..
<img src="https://images.velog.io/images/park_kyo_su/post/f3605936-eea8-4073-9927-a1d9a0783893/image.png" alt="">
이렇게 object를 사용한 데이터는 아래와 같이 <code>alert</code> 메세지를 바꿀 수 있다.</p>
<pre><code class="language-js">alert(plan2.name + &quot;플랜 가격은 한 달에 &quot; + plan2.price + &quot;달러입니다.&quot;)</code></pre>
<h2 id="2-객체-선언">2. 객체 선언</h2>
<p><img src="https://images.velog.io/images/park_kyo_su/post/cd6a34a1-9543-4ca5-8dab-dd0e20e71416/image.png" alt=""><del>var 지양 let 지향!</del>
객체를 만들때 규칙</p>
<ul>
<li>객체는 {}(중괄호)로 감싸져 있다.</li>
<li>property이름/property값 사이를 <strong>:(콜론)</strong>으로 구분한다.</li>
<li>property를 추가할 때는 <strong>,쉼표</strong>를 붙여준다.</li>
<li>property 이름은 중복되면 안된다.</li>
<li>property 값에는 어느 type이나 가능하다.<ul>
<li>type((string, number, array, object, function..)/</li>
</ul>
</li>
</ul>
<p>즉 객체는 이름과 값으로 구성된 프로퍼티들의 집합이다.
<code>plan1</code>의 객체를 만들면 다음과 같다.</p>
<pre><code class="language-js">let plan1 = {
  name: &quot;Basic&quot;,
  price: 3.99,
  space: 100,
  transfer: 1000,
  pages: 10
};</code></pre>
<h2 id="3-property-접근">3. Property 접근</h2>
<p><img src="https://images.velog.io/images/park_kyo_su/post/10990178-2443-4d6f-b6ef-98d852d7ca9b/image.png" alt="">
해당 객체의 property 값을 접근하고 싶을때는 다음과 같다.</p>
<pre><code class="language-js">let plan1 = {   
  name: &quot;Basic&quot;
};

console.log(plan1.name);
console.log(plan1[&quot;name&quot;]);</code></pre>
<p>단순히 생각하먼 마침표(.)로 접근하는 것이 편할 것 같은데, 대괄호 표현은 언제 쓰는지 알아보자🧐</p>
<p>대괄호에는 변수가 들어갈 수 있다. 예를 들어  <code>plan1</code> 객체의 <code>name</code>이라는 프로퍼티에 접근하고 싶을 때, 아래와 같이 활용한다.</p>
<pre><code class="language-js">let plan1 = {   
  name: &quot;Basic&quot;
};

let propertyName = &quot;name&quot;;

console.log(plan1[propertyName]);</code></pre>
<p>객체를 정의한 후에도 property 값을 수정할 수 있습니다.</p>
<pre><code class="language-js">let name = &quot;property1&quot;;

myObj[name] = [&quot;hi&quot;, &quot;hello&quot;];

console.log(myObj);</code></pre>
<p><img src="https://images.velog.io/images/park_kyo_su/post/7cdde131-f6ef-4355-a728-4b9d6c118c38/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-06-22%20%EC%98%A4%ED%9B%84%204.58.59.png" alt=""></p>
<h2 id="4-객체의-객체의-배열의-객체🤷">4. 객체의 객체의 배열의 객체.....?🤷</h2>
<pre><code class="language-js">let objData = {
  name: 50,
  address: { 
    email: &quot;gaebal@gmail.com&quot;,
    home: &quot;위워크 선릉2호점&quot;
  },
  books: {
    year: [2019, 2018, 2006],
    info: [{
      name: &quot;JS Guide&quot;,
      price: 9000
    }, {
      name: &quot;HTML Guide&quot;,
      price: 19000,
      author: &quot;Kim, gae bal&quot;
    }]
  }
};</code></pre>
<p><code>objData</code>라는 객체안에 <code>name</code>, <code>address</code>, <code>books</code>라는 프로퍼티가 있다. 그리고 <code>books</code>에 객체가 또 할당 되었다.</p>
<p>위의 데이터에서 &quot;HTML Guide&quot;에 접근하고 싶다면 아래와 같이 접근하면 된다.</p>
<pre><code class="language-js">let bookName = objData.books.info[1].name;</code></pre>
<h4 id="오늘의-한줄-✏️">오늘의 한줄 ✏️</h4>
<p><img src="https://images.velog.io/images/park_kyo_su/post/dce5adba-cf8a-4072-b71f-8cb1be15d1d1/5323ff32133b4d03ae5a98d4908afa40.gif" alt="">
리액트를 하나씩 진도를 나가며 복습하고 있는데 
왜 이러한 객체 구조를 필요한지를 이해할 수 있었다. 
또한 컴포넌트의 개념을 이해하는데에도
<strong><code>객체 = 이름과 값으로 구성된 프로퍼티의 집합</code></strong>이라는 플로우가 도움이 되었다. 
역시 복습 쵝오 👍👍👍</p>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 14 - JavaScript - Class]]></title>
            <link>https://velog.io/@park_kyo_su/TIL-14-JavaScript-Class-Object-1</link>
            <guid>https://velog.io/@park_kyo_su/TIL-14-JavaScript-Class-Object-1</guid>
            <pubDate>Tue, 22 Jun 2021 04:03:34 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>리액트를 공부하며 객체지향 프로그래밍의 핵심 공부를 다시하고자 자바스크립트의 Object와 Class를 정리해보고자 한다. 이번 TIL은 그 중에서 Class를 적고자 한다! 📝 </p>
</blockquote>
<h2 id="1-class">1. Class</h2>
<p>클래스는 객체지향 프로그래밍의 핵심이다. 객체지향 프로그래밍이란, <strong>프로그램을 객체들로 구성</strong>하고, *<em>객체들 간에 서로 상호 작용 *</em>하도록 작성하는 방법이다.</p>
<p>클래스는 <code>{ num: 1}</code>처럼 생긴 객체(Objcet)를 잘 설계하기 위한 틀이다. 이 때의 객체는 특정 로직을 갖고 있는 <strong>method(행동)</strong>와 <strong>멤버 변수(변경 가능한 상태)</strong>를 가진다. 원하는 구조의 객체 틀을 짜놓고, 비슷한 모양의 객체를 공장처럼 찍어낼 수 있다.</p>
<p>객체를 매번 만들어서 사용해도 좋지면, 큰 규모의 객체이거나 비슷한 모양의 객체를 단순반복적으로 계속 만들어야 한다면, <code>class</code>라는 설계도를 통해 만들 수 있다.</p>
<p><strong><u><em>CSS의 class와는 전혀 다른 개념이니 헷갈리지 말자!!!</em></u></strong></p>
<h2 id="2-construcror생성자">2. Construcror(생성자)</h2>
<p>객체(object)의 설계도인 클래스는 문법이 서로 비슷하다. 하지만 둘의 가장 큰 차이는 <code>constructor</code>라는 생성자 함수이다.</p>
<pre><code class="language-js">const morning = new Car(&#39;Morning&#39;, 2000000);</code></pre>
<p>위와 같이 class로 객체를 생성하는 과정을 <strong>&#39;인스턴스화</strong>&#39;라고 부른다.class를 통해 생성된 객체를 <strong>인스턴스(instance)</strong> 라고 부른다. class는 새로운 인스턴스를 생성할때마다 <code>constructor()</code> 매서드를 호출한다.</p>
<pre><code class="language-js">class Car {
  constructor(name, price) {
    this.name = name;
    this.price = price;
  };
}</code></pre>
<ul>
<li>Car는 class의 이름이다. 항상 대문자로 시작해야 하며, CamelCase로 작성해야 한다.</li>
<li>Car class의 istance를 생성할때마다 <code>constructor()</code> 매서드가 호출된다.</li>
<li><code>constructor()</code> 메서드는 name, price 2개의 argument(인자)를 받는다.</li>
<li><code>constructor()</code>에 <code>this</code>를 사용했는데, <u><code>class</code>의 실행범위(context)안에서 <code>this</code>는 해당 instance를 의미한다.</u></li>
<li><code>constructor()</code>에서 인자로 넘어오는 name과 price를 사용해 Car라는 class의 instace안에 있는 name, price 프로퍼티에 값을 할당했다.</li>
<li>이처럼 class 내에서 name, price와 같이 변경 가능한 상태값이자 class 내의 컨텍스트에서 어느 곳에서나 사용할 수 있는 변수를 &#39;<strong>멤버 변수&#39;</strong>라고 한다.</li>
<li>멤버 변수는** this** 키워드로 접근하다.</li>
</ul>
<h2 id="3-instance인스턴스">3. Instance(인스턴스)</h2>
<blockquote>
<p>const <strong>intance</strong> = new Word(<strong>&quot;사례, 경우&quot;, &quot;~을 예로 들다&quot;)</strong>;
인스턴스의 사전적 의미를 새로운 인스턴스에 담아 보았다.
사전적 의미에서 보듯이 <code>instance</code>는 새로운 case(경우)가 생겨난 것이다.
<em><del>개인적으로 사전의 의미를 보면 이해하기 쉬워 적어 보았다. 이번에도 역시 이해하는데 도움이 되었다.</del></em></p>
</blockquote>
<p>위에서 class instance를 생성했다.
<em>Instace(인스턴스) == <code>class</code>를 통해 생성된 객체</em>
인스턴스는 class의 property 이름과 method를 갖는 객체이다.
각각의 인스턴스마다 모두 다른 프로퍼티 값을 갖고 있다.</p>
<pre><code class="language-js">const morning = new Car(&#39;Morning&#39;, 20000000);</code></pre>
<ul>
<li>인스턴스는 Class 이름에 <code>new</code>를 붙여서 생성한다.</li>
<li>클래스 이름 우측에 <code>()</code>괄호를 열고 닫고, 내부에는 <code>constructor</code>에서 필요한 정보를 인자로 넘겨준다.</li>
<li>Car라는 클래스의 새로운 instance를 <code>morning</code>이라는 변수에 저장했다.</li>
<li><code>morining</code>이라는 String과 20000000이라는 Number를 Car 생성자에게 넘겨주었고, name, price 프로퍼티에 각자의 값이 할당되었다.</li>
</ul>
<p>즉, <strong>Car라는 클래스에</strong> 새로운 <strong>인스턴스</strong>를 생성하려면 <code>new</code>키워드가 필요하다. <code>new</code>키워드는 <code>constructor()</code> 메서드를 호출하고 새로운 인스터스를 <code>return</code> 해준다.</p>
<h2 id="4-methods메서드">4. Methods(메서드)</h2>
<p>메서드는 함수다. 그런데 객체가 프로퍼티 값을 갖고 있는 것을 메서드라고 부른다.
Class의 method는 Object(객체)의 문법과 똑같다.
다만 객체는 프로퍼티마다 comma(,)로 구분해줘야 하지만, 클래서는 그렇지 않다.</p>
<pre><code class="language-js">class Car {
  constructor(name, price) {
    this.name = name;
    this.price = price;
    this.department = &quot;선릉지점&quot;;
  }


  applyDiscount(discount) {  
    return this.price * discount;   
  }


  changeDepartment(departmentName) {
    this.department = departmentName;
  }
}</code></pre>
<p>위는 Car 객체에 <code>changeDepartment</code> 메서드를 추가한 것이다.</p>
<h3 id="assignment">Assignment</h3>
<ul>
<li><code>MyMath</code> 라는 class를 생성해주세요.</li>
<li><code>constructor</code> 에서는 숫자 2개를 인자로 받아 프로퍼티로 저장합니다.</li>
<li>총 4개의 메서드를 구현해주세요.<ul>
<li><code>getNumber</code> : 두 개의 숫자가 무엇인지 배열로 반환하는 메서드 → ex) [1, 2]</li>
<li><code>add</code> : 두 개의 숫자를 더하는 메서드</li>
<li><code>substract</code> : 두 개의 숫자를 빼는 메서드</li>
<li><code>multiply</code> : 두 개의 숫자를 곱하는 메서드</li>
</ul>
</li>
</ul>
<h4 id="answer">Answer</h4>
<pre><code class="language-js">class MyMath { constructor(number1, number2) {
  this.number1 = number1;
  this.number2 = number2;
}
  getNumber(){
  let arr = [];
  arr.push(this.number1);
  arr.push(this.number2);
    return arr;
}
  add(){
    return this.number1 + this.number2;
}
  substract() {
    return this.number1 - this.number2;
}
  multiply(){
    return this.number1 * this.number2;
 }
}</code></pre>
<h4 id="model-soulution">Model Soulution</h4>
<pre><code class="language-js">class MyMath { 
  constructor(a, b) {
      this.num1 = a;
      this.num2 = b;
}
  getNumber(){
      return [this.num1, this.num2];  
}
  add(){
    return this.num1 + this.num2;
}
  substract() {
    return this.num1 - this.num2;
}
  multiply(){
    return this.num1 * this.num2;
 }
}</code></pre>
<p>내가 작성한 코드와 비교해보면 간단한 변수명과 배열로 반환하는 메서드를 굳이 빈배열을 만들어서 push로 넣는 것이 아닌 배열로 바로 리턴하는 것이다. 줄일 수 있는 코드는 줄이고 변수명도 적합하게 바꾸는 <code>refactoring</code> 습관을 가져야 겠다.</p>
<h4 id="오늘의-한줄-✏️">오늘의 한줄 ✏️</h4>
<p><img src="https://images.velog.io/images/park_kyo_su/post/66a45879-1e2b-4ea4-ac4c-6a28c2943f07/4489176_1_16056878693691640.gif" alt="">
리액트를 처음 배우면서 솔직히 말하면 멘붕이였다. 🤦‍♂️ 
뭔가 머릿속이 뒤죽박죽이랄까, &quot;이게 뭐지&quot;라는 생각과 함께 
억지로 이해하는 나의 모습을 보고 객체지향 파트를 
다시 복습하기로 마음을 먹었다. </p>
<p>어차피 리액트 또한 하나의 자바스크립트 라이브러리이니까 
실습을 하면서 틈틈이 이해를 해야겠다.</p>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Classes">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Classes</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 14 - HTTP]]></title>
            <link>https://velog.io/@park_kyo_su/TIL-14-HTTP</link>
            <guid>https://velog.io/@park_kyo_su/TIL-14-HTTP</guid>
            <pubDate>Thu, 17 Jun 2021 06:18:50 GMT</pubDate>
            <description><![CDATA[<h2 id="http">HTTP</h2>
<p>HTTP(HyperText Transfer Protocol)</p>
<h4 id="hypertext">HyperText</h4>
<p>문서와 문서가 링크로 연결되어 있음을 뜻함</p>
<h4 id="transfer">Transfer</h4>
<p>HTML로 만든 웹페이지 문서(파일)을 보낸다</p>
<h4 id="protocol">Protocol</h4>
<p>컴퓨터끼리 어떻게 HTML 파일을 주고 받을 지에 대한 소통 방식 또는 약속</p>
<ol>
<li><p>Request(client, front-end)/Response(server, back-end) (요청/응답)
인간이 서로 소통하듯이 말이 아닌 메세지의 형식으로 서버와 요청하고 응답한다.</p>
</li>
<li><p>Stateless
HTTP 개별 통신은 모두 독립이어서, 과거의 HTTP 통신 결과(상태)를 보존하지 않는다.
State(상태) + less(없음)
매 통신마다 사전에 필요한 모든 정보를 담아서 요청을 보내야 한다.</p>
</li>
</ol>
<h3 id="http-request-method">HTTP request method</h3>
<h4 id="get">Get</h4>
<p>데이터를 받아오기만 할 때 사용
웹페이제 접속해서 필요한 데이터를 불러올 때 사용</p>
<h4 id="post">Post</h4>
<p>데이터를 생성/수정할 때 사용
Body에 담는 내용이 핵심</p>
<h4 id="delete">Delete</h4>
<p>서버에 저장된 특정 데이터를 삭제할 때 사용
Body에 값을 담지 않는다.</p>
<blockquote>
<p>Success
200:ok
201:created</p>
</blockquote>
<blockquote>
<p>error(front-end)
400:bad request
401:unauthorized
403:forbidden
404:not found</p>
</blockquote>
<blockquote>
<p>server error(back-end)
500:internal server error</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 13 - Git & GitHub]]></title>
            <link>https://velog.io/@park_kyo_su/TIL-13-JavaScript-Git-GitHub</link>
            <guid>https://velog.io/@park_kyo_su/TIL-13-JavaScript-Git-GitHub</guid>
            <pubDate>Wed, 16 Jun 2021 06:40:46 GMT</pubDate>
            <description><![CDATA[<h2 id="1-git--분산-버전-관리-시스템-vcs-👨👩👧👦">1. Git = 분산 버전 관리 시스템 (VCS) 👨‍👩‍👧‍👦</h2>
<p>Git은 프로젝트 파일의 변경 사항을 추적하는 시스템입니다.
이를 통해 개발자들은 프로젝트 변경 사항 기록 및 특정 시점의 버전으로 돌아갈 수 있습니다.</p>
<p><strong><u>Git을 통해 여러 사람들이 효율적으로 작업하고, 프로젝트를 중심으로 협업할 수 있다.</u></strong></p>
<p>쉽게 말해, 프로젝트 파일의 <strong>변경 사항을 추적하는 시스템</strong>입니다. 이를 통해 개발자들은 프로젝트의 변경 사항을 기록하고, 특정 시점의 버전으로 언제든 돌아갈 수 있습니다. 이런 버전 관리 시스템은 많은 사람들이 효율적으로 함께 작업하고, 프로젝트를 중심으로 협업할 때 사용할 수 있습니다. 어느 환경에서도 개발을 하게 해줄 수 있는 도구이기도 합니다.</p>
<p>각 개발자가 자신만의 프로젝트 버전을 본인 컴퓨터에 갖게됩니다. 나중에 이러한 개별 버전의 프로젝트를 병합하여 기준이 되는 버전의 프로젝트에 적용 할 수 있게 됩니다.</p>
<p>Git은 개인 혹은 팀 간의 프로젝트를 관리하는 데 가장 널리 사용되고 있는 툴입니다. 따라서 Git을 다룰 줄 아는 것은 요즘 모든 개발자들에게 <strong>가장 중요한 기술</strong> 중 하나입니다.</p>
<blockquote>
<p>Git 공식 홈페이지: <a href="https://git-scm.com/">https://git-scm.com/</a></p>
</blockquote>
<p><strong>Git 코드 버전 관리를 하는 이유</strong></p>
<ol>
<li>수정할 때 마다 파일을 새로 만들면 관리가 어렵기 때문</li>
<li>언제든 이전 버전의 코드로 돌아갈 수 있기 때문</li>
<li>이력을 남기기 위해</li>
<li>하나의 프로젝트를 두고 여러 개발자가 협업할 수 있기 때문</li>
</ol>
<h2 id="2-github-🗂">2. GitHub 🗂</h2>
<p><strong>GitHub</strong></p>
<ol>
<li>Git을 사용한 프로젝트들의 저장소</li>
<li>개발자들의 Social Network</li>
</ol>
<p><strong>2-1. 기본 명령어</strong></p>
<ol>
<li>git 시작 : git inint (<u>안쪽에서</u> init해야함/해당 폴도 내부안에서/녹화 개념과 비슷하다)</li>
<li>git 상태 확인 : git status (어떤 변경사항들이 있는지-임시 상태)</li>
<li>파일 수정 이력 기록 준비 : git add (쇼핑몰 장바구니?같은 느낌적인 느낌🤷)</li>
<li>파일 수정 이력 기록 : git commit (commit 하나 하나가 버전이라 생각하면 됨/구매확정같은 느낌적인 느낌🤷)</li>
<li>commit 이력 보기 : git log (coommit들의 이력들을 모아 봄/구매 이력같은 느낌적인 느낌🤷)</li>
</ol>
<p><strong>2-2. git Push 순서</strong></p>
<ol>
<li><p>파일이 있는 폴더로 이동 <code>cd Desktop/파일명</code></p>
</li>
<li><p>폴더안에 <code>git_pratice</code>폴더 생성</p>
</li>
<li><p>Git 시작 <code>git init</code></p>
<ul>
<li><code>git_pratice</code>폴더 진입 후 (<code>cd git_pratice</code>)<ul>
<li><code>.git</code>폴더 확인 (<code>ls -al</code>)</li>
</ul>
</li>
</ul>
</li>
<li><p><code>작업.md</code> 파일 생성</p>
</li>
<li><p>해당 파일에서 본인 이름 작성 후 저장</p>
<ul>
<li>vi junghoon.md</li>
<li>insert 모드 전환 후 내용 작성 및 저장</li>
<li>선택사항) git 상태 확인 : `git status``</li>
</ul>
</li>
<li><p>Staging(중간 저장) : <code>git add .</code></p>
<ul>
<li>Optional) git 상태 확인 : <code>git status</code></li>
</ul>
</li>
<li><p>Commit : <code>git commit -m &quot;메세지&quot;</code></p>
<ul>
<li>Optional) git 상태 확인 : <code>git status</code></li>
</ul>
</li>
<li><p>Commit history 확인 : <code>git log</code></p>
</li>
<li><p>Github repo 생성</p>
<ul>
<li>github 사이트 → New repository</li>
</ul>
</li>
<li><p><code>git_practice</code> 폴더와 github repository 연동 
  : <code>git remote add origin repository주소</code></p>
</li>
<li><p>git push : <code>git push origin main</code></p>
</li>
</ol>
<p><strong>나중에 이미 md 파일 지정되어 있을때 순서</strong>
1 -&gt; 3 -&gt; 7 -&gt; 8 -&gt; 9 -&gt; 10(이미 있으면 스킵) -&gt; 11 &gt; 12</p>
<blockquote>
<p>브랜치는 feature(기능)별로 딴다. ex)git branch feature/login</p>
<blockquote>
<p>처음 브랜치를 만들기 전에 최신화된 코드에서 브랜치를 만드는 것이 맞다.
즉, 먼저 (처음 작업을 시작할때) main에서 최신화된 코드를 clone 하고 브랜치를 만드는 습관.</p>
</blockquote>
</blockquote>
<p><strong>Branch 생성 순서</strong></p>
<ol>
<li>git branch</li>
<li>git branch feature/README</li>
<li>git checkout feature/README</li>
<li>git add . </li>
<li>git commit -m “Add: 메시지”</li>
<li>git push origin feature/이름</li>
</ol>
<p><strong>Conflict 해결 과정</strong></p>
<ol>
<li>git checkout master</li>
<li>git pull origin master</li>
<li>git checkout feature/branch</li>
<li>git merge master</li>
<li>충돌 해결</li>
<li>git add .</li>
<li>git commit</li>
<li>git push</li>
</ol>
<h4 id="오늘의-한줄-✏️">오늘의 한줄 ✏️</h4>
<p>사실 Git에 대해 세션을 듣고 공부를 하면서 너무 어려운 것 같이 느껴지기도 했다. 뭔가 굳이 저렇게 관리를 해야하나? 아마 이러한 생각이 과거에 나의 <code>다음에 써야지</code>라는 습관에서 비롯된 것이다.
<img src="https://images.velog.io/images/park_kyo_su/post/c9f871c3-1b9a-473f-814d-176c0267b559/bcfdd95ed00841f99433cfa08ae0a33d_1565669761.gif" alt="">
앞으로 개발자로써 일을 하기 위해 이런 습관과 이별하고 Git과 친해져야겠다. 
그럼 이만 github에 push해서 나도 잔디밭을 가꾸러🌳</p>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Learn/Tools_and_testing/GitHub">https://developer.mozilla.org/ko/docs/Learn/Tools_and_testing/GitHub</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 12 - JavaScript - DOM & Event]]></title>
            <link>https://velog.io/@park_kyo_su/TIL-12-JavaScript-DOM</link>
            <guid>https://velog.io/@park_kyo_su/TIL-12-JavaScript-DOM</guid>
            <pubDate>Wed, 16 Jun 2021 04:45:10 GMT</pubDate>
            <description><![CDATA[<h2 id="dom이란🧐">DOM이란?🧐</h2>
<p><a href="https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model/Introduction">MDN</a>에서 말하는 <strong>DOM(Document Object Model)</strong>의 정의는 다음과 같다.</p>
<blockquote>
<p>The Document Object Model (DOM) is a programming interface for HTML.
DOM은 HTML 문서를 위한 프로그래밍 인터페이스이다.</p>
</blockquote>
<p>쉽게 말하면 여러 소프트웨어 간의 교류를 가능하게 해주는 표면 같은 존재이다.</p>
<p>예시를 들면 이해하기가 쉽다. </p>
<p>TV를 보고 있을때 리모콘의 다양한 종류의 버튼들을 통해 TV와 교류(채녈 이동) 한다. 이러한 상황에서 <u>리모콘의 버튼들이 프로그래밍 인터페이스와</u> 같은 역할이고, 이러한 <u>인터페이스를 이용하여 TV를 컨트롤 할 수 있다.</u></p>
<pre><code class="language-js">let blueElement = document.querySelector(&#39;.blue&#39;);
blueElement.style.backgroundColor = &#39;blue&#39;;</code></pre>
<p>위와 같이 <code>.blue</code>라는 클래스를 가진 요소를 선택하여 해당 요소의 스타일을 수정하였다. 
즉, <strong>DOM이라는 프로그래밍 인터페이스를 사용하여 자바스크립트가 HTML 문서를 조정하는 것이다.</strong></p>
<p>여기서 주의해야 할 사항은 자바스크립트로 화면을 수정한다고 해서 내가 작업하는 HTML 문서(ex.<code>index.html</code>) 자체가 수정되는 것은 아니다.</p>
<h3 id="1-요소-선택하는-방법-🤏">1. 요소 선택하는 방법 🤏</h3>
<p><strong>1. 아이디 이름을 이용하여 선택 by.<code>document.getElementById</code></strong>
    - <code>document.getElementById</code>를 이용하여 요소를 선택할 경우 주어지는 값은 하나이다.
    - tip.여기서 Id는 페이지당 1개만 존재하므로 element</p>
<pre><code class="language-js">// start-button 아이디를 가진 요소를 선택하여 `$sb` 변수에 대입
const $sb = document.getElementById(&quot;start-button&quot;);

// special-button 아이디를 가진 요소의 텍스트 변경
$sb.textContent = &quot;Engine Start&quot;;
</code></pre>
<p><strong>2. 클래스 이름을 이용하여 선택 by.<code>getElementsByClassName</code></strong>
    - <code>getElementsByClassName</code>의 결과값은 배열과 유사한 형태(유사 배열)이다. 그렇기 때문에 대부분의 상황에서 배열의 <code>index</code>위치를 사용해야 한다.
    - HTML 상에서 해당 클래스를 가진 요소가 하나 뿐이라도, <strong><u><code>getElementsByClassName</code>의 결과값은 배열과 유사한 형태이므로 인덱스를 사용하여 접근한다.</u></strong>
    - tip.class는 한페이지에 여러개가 존재할 수 있으므로 elements =&gt; 배열 or 유사 배열</p>
<pre><code class="language-js">// letItGo 클래스를 가진 &quot;모든 요소들&quot;을 선택하여 `$container` 변수에 대입
const $letItGo = document.getElementsByClassName(&quot;letItGo&quot;);

// HTML 상에서 해당 클래스를 가진 요소가 단 하나 뿐이더라도,
// getElementsByClassName의 결과값은 배열과 유사한 형태이므로 인덱스로 접근하여 사용한다.
$letItGo[0].style.backgroundColor = &quot;green&quot;;</code></pre>
<p><strong>3. 태그 이름을 이용하여 선택 by.<code>getElementsByTagName</code></strong>
    - 특정 태그를 사용한 요소들을 선택
    - <code>getElementsByClassName</code>과 <code>getElementsByTagName</code>는 결과값이 대부분 동일한 형태(HTML Element가 담긴 유사 배열)이다.</p>
<p><strong>4. CSS선택자를 이용하여 선택 by.<code>querySelector</code></strong>
    - CSS 선택자 문법을 이용해야한다. (실수 조심!)
    - <code>querySelector</code>라는 함수는 모든 경우에 &quot;하나의 요소&quot;를 반환한다.
    - <code>querySelector</code> 함수의 CSS 선택자와 일치하는 요소가 여러 개일 경우, 가장 첫번째 요소를 반환한다.
    - <code>querySelectorAll</code>함수의 CSS 선택자와 일치하는 &quot;모든 요소들&quot;을 유사 배열의 형태로 반환한다.(<code>getElementsByClassName</code>처럼 요소를 제어하고 싶다면 <u><code>index</code>위치를 사용해야 한다.</u>)</p>
<pre><code class="language-js">const $container = document.querySelector(&quot;#container&quot;);
const $listName = document.querySelector(&quot;.name&quot;);
const $paragraphs = document.querySelectorAll(&quot;p&quot;);</code></pre>
<h3 id="2-요소-다루기">2. 요소 다루기</h3>
<p>DOM을 이용하면 선택한 요소들을 수정하거나 삭제할 수 있다.</p>
<pre><code class="language-js">const $article = document.querySelector(&quot;.meet&quot;);
$article.textContent = &quot;Hello!&quot;;</code></pre>
<p>HTML요소를 모두다 암기할려고 하지 말고 정확한 검색을 해서 이용하자!
검색어 : <code>자바스크립트 HTML 요소 텍스트 수정</code>등의 키워드</p>
<p><strong>자주 사용하는 속성</strong></p>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/API/ParentNode/children">Element.children</a></li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/API/Element/classList">Element.classList</a></li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/API/Element/innerHTML">Element.innerHTML</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/ElementCSSInlineStyle/style">Element.style</a></li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/API/ChildNode/remove">Element.remove</a></li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/API/Node/appendChild"> Element.appendChild</a></li>
</ul>
<h3 id="3-요소-만들기">3. 요소 만들기</h3>
<pre><code class="language-js">const secondHead = document.createElement(&quot;h2&quot;); // h2 요소를 만들어서 &quot;scondHead&quot;라는 변수에 할당
secondHead.textContent = &quot;소제목&quot;; // h2 요소 텍스트 설정
secondHead.fontSize = &quot;45px&quot;;     // h2 요소 스타일 설정
document.body.appendChild(secondHead); // h2 요소 body 태그의 자식으로 추가</code></pre>
<p>수정과 삭제가 가능하듯, 만들기도 가능하다.</p>
<h3 id="4-event">4. event</h3>
<p>&quot;event&quot;란 웹에서 발생하는 사건들을 일컫는 단어이다. ex)화면 클릭, 마우스 드래그, 윈도우 사이즈 조절..
이벤트의 종류는 굉장히 많다. 암기보다 많이 사용하면서 익숙해지자!</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Events">Event reference</a><pre><code class="language-html">&lt;div&gt;
&lt;p&gt;퀴즈를 다시 풀고 싶으시면 아래 버튼을 누르세요!&lt;/p&gt;
&lt;button&gt;시작!&lt;/button&gt;
&lt;/div&gt;</code></pre>
<pre><code class="language-js">const reStartBtn = document.querySelector(&quot;button&quot;);
</code></pre>
</li>
</ul>
<p>reStartBtm.addEventListener(&quot;click&quot;, function onButtonClick () {
    alert(&quot;퀴즈 시작합니다!&quot;);
}</p>
<p>```</p>
<br>

<h4 id="오늘의-한줄-✏️">오늘의 한줄 ✏️</h4>
<p><img src="https://images.velog.io/images/park_kyo_su/post/7ae39c58-095e-4f2a-b3c7-706751d98b1a/4164335_1582361978747.gif" alt="">
로그인 페이지 구현을 하다가 DOM과 event가 동작으로는 
이해를 하는데 개념적으로는 두루뭉실하여 부족하지만
복습용으로 정리를 해봤다. 뭔가 앞으로 벨로그 손님이 될것만 같다.🤷
단순히 빨리 진도를 나가는 것보다 내가 설명할 수 있도록 이해를 해야겠다.</p>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://developer.mozilla.org/ko/">https://developer.mozilla.org/ko/</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>