<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>gonkang_jeondosa.log</title>
        <link>https://velog.io/</link>
        <description>실수는 삶과 정신의 여백입니다. 여백이 많은 츄러블슈팅 맛집</description>
        <lastBuildDate>Sun, 26 Nov 2023 09:15:45 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>gonkang_jeondosa.log</title>
            <url>https://images.velog.io/images/gonkang_jeondosa/profile/fc109526-46c8-4602-88b7-642f87d47a9a/20191006_234915.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. gonkang_jeondosa.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/gonkang_jeondosa" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[개발보다는 컨설팅/설계를 메인으로 합니다]]></title>
            <link>https://velog.io/@gonkang_jeondosa/%EA%B0%9C%EB%B0%9C%EB%B3%B4%EB%8B%A4%EB%8A%94-%EC%BB%A8%EC%84%A4%ED%8C%85%EC%84%A4%EA%B3%84%EB%A5%BC-%EB%A9%94%EC%9D%B8%EC%9C%BC%EB%A1%9C-%ED%95%A9%EB%8B%88%EB%8B%A4</link>
            <guid>https://velog.io/@gonkang_jeondosa/%EA%B0%9C%EB%B0%9C%EB%B3%B4%EB%8B%A4%EB%8A%94-%EC%BB%A8%EC%84%A4%ED%8C%85%EC%84%A4%EA%B3%84%EB%A5%BC-%EB%A9%94%EC%9D%B8%EC%9C%BC%EB%A1%9C-%ED%95%A9%EB%8B%88%EB%8B%A4</guid>
            <pubDate>Sun, 26 Nov 2023 09:15:45 GMT</pubDate>
            <description><![CDATA[<p>개발은 더 잘하는 두 분에게 위임하고 있습니다
외국분들이신데 한국인도 제법 잘하십니다.
두 분의 작업스타일이 상당히 퀵하고 피드백이 빠른 까닭에, 비교적 애자일한 저희 팀 방향성과 잘맞아 1년째 같이 작업하고 있습니다.</p>
<p>Goh pilot - 주로 비주얼 스튜디오에 상주하십니다
Chasey Pity - 작성한 코드를 검수해주시는 분입니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]DOM과 바벨]]></title>
            <link>https://velog.io/@gonkang_jeondosa/TILDOM%EA%B3%BC-%EB%B0%94%EB%B2%A8</link>
            <guid>https://velog.io/@gonkang_jeondosa/TILDOM%EA%B3%BC-%EB%B0%94%EB%B2%A8</guid>
            <pubDate>Sun, 17 Jul 2022 12:58:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/04729fa6-7f7f-43a5-8f21-31f1733d4c73/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/4bf69b88-d16d-4448-9ba6-2bce6c9a2dda/image.png" alt=""></p>
<p>Paint라는 함수는 이하 태그를 리턴한다.
이 때 반드시 함수명의 첫 글자는 대문자로 입력한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[왜 GraphQL을 사용하나요?]]></title>
            <link>https://velog.io/@gonkang_jeondosa/%EC%99%9C-GraphQL%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EB%82%98%EC%9A%94</link>
            <guid>https://velog.io/@gonkang_jeondosa/%EC%99%9C-GraphQL%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EB%82%98%EC%9A%94</guid>
            <pubDate>Mon, 20 Jun 2022 11:37:34 GMT</pubDate>
            <description><![CDATA[<h2 id="1-기존-rest-api의-문제점">1. 기존 Rest API의 문제점</h2>
<h3 id="1-overfetching">1) OverFetching</h3>
<ul>
<li><p>RestAPI에서는 해당 URL의 모든 데이터를 받아야해요. 나는 다 필요 없는데요 !!!!! 뿌에에엥</p>
</li>
<li><p>그러다보니 data전송도 느리고 리소스도 많이 잡아먹고 다매!!!!!!!</p>
</li>
</ul>
<h3 id="2-underfetching">2) UnderFetching</h3>
<ul>
<li>URL에 원하는 정보가 없으면 다른 URL을 또 찔러야해요</li>
<li>하나의 정보를 얻기 위해 복수의 request는 다매요!!!!</li>
</ul>
<h2 id="2-graphql은-달라요">2. GraphQL은 달라요</h2>
<ul>
<li>필요한 정보만 1번의 request로 받아요.
=&gt;더 빨라요</li>
<li>실습실 : <a href="https://graphql.org/swapi-graphql">https://graphql.org/swapi-graphql</a>?</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Next.js]왜 써요? 어떻게 써요?]]></title>
            <link>https://velog.io/@gonkang_jeondosa/Next.js%EC%99%9C-%EC%8D%A8%EC%9A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%8D%A8%EC%9A%94</link>
            <guid>https://velog.io/@gonkang_jeondosa/Next.js%EC%99%9C-%EC%8D%A8%EC%9A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%8D%A8%EC%9A%94</guid>
            <pubDate>Tue, 03 May 2022 07:34:26 GMT</pubDate>
            <description><![CDATA[<h2 id="nextjs를-왜-써요">Next.js를 왜 써요?</h2>
<h3 id="1-라이브러리-vs-프레임워크">1) 라이브러리 vs 프레임워크</h3>
<ul>
<li>리액트 라이브러리(Create-react-app)로 작업시에는 Routes, Render 등등 작업을 해줘야 됨.</li>
<li>Next 프레임워크(npm install next@latest)는 <code>pages</code>폴더에 원하는 js문서를 만들어주면 됨. 앞서 리액트 라이브러리에서 해주던 세팅들이 추상화된것. </li>
<li>Next의 rule에 따라 페이지를 생성하기만 하면되어 간편.</li>
<li>이 때 js문서의 function 이름은 리액트와 달리 뭘 해도 상관 없음. js문서의 이름이 곧 url에 표시될 경로.<blockquote>
<p>pages rules
<code>export default function 함수명</code>을 js문서 앞단에 꼭 넣어줄 것
js문서의 이름은 url의 이름이 된다.
앱의 홈은 index.js에서 나온다
jsx문서가 아니더라도 return이하에 html 요소 활용 가능</p>
</blockquote>
</li>
</ul>
<h3 id="2-client-side-render-vs-server-side-render">2) Client Side Render vs Server Side Render</h3>
<ul>
<li><p>기존 리액트의경우, user의 브라우저는 javascript, react를 받아 천천히 HTML로 렌더링하기 시작함. 느린 인터넷 환경에서는 흰 화면부터 천천히 나타나게됨.</p>
</li>
<li><p>Next의 경우, 서버에서 미리 렌더링 후 HTML을 짜놓고 user에게 바로 보여준다. SEO에도 좋고, user는 미리 만들어진 HTML을 미리 보고있다가 추후에 연결된 react앱을 활용할 수 있어 사용성도 좋아짐.</p>
</li>
</ul>
<h2 id="2사용가이드">2.사용가이드</h2>
<h3 id="1routing">1)Routing</h3>
<ul>
<li><code>&lt;a&gt;</code>태그 대신 <code>&lt;Link&gt;</code>를 사용합시다</li>
<li><code>&lt;useLocation&gt;</code> 대신 <code>&lt;useRouter&gt;</code>활용해서 화면정보 가져오기, 화면 이동 모두 가능합니다 </li>
</ul>
<h3 id="2css-활용패턴1-modulecss-확용하기">2)CSS 활용패턴1 :.module.css 확용하기</h3>
<ul>
<li><p><code>임의지정이름.module.css</code>라는 css파일을 만들고 스타일을 작성합니다</p>
<pre><code>style01{
   background-color : blue;
}

style02{
   background-color : red;
}</code></pre></li>
<li><p>적용하려는 js파일에서는 아래와 같은 형식으로 적용합니다.</p>
<pre><code>  import sytles from &quot;./임의지정이름.module.css&quot;;</code></pre><p>먼저 상단에서 import해주시고</p>
<pre><code>&lt;div className={styles.style01}&gt;</code></pre><p>통상의 className=&quot;XXX&quot;이 아니라 위와같이 해주셔야해요</p>
</li>
</ul>
<h3 id="3css활용패턴2--styled-jsx-only-with-next-js">3)CSS활용패턴2 : styled jsx (only with NEXT js)</h3>
<pre><code>      &lt;Link href=&#39;/about&#39;&gt;
        &lt;div className={router.pathname === &#39;/about&#39; ? &#39;active&#39; : &#39;inactive&#39;}&gt;
          About
        &lt;/div&gt;
      &lt;/Link&gt;


      &lt;style jsx&gt;{`
        nav {
          display: flex;
          justify-content: space-between;
          background-color: gray;
        }
        .active {
          color: white;
        }
        .inactive {
          color: black;
        }
      `}&lt;/style&gt;</code></pre><p><code>&lt;style jsx&gt;</code>내에 중괄호&amp;백틱으로 감싼 css를 적용하여 해당 문서내의 스타일을 간편하게 바꿀 수 있음</p>
<p><code>&lt;style jsx global&gt;</code>이라고 표시하면 전역에서 활용가능한 스타일이 됨.</p>
<h3 id="3-_appjs-활용하기-언더바는-의무인가요">3) &quot;_app.js&quot; 활용하기 (언더바는 의무인가요?)</h3>
<p>네 의무입니다. 정식 명칭은 App Component지요. 딱 저이름을 쓰기로 우리모두 약속했어요. Next JS는 <code>_app.js</code>를 먼저 확인한 후에 다른 것들을 렌더링할겁니다..</p>
<p>기본적으로 아래의 것들이 먼저 들어가야하고</p>
<pre><code>export default function 앱이름({Component, pageProps}) {
  return (
      &lt;&gt;
        &lt;Component {...pageProps}&gt;
      &lt;/&gt;
  )
}</code></pre><p>그 윗단에서, 전역에서 사용할 라이브러리, global.css 등등을 import해줍니다.
return 이하에서는 전역에서 사용할 <code>&lt;style jsx global&gt;</code> 등도 선언해주고 nav도 넣고 다 넣어서 탬플릿처럼 사용가능합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Redux]알아보자]]></title>
            <link>https://velog.io/@gonkang_jeondosa/Redux%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@gonkang_jeondosa/Redux%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Tue, 26 Apr 2022 05:24:13 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p> Redux에서 제공하는 공식도구인 Redux Toolkit을 쓰세요.(RTK)</p>
</blockquote>
<h2 id="1-키워드">1. 키워드</h2>
<h4 id="1액션">1)액션</h4>
<p>: 상태변화가 필요할 때 발생시키는 객체</p>
<pre><code>{
    type:&quot;ADD_TODO&quot;
    data:{
        id:0,
        text:&quot;리덕스 배우기&quot;
           }
}</code></pre><h4 id="2액션-생성함수">2)액션 생성함수</h4>
<p>: 파라미터를 받아, 액션객체를 만드는 함수</p>
<pre><code>export const changeInput = text=&gt;({
    type:&quot;CHANGE_INPUT&quot;,
    text
    });</code></pre><ul>
<li>컴포넌트에서 액션 쉽게 발생시키기 위해 액션 생성함수 만듬 - <code>export</code>를 붙여 다른 파일에서도 불러올 수 있음</li>
</ul>
<h4 id="3reducer">3)Reducer</h4>
<p>:변화를 일으키는 함수. <code>state</code>, <code>action</code> 두 가지 파라미터 받아, 새로운 <code>state</code>를 반환함.</p>
<h4 id="4store">4)Store</h4>
<p>: 현재 앱의 <code>state</code>, <code>reducer</code>, <code>내장함수</code>가 들어있음. 한 애플리케이션에 하나의 스토어 보유</p>
<h4 id="5store의-주요-내장함수">5)Store의 주요 내장함수</h4>
<ul>
<li><p>dispatch : <code>dispatch(action)</code>형식으로, 해당 액션을 발생시킴.  <code>store</code>는 리듀서 함수 실행시켜 해당 액션 처리하는 로직과 <code>action</code>을 참고하여 새로운 <code>state</code>만들어줌</p>
</li>
<li><p>subscribe : <code>action</code>이 <code>dispatch</code>될 때마다 전달해준 함수 호출. 보통 사용할일 없고, <code>connect</code>함수나 <code>useSelector Hook</code>이용하여 리덕스 <code>store</code>의 상태 구독함.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[기업협업]새로 접한 스택들로 인한 부트캠프 수료생의 고뇌]]></title>
            <link>https://velog.io/@gonkang_jeondosa/%EA%B8%B0%EC%97%85%ED%98%91%EC%97%85%EC%83%88%EB%A1%9C-%EC%A0%91%ED%95%9C-%EC%8A%A4%ED%83%9D%EB%93%A4%EB%A1%9C-%EC%9D%B8%ED%95%9C-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%EC%88%98%EB%A3%8C%EC%83%9D%EC%9D%98-%EA%B3%A0%EB%87%8C</link>
            <guid>https://velog.io/@gonkang_jeondosa/%EA%B8%B0%EC%97%85%ED%98%91%EC%97%85%EC%83%88%EB%A1%9C-%EC%A0%91%ED%95%9C-%EC%8A%A4%ED%83%9D%EB%93%A4%EB%A1%9C-%EC%9D%B8%ED%95%9C-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%EC%88%98%EB%A3%8C%EC%83%9D%EC%9D%98-%EA%B3%A0%EB%87%8C</guid>
            <pubDate>Mon, 25 Apr 2022 17:15:33 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/13c49bc2-3da7-42ce-9103-2a6878e86760/image.png" alt=""></p>
<h2 id="1-부트캠프시절">1. 부트캠프시절</h2>
<ul>
<li>create-react-app하시고, package.json, gitignore 기타등등빼고는 싹 지워주실게요~</li>
<li></li>
</ul>
<h2 id="2-now">2. Now</h2>
<blockquote>
<p>뭐야 이 생소한 것들은... 일단 하나씩 구글링해보자</p>
</blockquote>
<h3 id="1보일러플레이트">1)보일러플레이트</h3>
<p>: 자주쓰는 초기세팅 템플릿</p>
<h3 id="2husky">2)husky</h3>
<p>: 개이름. git hooks를 관리. git 상태가 변화할때 자동실행되는 스크립트가 git hooks. 사용하는 이유는 모름.</p>
<h3 id="3nextjs-next-envdts-nextconfigjs">3)Next.js (next-env.d.ts, next.config.js)</h3>
<p>: 클라이언트가 아니고 서버사이드 렌더링 / SEO때문에 사용</p>
<h3 id="4vercel">4)vercel</h3>
<p>: Next.js랑 같은회사인데 배포할때 쓰는 듯</p>
<h3 id="5typescript-tsconfigjson">5)typescript (tsconfig.json)</h3>
<p>: 자바스크립트에 자료형 들어가고, private / public 등 상태값 들어가고.. class로 객체지향 가능케하고</p>
<h3 id="6appdts">6)app.d.ts</h3>
<p>:모름</p>
<h3 id="7changelogconfig">7)changelog.config</h3>
<p>:커밋관련 약속인듯 추정</p>
<h3 id="8jest-jestconfigjs--jestsetupts">8)jest (jest.config.js / jest.setup.ts)</h3>
<p>:코드 테스트 관련 프렘워크라는데, 공식문서 읽어봐야할듯</p>
<h3 id="9webpack">9)webpack</h3>
<p>: 모름</p>
<h3 id="10바벨">10)바벨</h3>
<p>:모름. 아령은 아님</p>
<h3 id="11yarnlock">11)yarn.lock</h3>
<p>:모름</p>
<h3 id="12차크라">12)차크라</h3>
<p>:나루토와는 무관해보임</p>
<blockquote>
<p>읽어야될 공식문서가 산더미...ㅎㅎㅎㅎㅎㅎ</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[map]써도써도 까먹는 map 실수리스트 정리]]></title>
            <link>https://velog.io/@gonkang_jeondosa/map%EC%8D%A8%EB%8F%84%EC%8D%A8%EB%8F%84-%EA%B9%8C%EB%A8%B9%EB%8A%94-map-%EC%8B%A4%EC%88%98%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@gonkang_jeondosa/map%EC%8D%A8%EB%8F%84%EC%8D%A8%EB%8F%84-%EA%B9%8C%EB%A8%B9%EB%8A%94-map-%EC%8B%A4%EC%88%98%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 13 Apr 2022 17:25:17 GMT</pubDate>
            <description><![CDATA[<p>Back to the basic!</p>
<h1 id="1-map-is-not-a-function">1. *.map is not a function</h1>
<p>map을 돌리는 대상이 배열의 형태가 아니다.
혹시 아래과 같은 객체를 놓고 씨름하고 있었다면</p>
<pre><code>{
    id : jaySur,
    name: jayYoon,
}</code></pre><p>배열의 형태로 바꿔줍시다...</p>
<h1 id="2encountered-two-children-with-the-same-key">2.encountered two children with the same key</h1>
<p>key 설정을 동일한 값으로 돌리셨군요..
key는 unique한 값으로 꼭 세팅해주셔야합니다.
객체의 id가 있으면 id를 쓰셔도 좋고
없으면 index로 만들어줍니다 </p>
<pre><code>{products.map((product, index)=&gt;(
    &lt;productFeature key={index} product={product} /&gt;
    ))}</code></pre><p>이 때, index와 props는 꼭 꼭 괄호로 묶어줍시다..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Custom Hooks 개요]]></title>
            <link>https://velog.io/@gonkang_jeondosa/Custom-Hooks-%EA%B0%9C%EC%9A%94</link>
            <guid>https://velog.io/@gonkang_jeondosa/Custom-Hooks-%EA%B0%9C%EC%9A%94</guid>
            <pubDate>Wed, 13 Apr 2022 02:42:54 GMT</pubDate>
            <description><![CDATA[<h1 id="1-관심사의-분리socseparation-of-concerns">1. 관심사의 분리(SOC:Separation Of Concerns)</h1>
<blockquote>
<p>ASIS : ID &amp; PWD 유효성검사 후 버튼색 변경하는 함수
TOBE : ID유효성 함수 , PWD유효성 함수, 버튼색 변경 함수로 분리</p>
</blockquote>
<h2 id="1목적">1)목적</h2>
<ul>
<li><p>하나의 수정사항에는 해당 부분만 변경하기 위해, 단위를 잘게 나눔 
=&gt;<code>Divide &amp; Conquer</code>를 용이하게 함.</p>
</li>
<li><p><code>Loose Coupling</code> : 낮은 결합도. 독립적으로 분리됨</p>
</li>
<li><p><code>High Cohesive</code> : 높은 응집도. 유사한 내용은 비슷한 위치에 모아두기.
=&gt; 파일경로 직관적으로 설정</p>
</li>
</ul>
<h2 id="2장점">2)장점</h2>
<ul>
<li>코드 명료해짐</li>
<li>코드 재사용성 올라감</li>
<li>유지보수 용이함</li>
<li>테스트코드 작성 용이함</li>
</ul>
<h1 id="2-custom-hook">2. Custom Hook</h1>
<h2 id="1개요">1)개요</h2>
<ul>
<li>컴포넌트는 <code>로직</code> 과 <code>뷰</code>로 분리할 수 있다.</li>
<li>관심사 분리를 위한 <code>use</code>로 시작하는 리액트 함수.</li>
</ul>
<blockquote>
<p>ASIS
<img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/14f816de-a94d-4fa0-9229-63d90541a96b/image.png" alt=""></p>
</blockquote>
<p>user정보를 set하는 컴포넌트로, 로직과 뷰가 분리되어있지않다.</p>
<blockquote>
<p>TOBE
<img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/f2ed7953-6331-4cc0-b02b-fc8a8b929e24/image.png" alt="">
로직은 useGetUserList()한줄로 실행만하고 view에 집중
<img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/c5b2b310-c216-4750-bb19-b44d8d07a96d/image.png" alt="">
user정보 set하는 로직은 별도로 분리</p>
</blockquote>
<h2 id="2참고사항">2)참고사항</h2>
<ul>
<li>이름은 <code>use</code>로 시작할 것</li>
<li>Hook안에서Hook 호출 가능</li>
<li>src내부에 컨벤션으로 위치잡거나, 특정 기능에서 자주 사용되는 경우 해당 컴포넌트 옆에 js파일 생성</li>
</ul>
<h2 id="3실습">3)실습</h2>
<blockquote>
<p>ASIS<img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/9cd6f658-1ab9-4952-89be-4c169b573ca9/image.png" alt="">
TOBE (Custom Hooks)
<img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/07470a4a-96a4-4c0a-87c4-50dfa24b282e/image.png" alt=""></p>
</blockquote>
<blockquote>
<p>다른 컨포넌트에서 쓸 떄에는 해당 hooks을 import만 해주면 된다.
<img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/7af21112-681c-4a6d-b4be-eca68d2a954c/image.png" alt=""></p>
</blockquote>
<blockquote>
<p>-기타
<img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/9bfbbe67-cc94-424a-80c8-fa15bf41d221/image.png" alt="">객체로 리턴 vs 배열로 리턴 차이점
=&gt;배열로 리턴 : 이름을 조정하기 쉽다(useState같은 경우)
=&gt;객체로 리턴 : 이름이 픽스되어있음</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Infra] 가용성(Availibility)]]></title>
            <link>https://velog.io/@gonkang_jeondosa/Infra-%EA%B0%80%EC%9A%A9%EC%84%B1Availibility</link>
            <guid>https://velog.io/@gonkang_jeondosa/Infra-%EA%B0%80%EC%9A%A9%EC%84%B1Availibility</guid>
            <pubDate>Sun, 10 Apr 2022 10:41:41 GMT</pubDate>
            <description><![CDATA[<h2 id="1-가용성">1. 가용성</h2>
<ul>
<li>서버와 네트워크 등 시스템이 정상적으로 사용가능한 정도를 의미</li>
<li>고가용성이란 해당 시스템이 오랜기간동안 지속적으로 장애없이 정상운영이 가능하다는 성질을 의미한다.</li>
</ul>
<h2 id="2-five-nines">2. Five Nines</h2>
<ul>
<li>9가 5개라는 뜻으로 99.999%의 고가용성을 지닌다는 의미이다.</li>
</ul>
<h2 id="3-sla">3. SLA</h2>
<ul>
<li>Service Level Agreement의 양자</li>
<li>인프라 공급사가 이용자에게 어느 정도의 수준으로 서비스를 제시할 것이지를 정량적으로 명확히 제시하는 약정을 의미한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Infra]Scale up & Scale out]]></title>
            <link>https://velog.io/@gonkang_jeondosa/InfraScale-up-Scale-out</link>
            <guid>https://velog.io/@gonkang_jeondosa/InfraScale-up-Scale-out</guid>
            <pubDate>Sun, 10 Apr 2022 10:22:34 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/3fbda31c-fec4-4312-88ba-4f78ff66a72a/image.png" alt=""></p>
<ul>
<li><p>Scale out : 하나의 장비에서 처리하던 일을 여러 장비로 나눠 처리할 수 있도록 증량한다. 수평확장이라고도 한다.</p>
</li>
<li><p>Scale up : 더 빠른 속도의 CPU나 RAM을 추가하는 것. 일반적으로 Scale out보다 비용부담이 크다. 수직확장이라고도 한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[디즈니샵 프로젝트 후기]]></title>
            <link>https://velog.io/@gonkang_jeondosa/Clone-Coding%EB%94%94%EC%A6%88%EB%8B%88%EC%83%B5-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@gonkang_jeondosa/Clone-Coding%EB%94%94%EC%A6%88%EB%8B%88%EC%83%B5-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Sun, 10 Apr 2022 09:59:31 GMT</pubDate>
            <description><![CDATA[<h2 id="1-프로젝트-목적물-설정">1. 프로젝트 목적물 설정</h2>
<blockquote>
<p>디즈니샵
<a href="https://www.shopdisney.com/">https://www.shopdisney.com/</a>
제품 카테고리를 줄이고 기능적인 측면을 구현하는데에 집중하기로 하였으며, 자세한 내용은 하기와 같습니다.</p>
</blockquote>
<h4 id="1-구현-범위-설정">1) 구현 범위 설정</h4>
<ul>
<li><p>150여개 카테고리와 다양한 IP를 보유하고 있는 쇼핑몰 
=&gt; <code>7개 카테고리와 3개 브랜드로 축소 구현</code></p>
</li>
<li><p>랜딩페이지의 기획전을 비롯하여, 추천상품 등 제품 노출영역 
=&gt; <code>기획전 배너 2개, 추천상품 영역 1개</code></p>
</li>
<li><p>그 밖의 제품구매 프로세스는 전체 구현
=&gt; <code>제품탐색(필터링,검색) - 찜하기 - 장바구니 넣기 - 결제</code></p>
</li>
</ul>
<h2 id="2-프로젝트-관리">2. 프로젝트 관리</h2>
<h4 id="1일정관리">1)일정관리</h4>
<ul>
<li><p>의사결정록 notion 도입
<img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/92b2c26d-65f2-4fa3-b50a-54d2792b524b/image.png" alt=""></p>
<pre><code>  특정 안건 열람이 어려운 standing회의록의 단점 보완하고자 의사결정록 도입.
  이슈를 한눈에 열람하고 구성원간 공유 원활히 할 수 있도록 함.</code></pre></li>
</ul>
<ul>
<li>trello + BigPicture<pre><code>    트렐로 카드는 개별 업무단위를, BigPicture는 전체 진도율 관리.</code></pre></li>
</ul>
<h4 id="2업무-배분">2)업무 배분</h4>
<p>  <img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/0d0a0301-b980-4a1b-ab85-de2a795cb7fd/image.png" alt=""></p>
<pre><code>        크게 3가지 단위와 추가구현기능으로 업무를 나누었고, 
        붉은 테두리의 영역을 맡아 구현하기로 함.</code></pre><h4 id="3기타-담당-내역">3)기타 담당 내역</h4>
<ul>
<li>프로젝트 개시 직후, 상품이미지/브랜드/이벤트배너 등 쇼핑몰 전반에 표시될 상품데이터 제작하여 스프레드시트 형태로 Backend에 전달.
=&gt; <code>제품데이터를 사전에 픽스함으로써 기능의 범위가 명확해졌으며, Backend와의 소통 원활해짐. 아울러 프로젝트 막바지에 신경쓰기 어려운 이미지작업을 사전에 마쳐놓음으로써 팀원들이 개발에만 전념할 수 있는 환경 조성</code></li>
</ul>
<h2 id="3-프로젝트-개발">3. 프로젝트 개발</h2>
<blockquote>
<p>GIT : <a href="https://github.com/JaySurplusYoon/31-1st-kidsney-frontend">https://github.com/JaySurplusYoon/31-1st-kidsney-frontend</a></p>
</blockquote>
<h3 id="3-1-query-parameter활용한-제품탐색기능">3-1. Query Parameter활용한 제품탐색기능</h3>
<h4 id="1구현화면">1)구현화면</h4>
<p><img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/3eea78f7-fbc3-4543-88e8-38011b8e6ef3/image.gif" alt=""></p>
<h4 id="2구성도">2)구성도</h4>
<ul>
<li>제품탐색기능은 <code>필터</code>, <code>가격순정렬</code>, <code>검색</code>, <code>페이지네이션</code> 4가지로 구분.
<img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/19eee4ca-b123-480b-a51d-b5ee4a982a7d/image.png" alt=""></li>
</ul>
<h4 id="3구현특징">3)구현특징</h4>
<ul>
<li>디즈니샵의 경우 필터링시 쇼핑몰 URL이 변하지 않음.
따라서, <code>useLocation</code>에서 <code>url</code>을 받아 렌더링하는 방법 사용할 수 없음.</li>
<li>대신 각 조건을 배열의 형태로 <code>state</code>에 저장하여 렌더링의 대상이 되는 <code>queryString</code>으로 만들어 렌더링하는 방식으로 구현함.</li>
</ul>
<h4 id="4구현상세">4)구현상세</h4>
<p>(1) Product List에서는 Filter, Sorter, Search, Pagination에 필요한 <code>state</code>와 이를 수정할 수 있는 <code>function</code>을 만들어 각각의 컴포넌트로 전달.</p>
<pre><code>  const handleFilter = (name, attr) =&gt; {
    const filterArr = [...filters];
    filterArr.includes(`${name},${attr}`)
      ? filterArr.splice(filterArr.indexOf(`${name},${attr}`), 1)
      : filterArr.push(`${name},${attr}`);
    setFilters(filterArr);
    setQueryStrings(filterArr);
  };</code></pre><p>  ※필터의 경우 1회 클릭시 적용, 중복 클릭시 적용이 해제되므로, Splice로 중복된 인덱스의 필터배열을 제거하도록 함.</p>
<p>(2)각각의 컴포넌트에서는 <code>onClick</code>, <code>onChange</code> 등을 통해 내려받은 <code>function</code>으로 부모의 <code>state</code>를 수정하고 끌어올림.</p>
<pre><code> &lt;li
 key={categoryAttr}
 className=&quot;categoryAttr&quot;
 onClick={() =&gt; handleFilter(categoryName, categoryAttr)}
 &gt;</code></pre><p>(3)끌어올린 <code>state</code>값으로 <code>queryParameter</code>를 만들고 이에 의존성에 있는 <code>useEffect</code>내부의 <code>fetch</code>함수로 화면을 렌더링.</p>
<pre><code>   switch (splittedFilter[0]) {
          case &#39;sub&#39;:
            addParamFilters.push(`&amp;sub=${param}-${splittedFilter[1]}`);
            break;
          case &#39;size&#39;:
            addParamFilters.push(`&amp;size=${splittedFilter[1]}`);
            break;
          case &#39;character&#39;:
            addParamFilters.push(`&amp;character=${splittedFilter[1]}`);
            break;
          default:
        }</code></pre><h3 id="3-2-서버통신을-통한-결제-및-주소업데이트-기능">3-2. 서버통신을 통한 결제 및 주소업데이트 기능</h3>
<h4 id="1구현화면-1">1)구현화면<img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/2ba03bd0-b2c6-4cbc-a62d-6d1098f6c4cd/image.gif" alt=""></h4>
<h4 id="2구성도-1">2)구성도</h4>
<p><img src="https://velog.velcdn.com/images/gonkang_jeondosa/post/2ccebf43-ce6f-464f-970c-37e8070ae7df/image.png" alt=""></p>
<h4 id="3구현특징-1">3)구현특징</h4>
<ul>
<li>가입시점에 고객주소정보 입력하지않으므로, 배송정보를 수집 및 고객정보로 저장하는 기능 필요.</li>
<li>PG를 붙일 수 없으므로 고객마일리지에서 차감하는 형식으로 진행.</li>
</ul>
<h4 id="4구현상세-1">4)구현상세</h4>
<p>(1)배송정보 유효성 검사 후, 고객이 입력한 주소를 기본배송지로 업데이트하겠다는 의사를 확인하고 이에 따라 결제대금 차감 및 주소 업데이트 진행.</p>
<pre><code>  const submitOrder = () =&gt; {
    if (orderNecessaryInfo) {
      if (orderInfo.updateAddress) {
        postBalance();
        patchAddress();
      } else {
        postBalance();
      }
    } else alert(&#39;정보를 모두 입력해주세요&#39;);
  };</code></pre><p>  (2)결제는 POST방식으로 서버와 통신하여 진행하며 처리결과는 <code>alert</code>로 안내.</p>
<pre><code>  const postBalance = () =&gt; {
    fetch(`${BASE_URL}/orders`, {
      method: &#39;POST&#39;,
      headers: {
        Authorization: localStorage.getItem(&#39;token&#39;),
      },
      body: JSON.stringify({
        total_price: subtotal,
      }),
    })
      .then(response =&gt; {
        if (response.ok) {
          alert(&#39;주문이 완료되었습니다.&#39;);
        } else if (response.message === &#39;moneyless&#39;) {
          alert(&#39;잔액이 부족합니다.&#39;);
        } else if (response.message === &#39;stockless&#39;) {
          alert(&#39;재고가 부족합니다.&#39;);
        } else {
          throw new Error(&#39;Unexpected Error&#39;);
        }
      })
      .catch(error =&gt; {
        // eslint-disable-next-line no-console
        console.log(error.message);
      });
  };</code></pre><p>(3)주소 업데이트는 PATCH방식으로 서버와 통신하여 진행하며 처리결과는 <code>alert</code>로 안내.</p>
<pre><code>const patchAddress = () =&gt; {
    fetch(`${BASE_URL}/users/`, {
      method: &#39;PATCH&#39;,
      headers: {
        Authorization: localStorage.getItem(&#39;token&#39;),
      },
      body: JSON.stringify({
        zip_code: orderInfo.zipCode,
        location: orderInfo.addressMain,
        datail_address: orderInfo.addressDetail,
      }),
    })
      .then(response =&gt; {
        if (response.ok) {
          alert(&#39;주소변경이 완료되었습니다.&#39;);
        } else {
          throw new Error(&#39;Unexpected Error&#39;);
        }
      })
      .catch(error =&gt; {
        // eslint-disable-next-line no-console
        console.log(error.message);
      });
  };</code></pre><h2 id="4-lesson-learned">4. Lesson Learned</h2>
<h4 id="1-pr-attitude">1) PR Attitude</h4>
<ul>
<li>가능한한 세분화하여 PR 올릴 것.</li>
<li>Sider 및 컨벤션 면밀히 체크한 후 PR올릴 것.</li>
</ul>
<h4 id="2--co-work">2)  Co work</h4>
<ul>
<li>이슈발생시 즉각 논의하고 기록으로 남길 것.</li>
<li>기록을 한눈에 찾아볼 수 있는 시스템을 활용하여 불필요한 회의는 줄일 수 있도록 할 것.</li>
<li>팀원들의 코드를 리뷰하고 질의함으로써, 담당파트를 더욱 빠르게 구현하고 학습할 수 있음.</li>
<li>담당파트와 더불어 전체그림의 진척도를 계속 상기할 것.</li>
</ul>
<h4 id="3-hook">3) Hook</h4>
<ul>
<li>리액트의 다양한 hook을 사용하며 dependency 및 불변성 학습</li>
<li>깊은 복사/ 얕은 복사 개념 학습</li>
</ul>
<h4 id="4동적라우팅">4)동적라우팅</h4>
<ul>
<li>동적라우팅의 개념 및 리액트 내 다양한 기법 학습(useParams / Router / QueryParameter / Path Parameter)</li>
<li>작성 블로그 게시글<ul>
<li><a href="https://velog.io/@gonkang_jeondosa/%EB%8F%99%EC%A0%81%EB%9D%BC%EC%9A%B0%ED%8C%85%EB%8B%A4%EC%A4%91%ED%95%84%ED%84%B0-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0">[동적라우팅]다중필터 처리하기 (1편:라우팅개념)</a><ul>
<li><a href="https://velog.io/@gonkang_jeondosa/%EB%8F%99%EC%A0%81%EB%9D%BC%EC%9A%B0%ED%8C%85%EB%8B%A4%EC%A4%91%ED%95%84%ED%84%B0-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-2%ED%8E%B8Query-Parameter%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%9E%90">[동적라우팅]다중필터 처리하기 (2편:Query Parameter를 사용해보자)</a></li>
</ul>
</li>
<li><a href="https://velog.io/@gonkang_jeondosa/%EB%8F%99%EC%A0%81%EB%9D%BC%EC%9A%B0%ED%8C%85%EB%8B%A4%EC%A4%91%ED%95%84%ED%84%B0-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-3%ED%8E%B8-%ED%95%84%ED%84%B0%EC%9D%98-%EC%A2%85%EB%A5%98%EB%B3%84-queryString-%EC%B2%98%EB%A6%AC">[동적라우팅]다중필터 처리하기 (3편: 카테고리 depth별 서로다른 queryString 만들기)</a></li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[동적라우팅]다중필터 처리하기 (3편: 카테고리 depth별 서로다른 queryString 만들기)]]></title>
            <link>https://velog.io/@gonkang_jeondosa/%EB%8F%99%EC%A0%81%EB%9D%BC%EC%9A%B0%ED%8C%85%EB%8B%A4%EC%A4%91%ED%95%84%ED%84%B0-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-3%ED%8E%B8-%ED%95%84%ED%84%B0%EC%9D%98-%EC%A2%85%EB%A5%98%EB%B3%84-queryString-%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@gonkang_jeondosa/%EB%8F%99%EC%A0%81%EB%9D%BC%EC%9A%B0%ED%8C%85%EB%8B%A4%EC%A4%91%ED%95%84%ED%84%B0-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-3%ED%8E%B8-%ED%95%84%ED%84%B0%EC%9D%98-%EC%A2%85%EB%A5%98%EB%B3%84-queryString-%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Sat, 02 Apr 2022 16:50:44 GMT</pubDate>
            <description><![CDATA[<p>지난시간까지 했던 다중필터는 의류의 TYPE이라는 카테고리가 지닌 top, bottom, acc라는 속성안에서는 잘 돌아가지만, 
카테고리가 바뀌어버리면 백엔드에 올바른 쿼리스트링을 줄 수 없다는 문제가 생겼다.
이에 신박한 접근을 떠올리게 되는데,,,</p>
<blockquote>
<p>클릭의 대상이 되는 속성버튼의 id 자체를 쿼리로 입력하면되잖아?
<img src="https://media.vlpt.us/images/gonkang_jeondosa/post/8e0b045b-96ee-4446-8885-d1f4995b74fe/image.png" alt=""></p>
</blockquote>
<p>그리하여 상수데이터를 위와같이 변경하게 되는데, 이는 추후에 대카테고리별로 서버에서 카테고리 속성을 달리 가져오는 경우에는 무용지물이 되는 단점이 있고. PR을 올리면 가차없이 철퇴를 맞기에 부족함이 없는 로직이라고 할 수 있겠다...</p>
<p>잠시나마 미쳤었던 마음을 추스리고, 각각의 카테고리속성과 카테고리의 이름을 모두 받아서 switch로 분리하고 처리하는 로직으로 재구현했다.</p>
<h3 id="step-1--버튼의-id를-받을-때-카테고리명과-속성을-모두-받아온다">Step 1 : 버튼의 id를 받을 때 카테고리명과 속성을 모두 받아온다</h3>
<p><img src="https://media.vlpt.us/images/gonkang_jeondosa/post/1fd191a5-61aa-40da-97c6-b5391d8d8f8e/image.png" alt=""></p>
<h3 id="step-2---type-size-character-각각으로-들어왔을때-각각-다른-쿼리스트링-제작-로직을-세팅했다">Step 2 :  TYPE, SIZE, CHARACTER 각각으로 들어왔을때 각각 다른 쿼리스트링 제작 로직을 세팅했다.</h3>
<pre><code>  const setQueryStrings = () =&gt; {
    let queryString = &#39;&#39;;
    let addParamFilters = [];
    if (filters) {
      filters.forEach(filter =&gt; {
        const splittedFilter = filter.split(`,`);
        switch (splittedFilter[0]) {
          case &#39;TYPE&#39;:
            addParamFilters.push(`&amp;sub=${param}-${splittedFilter[1]}`);
            break;

          case &#39;SIZE&#39;:
            addParamFilters.push(`&amp;size=${splittedFilter[1]}`);
            break;

          case &#39;CHARACTER&#39;:
            addParamFilters.push(`&amp;character=${splittedFilter[1]}`);
            break;

          default:
        }
      });
      queryString = `${API.productList}${param}${addParamFilters.join(&#39;&#39;)}`;
    } else {
      queryString = `${API.productList}${param}`;
    }
    setUrl(queryString);
  };</code></pre><p> 아아...돌아간다 잘돌아간다...
 하지만 혹여나 정성스레 작성한 PR에 또다른 철퇴가 꽂힌다면..</p>
<p> 나는 또 4부를 쓰게 될것이다... 과연 다중필터는 몇부작까지 도달할것인가...거의뭐..대하드라마..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[동적라우팅]다중필터 처리하기 (2편:Query Parameter를 사용해보자)]]></title>
            <link>https://velog.io/@gonkang_jeondosa/%EB%8F%99%EC%A0%81%EB%9D%BC%EC%9A%B0%ED%8C%85%EB%8B%A4%EC%A4%91%ED%95%84%ED%84%B0-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-2%ED%8E%B8Query-Parameter%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@gonkang_jeondosa/%EB%8F%99%EC%A0%81%EB%9D%BC%EC%9A%B0%ED%8C%85%EB%8B%A4%EC%A4%91%ED%95%84%ED%84%B0-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-2%ED%8E%B8Query-Parameter%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Sat, 02 Apr 2022 09:06:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://media.vlpt.us/images/gonkang_jeondosa/post/b52431fe-cb06-42fa-88e3-30c7c3c3c5e5/image.png" alt="">
이번에는 좌측에 위치한 필터들을 클릭했을 때, 해당 필터에 해당하는 제품들을 보여주는 기능을 구현해보고자 한다.
한 번 클릭하면 필터가 활성화되고, 두 번 클릭하면 해제되는 형태이다. 토글등등 다양한 방법을 고민해보았는데, 결국 아래 3단계로 완료할 수 있었다.</p>
<h2 id="1-필터리스트-스테이트-관리">1. 필터리스트 스테이트 관리</h2>
<pre><code> const handleFilter = e =&gt; {
    let filterArr = filters;
    filterArr.indexOf(e.target.id) === -1
      ? filterArr.push(e.target.id)
      : filterArr.splice(filterArr.indexOf(e.target.id), 1);
    setFilters(filterArr);
    setQueryParameter();
  };</code></pre><p>필터를 클릭할때마다 state로 선언한 filters에 핕터목록을 배열로 넣어준다. 단 이미 해당 필터가 들어있을때에는 splice로 제거한다.</p>
<h2 id="2-백엔드에-get요청할-url-생성">2. 백엔드에 GET요청할 URL 생성</h2>
<pre><code> const setQueryParameter = () =&gt; {
    let queryParameter = &#39;&#39;;
    let addParamFilters = [];
    if (filters) {
      filters.forEach(filter =&gt; {
        addParamFilters.push(`${param}-${filter}`);
      });
      queryParameter = `${API.productList}${param}&amp;sub=${addParamFilters}`;
    } else {
      queryParameter = `${API.productList}${param}`;
    }
    setUrl(queryParameter);
  };</code></pre><p>1번에서 만든 필터를 백엔드와 약속한 형태로 전처리한 후 url이라는 state를 최신화한다.</p>
<h2 id="3-useeffect로-렌더링-요청">3. useEffect로 렌더링 요청</h2>
<pre><code>  useEffect(() =&gt; {
    fetch(url)
      .then(response =&gt; response.json())
      .then(product =&gt; {
        setProducts(product.result);
        setSubtotal(product.count);
      });
  }, [url]);</code></pre><p>  url값이 바뀔때마다 바뀐 url로 fetch를 요청하도록 useEffect를 작성.</p>
<h2 id="4-총평">4. 총평</h2>
<p>  일견 괴랄한 코드이나 백엔드와 통신해보니  잘굴러갑니다.
  작성 중 useEffect구문 내에서 dependency이슈로 에러가 있었는데, fetch에서 가져오는 url을 하단 의존성배열에 넣어 해결하였습니다.
  코드리뷰이후 변경될 경우 해당 코드의 문제점 및 보완사항도 3부작으로 업데이트하고자합니다.</p>
<p>  그럼 아디오스</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[동적라우팅]다중필터 처리하기 (1편:라우팅개념)]]></title>
            <link>https://velog.io/@gonkang_jeondosa/%EB%8F%99%EC%A0%81%EB%9D%BC%EC%9A%B0%ED%8C%85%EB%8B%A4%EC%A4%91%ED%95%84%ED%84%B0-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@gonkang_jeondosa/%EB%8F%99%EC%A0%81%EB%9D%BC%EC%9A%B0%ED%8C%85%EB%8B%A4%EC%A4%91%ED%95%84%ED%84%B0-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 01 Apr 2022 05:33:01 GMT</pubDate>
            <description><![CDATA[<h2 id="1-라우팅-개념정리하고가실게요">1. 라우팅 개념정리하고가실게요~</h2>
<h3 id="1-1라우팅이란">1-1.라우팅이란</h3>
<ul>
<li><code>url</code>주소를 기준으로 다른 <code>view</code>를 보여주는 것</li>
</ul>
<h3 id="1-2-spa에서의-라우팅이란">1-2. SPA에서의 라우팅이란</h3>
<ul>
<li>화면을 이동하여 새로고침하지 않고, 동적으로 화면(뷰)를 그려주는 기술</li>
<li><code>react</code>에서는 <code>recat-router-dom</code>을 활용하여 SPA라우팅을 구현</li>
</ul>
<h3 id="1-3정적라우팅과-동적라우팅">1-3.정적라우팅과 동적라우팅</h3>
<p>1)정적라우팅 : <code>/</code>, <code>/users</code> , <code>/products</code>와 같이 정해진 경우에 대해서만 경로를 표현</p>
<p>2)동적라우팅 : url마지막에 특정 id값이 들어감. id값에 따라 무수히 많은 url이 생성됨 ex)<code>/products/1043</code> 1043번째로 등록된 제품 상세페이지</p>
<h2 id="2-동적-라우팅-처리방법-2가지">2. 동적 라우팅 처리방법 2가지</h2>
<p>우리가 구현하고자하는 것은, SIZE, 제품Type(상의, 하의, 악세서리), 캐릭터(브랜드) 각각의 속성을 다중으로 처리하는 것이다.</p>
<h3 id="1path-parameter">1)Path Parameter</h3>
<p>해당기능은 useNavigate &amp; useLocation 훅을 사용하여 상품리스트페이지에서 상세페이지로 보내는 기능을 구현하는데에 활용하기로 했다.</p>
<blockquote>
<p><code>user/:id</code>  =&gt; <code>&lt;users /&gt;</code>  // <code>useParams().id</code></p>
</blockquote>
<p>[부모컴포넌트]</p>
<pre><code>return (
    &lt;BrowserRouter&gt;
      &lt;div&gt;
        &lt;h2&gt;Accounts&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;Link to=&quot;/Boy&quot;&gt;소년용품&lt;/Link&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;Link to=&quot;/Girls&quot;&gt;소녀용품&lt;/Link&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;Link to=&quot;/Toys&quot;&gt;장난감&lt;/Link&gt;
          &lt;/li&gt;
        &lt;/ul&gt;

        &lt;Routes&gt;
          &lt;Route path=&quot;/:id&quot; element={&lt;Child /&gt;} /&gt; &lt;-자녀컴포넌트를 element로 삼고 그 path 뒷부분에 id를 넣어주겠다.
        &lt;/Routes&gt;
      &lt;/div&gt;
    &lt;/BrowserRouter&gt;
  );</code></pre><p>[자식컴포넌트]</p>
<pre><code>  const { id } = useParams();   &lt;-useParams()로 부모에서 준 id를 받아오겠어요. 

  return (
    &lt;div&gt;
      &lt;h3&gt;ID: {id}&lt;/h3&gt;   &lt;--{id}를 쓰겠어요
    &lt;/div&gt;
  );
}</code></pre><h3 id="2query-parameter">2)Query Parameter</h3>
<blockquote>
<p><code>/search?keyword=something</code> : <code>&lt;Search /&gt;</code> // <code>useLocation().search</code></p>
</blockquote>
<p>[조부모(?)컴포넌트]</p>
<pre><code>export default function QueryParamsExample() {
  return (
    &lt;Router&gt;
      &lt;QueryParamsDemo /&gt;  &lt;-쿼리파라미터라는 하위컴포넌트 따로갈게요~
    &lt;/Router&gt;
  );
}</code></pre><p>[부모컴포넌트]</p>
<pre><code>return (
    &lt;div&gt;
      &lt;div&gt;
        &lt;h2&gt;Accounts&lt;/h2&gt;
        &lt;ul&gt;
          &lt;li&gt;
            &lt;Link to=&quot;/account?name=top&quot;&gt;상의&lt;/Link&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;Link to=&quot;/account?name=bottom&quot;&gt;하의&lt;/Link&gt;
          &lt;/li&gt;
          &lt;li&gt;
            &lt;Link to=&quot;/account?name=acc&quot;&gt;악세서리&lt;/Link&gt;
          &lt;/li&gt;
        &lt;/ul&gt;

        &lt;Child name={query.get(&quot;name&quot;)} /&gt;    &lt;=쿼리의 name항목을 가져다가 자식컴포넌트의 name으로 보내준다.
      &lt;/div&gt;
    &lt;/div&gt;
  );
}</code></pre><p>[자식컴포넌트]</p>
<pre><code>return (
    &lt;div&gt;
      {name ? (   &lt;-중괄호치고 로직들어갑니다~. 부모에서 받은 name에 따라 아래 코드로 렌더링을 가겠다 이겁니다.
        &lt;h3&gt;
          The name in the query string is &amp;quot;{name}
          &amp;quot;    &lt;---쫄지마요 &amp;quot;는 단지 쌍따옴표(&quot;)일뿐...쌍따옴표사이에 부모에서 받은 name값을 넣어주겠다라는 것...
        &lt;/h3&gt;
      ) : (
        &lt;h3&gt;There is no name in the query string&lt;/h3&gt;
      )}
    &lt;/div&gt;
  );</code></pre><blockquote>
<p>그렇다면 다중필터를 위해서는 어떤 동적라우팅 기능을 선택해야할까..
다음 편에서 계속됩디다..</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Hook]구조분해할당으로 child에 State값 내리기]]></title>
            <link>https://velog.io/@gonkang_jeondosa/Hook%EA%B5%AC%EC%A1%B0%EB%B6%84%ED%95%B4%ED%95%A0%EB%8B%B9%EC%9C%BC%EB%A1%9C-child%EC%97%90-State%EA%B0%92-%EB%82%B4%EB%A6%AC%EA%B8%B0</link>
            <guid>https://velog.io/@gonkang_jeondosa/Hook%EA%B5%AC%EC%A1%B0%EB%B6%84%ED%95%B4%ED%95%A0%EB%8B%B9%EC%9C%BC%EB%A1%9C-child%EC%97%90-State%EA%B0%92-%EB%82%B4%EB%A6%AC%EA%B8%B0</guid>
            <pubDate>Sat, 26 Mar 2022 12:36:10 GMT</pubDate>
            <description><![CDATA[<p>구조분해할당을 적용하면 State값을 child에 내릴 때 좀 더 간단히 진행할 수 있다.</p>
<h3 id="1-parents가-내려줄-때">1. Parents가 내려줄 때</h3>
<p>monsters라는 state는 여러 monster의 속성들이 객체의 형태로 담겨있는 배열이다.
parents에서 child로 monsters의 id / name / email이라는 속성을 내려주고자 한다.</p>
<h4 id="as-is">AS-IS</h4>
<pre><code>function CardList({monsters}) {

  return(
  &lt;div className=&quot;cardList&quot;&gt;
    {monsters.map((monster)=&gt;(
    &lt;Card 
        key={monster.id}
        id = {monster.id}
        name = {monster.name}
        email = {monster.email}
    /&gt;
    ))}
  &lt;/div&gt;
  );
};
</code></pre><h4 id="to-be">TO-BE</h4>
<pre><code>function CardList({monsters}) {

  return(
  &lt;div className=&quot;cardList&quot;&gt;
    {monsters.map((monster)=&gt;(
    &lt;Card key={monster.id} {...monster}/&gt;
    ))}
  &lt;/div&gt;
  );
};
</code></pre><h3 id="2-child에서-받을-때">2. child에서 받을 때</h3>
<h4 id="as-is-1">AS-IS</h4>
<p>props를 불러와 필요한 속성앞에 <code>props.</code>을 붙이고 사용한다</p>
<pre><code>function Card(props) {
  return (
  &lt;div className=&quot;cardContainer&quot;&gt;
    &lt;img src ={`https://robohash.org/${props.id}?set=set2&amp;size=180x180`} /&gt;
    &lt;h2&gt;{props.name}&lt;/h2&gt;
    &lt;p&gt;{props.email}&lt;/p&gt;
  &lt;/div&gt;
  );
}

export default Card;

}

export default Card;</code></pre><h4 id="to-be-1">TO-BE</h4>
<p>필요한 객체속성을 <code>{}</code>중괄호에 담아서 <code>props.</code>생략하고 사용한다</p>
<pre><code>function Card({id, name, email}) {
  return (
  &lt;div className=&quot;cardContainer&quot;&gt;
    &lt;img src ={`https://robohash.org/${id}?set=set2&amp;size=180x180`} /&gt;
    &lt;h2&gt;{name}&lt;/h2&gt;
    &lt;p&gt;{email}&lt;/p&gt;
  &lt;/div&gt;
  );
}

export default Card;</code></pre><p>크-린 코드의 길은 멀고도 험한것..
그럼 20000....</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Javascript]Promise객체와 비동기처리]]></title>
            <link>https://velog.io/@gonkang_jeondosa/JavascriptPromise%EA%B0%9D%EC%B2%B4%EC%99%80-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@gonkang_jeondosa/JavascriptPromise%EA%B0%9D%EC%B2%B4%EC%99%80-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Sat, 26 Mar 2022 08:42:40 GMT</pubDate>
            <description><![CDATA[<h2 id="1-promise-객체의-정의">1. Promise 객체의 정의</h2>
<blockquote>
<p>Promise객체란 비동기 작업이 멎아헐 성공/실패에 대한 결과값을 의미한다.
-MDN-</p>
</blockquote>
<p>생성된 작업에 대한 상태정보를 하기 3가지 유형으로 가지고 있는 객체이다</p>
<h4 id="1pending-대기-fulfilled--rejected-둘다-아닌-초기상태">1)pending (대기): fulfilled / rejected 둘다 아닌 초기상태</h4>
<h4 id="2fulfilled-이행-연산-완료">2)fulfilled (이행): 연산 완료</h4>
<h4 id="3rejected-거부--연산-실패">3)rejected (거부) : 연산 실패</h4>
<h2 id="2-왜-필요한지">2. 왜 필요한지</h2>
<p><code>Promise</code>객체에 대해 찾아보면 비동기처리에 대해 먼저 확인하고 오라는 답변을 익숙하게 받았을 것이다.  이는 <code>Promise</code>객체의 <code>Chaining</code>이라는 강력한 기능때문이다. </p>
<h3 id="1비동기-처리란">1)비동기 처리란</h3>
<ul>
<li><p>CPU를 사용한 데이터 처리방식에 비해 하드디스크 읽쓰작업 &amp; 네트워크를 통해 데이터 주고받는 작업(이하 &#39;I/O작업&#39;으로 통칭) 매우 느리다.</p>
</li>
<li><p>이에 I/O작업이 다 될때까지 기다리는 것이 아니라, 요청만 해두고 다른 작업을 먼저 하는 것을 비동기처리라고 한다.</p>
<h3 id="2그러면-promise객체는-왜-필요한건지">2)그러면 Promise객체는 왜 필요한건지?</h3>
<ul>
<li>비동기 작업들의 상태(pending/fulfulled/rejected)를 동기적으로 반환함으로써 필요한 동작을 실행할 수 있다.</li>
<li><code>Chaining</code> : 비동기 처리들을 순차적으로 처리할 수 있다.</li>
<li><code>fetch</code>와 <code>then</code>의 사례를 들어 확인해보자 이 둘은 <code>promise</code>객체를 리턴하는 함수이다.</li>
</ul>
<pre><code>fetch(&quot;주소&quot;) 
.then((response) =&gt; response.text()) 
.then(result=&gt; {
 const users = JSON.parse(result);
 return users[0];
});</code></pre><p>fetch를 실행하면 HTTP Response를 받아온다.
이는 실제 JSON이 아니기떄문에, json()메서드를 사용해야한다.
이 떄, fetch작업이 fulfilled되고난 이후 비로소 .json()메서드가 실행되도록 해야하는데
이를 <code>chaining</code>이라고 한다.</p>
</li>
</ul>
<h3 id="참고자료">참고자료</h3>
<ul>
<li>Promise : <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise</a></li>
<li>fetch : <a href="https://developer.mozilla.org/en-US/docs/Web/API/fetch">https://developer.mozilla.org/en-US/docs/Web/API/fetch</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로젝트 분석 개론]]></title>
            <link>https://velog.io/@gonkang_jeondosa/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%B6%84%EC%84%9D-%EA%B0%9C%EB%A1%A0</link>
            <guid>https://velog.io/@gonkang_jeondosa/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%B6%84%EC%84%9D-%EA%B0%9C%EB%A1%A0</guid>
            <pubDate>Thu, 24 Mar 2022 07:27:43 GMT</pubDate>
            <description><![CDATA[<h2 id="처음-프로젝트-받았을-때-소스코드-검토하는-법">처음 프로젝트 받았을 때 소스코드 검토하는 법</h2>
<p>1)package.json</p>
<ul>
<li>(디펜던시)의존성확인</li>
</ul>
<p>2)index.html -&gt; index.js -&gt; router.js</p>
<p>복잡한 코드에 대해 설명하는 주석 지양해야하는 이유 : 코드가 업데이트될때마다 설명도 업데이트해야되는데 쉽지않다. 그러므로, 코드설명하는 주석 대신 코드를 쉽게 수정할것</p>
<p>코드설명을 제외한 주석활용 : 나중에 들어올 기능, 추가 디벨롭 예정사항 등 마킹</p>
<p>//TODO : <del>나중에 할일,
//FIXME: ~</del>나중에 고칠사항 마킹,</p>
<p>나중에는 TODO / FIXME를 검색해서 업무를 진행하기도 함
개발버전에서 진행하고, 마스터에 MERGE되기 전까지는 TODO/FIXME 모두 해결해서 없도록 하는것이 국룰</p>
<p>useState는 관심사에 따라 묶어준다 =&gt;어떤 목적을 가지고 있는지 판단</p>
<p>isValueTrue -&gt;불리언을 말하는건가? 값이 TRUE라는건가 오해의 소지있음. 변수명과 네이밍 정확하게</p>
<p>함수 분리하는 이유-&gt;유지보수를 최대한 쉽게 하기 위해서. 한가지가 바뀌었을때 어디까지 수정해야하는지를 줄어주는것. 지금은 너무작아서 안쪼개도, 나중에는 점점 커질수 있으므로 목적단위로 쪼개라.</p>
<hr>
<p>fetch에서 localhost;3000T쓰지마라. 바로 퍼블릭 이하의 경로를 작성해줄것. ㅣocal host3000은 포트번호 변경되거나 배포후에는 url이나 다른 ip로 바뀌게된다.</p>
<p>arr, obj, num, string, data등을 접미사로 변수만들지마라</p>
<p>arr/list등 접미사 쓰지말고 복수형을 써라 feed list-&gt; feeds</p>
<hr>
<p>fetch는 promise를 반환하고
.then =&gt; 그 반환값에 뭔가 이하 처리를한다
그것을 연속해서 처리하는게...
.then
.then 연속사용도 가능해 마치 (Array.map(x-&gt;x).map</p>
<p>.then은 프로미스에만 사용할 수 있다.</p>
<p>비동기상황을 쉽게 표현하기 위해 만든 객체가 바로 promise</p>
<hr>
<p>feeds.map() 괄호안에 element를 쓰거나 data를 쓰거나 등등...
사실 feed를 쓰면된다. feeds 내부값을 배열로 돌릴건데, 각각의 값이 feed이므로...</p>
<hr>
<p>]</p>
<p>const Feed=({Feeds})=&gt;{
const {id, topUser img 등등}= Feeds 구조분해
--
prefer const. let쓰면 나중에 얘가바뀔값인지 오해하게됨</p>
<hr>
<p>코멘트, push하지말고
먼저 newCOmment만들어서 값을 넣고
이후에 newcommentArry=[...commentArr, newComment]이런식으로 선언적으로 쓰면 좋다.</p>
<hr>
<h2 id="리액트-쓸때-주의할-점">리액트 쓸때 주의할 점</h2>
<p>리액트의 근간 - state, props, effect</p>
<p>state를 언제써야하는가? 
초기 리액트 개발자는 모든 변수를 state를 가져가려고 하는데, 그럴필요가 있나?
스테이트 바뀔떄마다 리랜더링되므로 부하도 많이 걸린다.데이터를 꼭 set으로 넣어야하므로 불편..</p>
<p>[리액트로 사고하기]다시 읽어보고 코드쳐보기</p>
<p>state쓰는기준 
1)부모를 통해 전달됩니까? 아닙니다  =&gt;유지보수가 굉장히 어려워져요.
 -리액트는 단방형 / 하나의 상태를 표현하는 값은 하나다
 -부모에서 받은 코멘트를 자식에서 새로운 스테이트로 수정한다면...양쪽의 씽크를 맞춰야되는건데ㅏ,,,하나의 상태를 표현하는 값이 여러개가 되면 힘들어짐
 -부모에서 진리의 원천을 가져오면 (useEffect - fetch - get)거기서 데이터를 조작할 수 있는 함수를 만들어서 내려줄 것</p>
<p>시간이 지나도 변하지 않는다? 아닙니다
컴포넌트안에 다른state props로 대체가능한가? 아닙니다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[인증과 인가]]></title>
            <link>https://velog.io/@gonkang_jeondosa/%EC%9D%B8%EC%A6%9D%EA%B3%BC-%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@gonkang_jeondosa/%EC%9D%B8%EC%A6%9D%EA%B3%BC-%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Mon, 21 Mar 2022 03:28:21 GMT</pubDate>
            <description><![CDATA[<h2 id="1-왜-인증이-필요한가">1. 왜 인증이 필요한가</h2>
<ul>
<li>인증 : 올바른 유저인지 확인하는 것</li>
<li>인가 : 유저별 권한을 부여하는 것<ul>
<li>유저의 이력을 추적하기 위해서</li>
</ul>
</li>
</ul>
<blockquote>
<p>인증에 필요한것은?</p>
</blockquote>
<ul>
<li>ID/Email : 외부에 노출이 된 개인정보</li>
<li>Password : 노출안된 정보. 가장 중요하다</li>
</ul>
<h3 id="1비밀번호-관리하기">1)비밀번호 관리하기</h3>
<ul>
<li>상용 암호화 알고리즘으로 법적으로 암호화하도록 되어있다.(회원가입하여 DB에 저장될 때 암호화 진행)
<img src="https://images.velog.io/images/gonkang_jeondosa/post/9dc0a317-0ac2-4a22-bb04-e328c6fc8534/image.png" alt=""></li>
<li>통신시 개인정보 주고받을 때 SSL 적용하여 암호화(HTTPS)</li>
<li>http를 하나의 레이어로 감싸, 외부에서 원본을 볼 수 없게 하는 것</li>
</ul>
<h3 id="2단방향-해쉬함수">2)단방향 해쉬함수</h3>
<ul>
<li>암호화는 가능하지만, 복호화는 불가능</li>
<li>SHA-256이 대표적</li>
<li>결과만 봐서는 당장 식별이 불가능하나 두 가지 단점 존재.<blockquote>
<p>(문제1)메시지가 같으면 다이제스트도 동일하므로, 다이제스트 하나가 털리면 동일한 다이제스트를 사용하는 다른 사용자의 패스워드도 털려버림
<code></code>
(문제2)<a href="http://wiki.hash.kr/index.php/%EB%A0%88%EC%9D%B8%EB%B3%B4%EC%9A%B0_%ED%85%8C%EC%9D%B4%EB%B8%94#.EB.A0.88.EC.9D.B8.EB.B3.B4.EC.9A.B0_.ED.85.8C.EC.9D.B4.EB.B8.94.EC.9D.98_.EC.9B.90.EB.A6.AC">Rainbow Attack</a>에 취약 
※RainbowTable에 미리 해시해둔 패스워드를 쌓아놓고 모든 값을 대입해서 로그인 시도하는 것</p>
</blockquote>
</li>
</ul>
<h3 id="3salting--key-stretching">3)Salting &amp; Key Stretching</h3>
<p><img src="https://images.velog.io/images/gonkang_jeondosa/post/380eca2d-57ed-48cf-8b01-2a43ad41c727/image.png" alt=""></p>
<ul>
<li>SHA-256에서의 허점 보완하기 위해 나옴<blockquote>
<p>Rainbow Attack 
Rainbow Ta해커가 Rainbow테이블 활용해서 무작위대입으로 해시값 계산하는데 필요한 시간을 대폭 늘리기 위해, </p>
</blockquote>
</li>
<li>입력한 비밀번호와 임의로 생성한 문자열(salt)을 합쳐서 해싱한 후 해시값을 저장.</li>
<li>Salting: 해시값과 Salt값을 함께 저장해준다(Salt는 128bit 정도는 되어야 안전하다.)</li>
<li>Key Stretching : Salting &amp;해싱을 여러번 반복해서 Rainbow Attack에 소요되는 시간을 늘려 원본값 유추하기 어렵게 만들기위함(Key Stretching)
<img src="https://images.velog.io/images/gonkang_jeondosa/post/c683e79a-7d95-495b-95aa-0e27232cfa21/image.png" alt=""><blockquote>
<p>일정길이로 해싱된 값에 salt를 붙이고 해싱하고, 그 값에 salt를 또 붙여서 해싱하는 동작을 여러번 반복함.
3개월지나면 비밀번호를 바꿔야하는 이유가 여기에 있다.</p>
</blockquote>
</li>
</ul>
<h3 id="4bcrypt">4)bcrypt</h3>
<ul>
<li>Salting &amp; Key Stretching의 대표적인 라이브러리</li>
<li>DB에 Salt 컬럼을 따로 설계하지않아도 저장없이 알아서 해줌.</li>
</ul>
<p><img src="https://images.velog.io/images/gonkang_jeondosa/post/eafca4a4-7c46-419b-8967-c7e501326c17/image.png" alt=""></p>
<h2 id="2-인가는-무엇인가">2. 인가는 무엇인가?</h2>
<ul>
<li>해당 유저가 request에 해당하는 권한이 있는지 확인하는 절차<blockquote>
<p>HTTP는 stateless한 특성을 지니므로, 각 통신의 상태는 저장되지 않는다.
그러나 매번 새 페이지를 요청할때마다 로그인을 해야 한다면 사용이 불가능할 것이다.</p>
</blockquote>
</li>
</ul>
<p>상기 문제 해결위해 Session과 Token 등장</p>
<h3 id="1session과-token">1)Session과 Token</h3>
<ul>
<li><p>유저의 로그인 시도 후 서버에서 일치하는 값을 찾은 후 유저에게 Session 또는 Token을 발급함.</p>
</li>
<li><p>브라우저는 request마다 해당 Session 또는 Token을 함께 보냄</p>
</li>
<li><p>Session은 서버에서 관리, Token은 웹브라우저에 저장되므로 민감정보를 담지 않고 유효기간 짧게 설정함. 
짧은 유효기간으로 인한 불편함은 Refresh Token 발행하여 유효기간 연장하고 좀 더 안전한곳에 저장하도록 하여 해소.</p>
</li>
<li><p>Session은 오늘날 분산된 서버형태에서는 사용하기 어렵고 서버부하 많이 걸림. 확장성에 유연하지 못함. 이에 주로 Token을 사용함</p>
</li>
</ul>
<h3 id="2-jason-web-token">2) JASON web Token</h3>
<p><img src="https://images.velog.io/images/gonkang_jeondosa/post/d10085fc-5bfd-4ff0-9450-259979ced3b1/image.png" alt=""></p>
<ul>
<li><p>서버는 사용자가 로그인했을 경우 headers에 메타데이터를 보내 확인하는데, 해당 메타정보를 JWT(Jason Web Token)이라고 함.
<img src="https://images.velog.io/images/gonkang_jeondosa/post/7ec2eab7-85ed-4876-84d7-15eb964f3a35/image.png" alt=""></p>
<p>토큰이 우리서버에서 발급한게 맞는지 확인하기 위한 것.
개인정보를 담긴 담아야하는데, 우리 DB에서만 인식할 수 있는 값을 넣어준다</p>
<ul>
<li><p>헤더 <code>인코딩(암호화 아님)</code></p>
<ul>
<li>토큰타입과 해시알고리즘정보를 <code>BASE64</code>로 인코딩</li>
<li>인코딩은 암호화는 아님. 단 개인정보를 노출하지 않기
ex) {&quot;alg&quot;:&quot;HS256&quot;, &quot;typ&quot;:&quot;JWT&quot;}</li>
</ul>
</li>
<li><p>내용(payload) <code>인코딩(암호화 아님)</code></p>
<ul>
<li>Registered Claim : 만료시간 나타내는 exp 등 미리 정의된 집합</li>
<li>Public Claim : 공개용 정보전달을 목적으로 함 </li>
<li>Private Claim : 클라이언트-서버간 협의하 사용</li>
<li>위의 세 가지 요소를 조합하여 작성후 <code>BASE64</code>인코딩함
ex) {&quot;user-id&quot; : 1, &quot;exp&quot;:1539517391}</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li><h2 id="서명signature-암호화됨">서명(signature) <code>암호화됨</code></h2>
 <code>BASE64</code>로 인코딩된 <code>header</code>와 <code>playload</code>와 <code>JWT secret</code>을 헤더에 지정된 <code>양방향 암호 알고리즘</code>으로 함호화하여 전송<ul>
<li>프론트에서 전달받은 JWT의 서명부분을 백엔드 API에서 복호화 한 후, 서버에서 생성한 JWT가 맞는지 진본여부 확인</li>
</ul>
</li>
</ul>
<p><a href="https://swalloow.github.io/implement-jwt/"> 다른 읽어볼 자료
</a> </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Git]Git conflict]]></title>
            <link>https://velog.io/@gonkang_jeondosa/Git-conflict</link>
            <guid>https://velog.io/@gonkang_jeondosa/Git-conflict</guid>
            <pubDate>Fri, 18 Mar 2022 02:24:45 GMT</pubDate>
            <description><![CDATA[<h3 id="1-왜-발생하는지">1. 왜 발생하는지</h3>
<p><img src="https://images.velog.io/images/gonkang_jeondosa/post/12a746da-dd15-4403-bf94-20ec7e4cb603/image.png" alt="">
마스터시점에서 feature/main , feature/list로 나누어 두 사람이 작업을함
<img src="https://images.velog.io/images/gonkang_jeondosa/post/d661edcb-60ba-48e4-82e0-5cf1689fde01/image.png" alt=""></p>
<p>list가 먼저 pr한후 merge되어 업데이트 된 상황
main이 pull한후 push하였는데 충돌이 남.
원인은 list가 수정한 파일을 main도 수정했기 떄문</p>
<p>만약 공통의 파일을 동시간대에 두 사람이 건드렸다면, masters는 같은 내용중 누구의 것을 받아야되는지 판단이 어려워진다. 
이 때, 두 작업자에게 충돌됨을 고지하고 해결할 필요있음</p>
<h3 id="2-해결-프로세스">2. 해결 프로세스</h3>
<p>일단 후발작업자인 main작업자는 로컬에서 feature/main에서 master에 있는 내용을 가져와서 합쳐봐야한다</p>
<p><img src="https://images.velog.io/images/gonkang_jeondosa/post/b264313e-0d3f-4b01-a89f-1cdc1a9c39dd/image.png" alt="">
gir merge master</p>
<p>VS코드 좌측 공유작업 클릭하면 하기와같이 확인
<img src="https://images.velog.io/images/gonkang_jeondosa/post/ec515db8-2f02-4c30-955d-03f0b89ca813/image.png" alt="">
current change (내가 한거)
incoming change(남이한거 받아온거)</p>
<p><img src="https://images.velog.io/images/gonkang_jeondosa/post/e619ca14-d73b-4458-8275-09baeb510fd7/image.png" alt=""></p>
<p>버튼눌러서 수정하거나 지워서 수정할수있는데
처음에는 걍 직접 지워가며 수정할 것</p>
<p>수정이후에는 커밋 
<img src="https://images.velog.io/images/gonkang_jeondosa/post/782e9ab2-ea58-4c00-be0a-1c6d06fc287a/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/gonkang_jeondosa/post/05c7e760-b59f-4f47-b3a8-87358f3649b5/image.png" alt="">
리모트 마스터가 머징하려고하면 충돌메시지 상기와 같이 확인하게됨</p>
<p>후발주자는 자신의 로컬마스터로 이동해서 git pull origin master로 리모트 마스터의 내용을 가져온다
(충돌상황 확인해야하므로)</p>
<p><img src="https://images.velog.io/images/gonkang_jeondosa/post/9d8c2eee-c62d-4a6e-9529-0578957a901c/image.png" alt="">
PR내역에서 컨플릭 사항 먼저 확인하고 진행하자</p>
<p>이후 git checkout feature/main으로 이동해서 로그 확인(master의 내용이 없을것이다)
여기서 git merge master (마스터의 내용을 가져와서 feature/main에서 작업해보겠다. 마스터 내용은 건드리지말고, 브랜치 작업공간에서 수정하는걸로)</p>
<p>이 지점에서 팀원과 상의하거나 간단한것은 직접 의사결정해서 문서 수정한이후 동일하게 애드-커밋-푸시-피알</p>
<p>리모트 마스터가 merge하면 끝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TS] React CRA설치중 발생하는 에러(npm ERR! could not determine executable to run )]]></title>
            <link>https://velog.io/@gonkang_jeondosa/TS-React-CRA%EC%84%A4%EC%B9%98%EC%A4%91-%EB%B0%9C%EC%83%9D%ED%95%98%EB%8A%94-%EC%97%90%EB%9F%ACnpm-ERR-could-not-determine-executable-to-run</link>
            <guid>https://velog.io/@gonkang_jeondosa/TS-React-CRA%EC%84%A4%EC%B9%98%EC%A4%91-%EB%B0%9C%EC%83%9D%ED%95%98%EB%8A%94-%EC%97%90%EB%9F%ACnpm-ERR-could-not-determine-executable-to-run</guid>
            <pubDate>Wed, 16 Mar 2022 15:42:28 GMT</pubDate>
            <description><![CDATA[<pre><code>npx install create-react-app 경로명</code></pre><p>CRA섩치를 위해 터미널에서 상기와 같이 입력하면
아래의 에러를 만나게 됩니다..</p>
<blockquote>
<p>npm ERR! could not determine executable to run
<img src="https://images.velog.io/images/gonkang_jeondosa/post/17318da0-1640-49f8-88f8-856eb3270593/image.png" alt=""></p>
</blockquote>
<p>만약 당신이 이 문제에 직면했다면 당황하지 마시고..</p>
<p><code>npx &lt; install &gt; create-react-app 경로명</code></p>
<p>install을 빼주시면 정상적으로 설치됩니다...</p>
<p>이것 때문에 잡아먹은 1시간이 안타까워서 남깁니다...
혹시 도움이 되셨다면 따봉을 눌러주세요..저만 이런실수하나싶어 외롭습디다...</p>
]]></description>
        </item>
    </channel>
</rss>