<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Bright Root.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sat, 02 Jul 2022 08:28:34 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Bright Root.log</title>
            <url>https://images.velog.io/images/bright_root/profile/4120790c-1ad2-481b-b672-c71166d590e3/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Bright Root.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/bright_root" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[React.StrictMode 때문에 2시간..]]></title>
            <link>https://velog.io/@bright_root/React.Strictmode-%EB%95%8C%EB%AC%B8%EC%97%90-2%EC%8B%9C%EA%B0%84</link>
            <guid>https://velog.io/@bright_root/React.Strictmode-%EB%95%8C%EB%AC%B8%EC%97%90-2%EC%8B%9C%EA%B0%84</guid>
            <pubDate>Sat, 02 Jul 2022 08:28:34 GMT</pubDate>
            <description><![CDATA[<h2 id="2시간-날렸">2시간 날렸..</h2>
<p>호기심은 개발에 원동력이고, 
이러한 원동력은 내가 재밌게 개발하게 해준다.</p>
<p>혼자 그냥 간단하게 프로젝트를 하고있었다. </p>
<p>To do list 이런것 만들고 있었다. 타입스크립트로.
그리고 거기다가 css적으로 이쁘게 하는 것을 연습하기 위해서,
react-beautiful-dnd 패키지도 다운받았다.</p>
<p>그런데 다 순조롭게 되고 있었다. 목록에서 투두리스트가 드래그가 갑자기 안되었다.</p>
<p>되다가 안되다가를 반복했다. 이상했다.</p>
<p>아니 왜? 드래그 기능 하려고 뼈빠지게 유튜브보고 구글링하면서 했는데 왜안되지?</p>
<p>하아..코드 틀린것 없는데..뭐지...</p>
<p>에러난 부분을 복사해서 구글링해보았다.</p>
<p>React.StrictMode가 기능을 막고있다고 써있었다... 후...</p>
<pre><code>import React from &quot;react&quot;;
import ReactDOM from &quot;react-dom/client&quot;;
import &quot;./index.css&quot;;
import App from &quot;./App&quot;;

const root = ReactDOM.createRoot(
  document.getElementById(&quot;root&quot;) as HTMLElement
);
root.render(
  &lt;React.StrictMode&gt;
    &lt;App /&gt;
  &lt;/React.StrictMode&gt;
);</code></pre><p>저기서 저게 문제라고 한다, React.StrictMode..</p>
<pre><code>import React from &quot;react&quot;;
import ReactDOM from &quot;react-dom/client&quot;;
import &quot;./index.css&quot;;
import App from &quot;./App&quot;;

const root = ReactDOM.createRoot(
  document.getElementById(&quot;root&quot;) as HTMLElement
);
root.render(
  &lt;&gt;
    &lt;App /&gt;
  &lt;/&gt;
);</code></pre><p>이렇게 다시 만들어주니까 되다안되다가 불안정하게 동작 하던 것이 잘 되었다!!</p>
<p>저것은 무슨 힘을 가진것일까?</p>
<h2 id="그녀석의-역할">그녀석의 역할.</h2>
<p>공식문서에 따르면: React.StrictMode 는 나같이 개발하던 사람들에게는 눈에보이는데, 배포하고 나서는 저게 없어진다고 한다. 신기하네.</p>
<h3 id="그녀석의-조심성">그녀석의 조심성.</h3>
<p>그녀석 (React.StrictMode)는 우리에게 경고를 주는 것이다. 잘되라고 엄마같이 잘 챙겨주는 뜻인것같다. 하지만 뜻밖의 과보호는 우리를 에러의 바다에 넣고 왜 안될까라는 질문을 수십번 수백번 수천번 반복하면서 있게한다.
리액트는 렌더링 과 커밋 단계 두개로 동작한다.
랜더링 단계: render함수 (return)호출해서 이전 렌더와 비교 수행하는 단계.
커밋 단계: 라이프사이클 함수를 실행시키며 DOM 노드를 추가 또는 변경해주는 단계. 이것은 렌더링 보다 빠르다.
만약 렌더링이 느릴경우에, 그녀석이 개입해서 문제가 될만한 것들을 2번 실행해서 부작용을 잡아준다. 이것을 Double-Invoke방식이라고 한다. 그녀석이 개입해서 Double-Invoke를 하는데, 만약에 첫번째 시도와 두번째 시도를 했을 때 코드가 다르다? 그러면 문제가 있는 코드라는 것이다. 통 class component의 생명 주기 메소드인 componentWillMount()나 componentWillUpdate() 등에서 이런 형태가 나타나지만 setState에서 역시 이러한 현상들이 나타납니다. 당연히 setState와 같은 기능으로 사용되는 useState에서도 이러한 현상이 나타나는 경우가 있다.</p>
<p>리액트 공식 홈페이지 (<a href="https://ko.reactjs.org/docs/strict-mode.html)%EC%97%90%EC%84%9C">https://ko.reactjs.org/docs/strict-mode.html)에서</a> 이럴때 도움이 된다고 한다.</p>
<ul>
<li>안전하지 않은 생명주기를 사용하는 컴포넌트 발견</li>
<li>레거시 문자열 ref 사용에 대한 경고</li>
<li>권장되지 않는 findDOMNode 사용에 대한 경고</li>
<li>예상치 못한 부작용 검사</li>
<li>레거시 context API 검사</li>
</ul>
<p>주로 발생하는 함수:</p>
<ul>
<li>클래스 컴포넌트의 constructor, render 그리고 shouldComponentUpdate</li>
<li>클래스 컴포넌트의 getDrivedStateFromProps static 메서드</li>
<li>함수 컴포넌트 바디</li>
<li>State updater 함수(setState 의 첫 번째 인자)</li>
<li>useState, useMemo, useReducer 에 전달되는 함수</li>
</ul>
<p>그리고 내가 만든 투두리스트가 문제가 된 이유중 하나가 저녀석 때문이긴 하지만...얼마전에 리액트가 버전 업데이트했는데, 패키지 또한 새 버전에 맞게 업데이트를 해줘야하는데 못해줘서 그런것도 있다고 스택오버플로우에서 그런다..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[useEffect vs. useLayoutEffect ]]></title>
            <link>https://velog.io/@bright_root/useEffect-vs.-useLayoutEffect</link>
            <guid>https://velog.io/@bright_root/useEffect-vs.-useLayoutEffect</guid>
            <pubDate>Fri, 01 Jul 2022 05:51:11 GMT</pubDate>
            <description><![CDATA[<h2 id="useeffect를-제일-많이쓰고-uselayouteffect는-한번도-안써봄">useEffect를 제일 많이쓰고, useLayoutEffect는 한번도 안써봄..</h2>
<p>아니글쎄, 내가 어제, 가고싶었던 회사 면접을 봤는데...아니글쎄...나는 생각지도 못한질문을 듣게된다. </p>
<p>Q: useEffect와 useLayoutEffect 차이를 혹시 알고계신가요?</p>
<p>면접관님께서 물어보시는데...하아...순간...와 어디서 보긴했는데...</p>
<p>우선 내 성격상 솔직히 말씀은 드렸다..</p>
<p>render 와 paint 두가지가 있는데...순서가 다른 것으로 알고있습니다...</p>
<p>라고 말씀드리고 각각 설명하고...</p>
<p>Q: 어느 상황에 쓰시나요?</p>
<p>면접이라 긴장되는상황에 또 물어보시는데 하아...사실 써보진 않았다고 솔직히 말씀드리고...</p>
<p>저같으면,, 렌더링 전에 모든것을 보여주고 싶을때 useLayoutEffect...아니면 useEffect....</p>
<p>민오ㅓ림노리ㅗㅁㄴㅇ러ㅣㅏㅗㅇㄴ미ㅓ라ㅗㅁㅇ니ㅓㅏㅗㄹㅁㅇ니ㅏ롱ㅁ니ㅓㅏ롬이너ㅏ롬이나ㅓ롬ㄴ어ㅣㅏ로ㅓㅏㅣ</p>
<p>하아..모르겠다..사실 답은 맞긴하지만, 구체적이지도않고 너무 두리뭉실해서..집에 오는데 기차에서 계속 생각나갖고...</p>
<p>모르면 알아야지..그럼..알아야지 주니어개발자인데 몰라야지...몰라야 정상이지....가 아니고 정신차려 제발. ㅠㅠㅠ</p>
<h3 id="알아야할-것-side-effect">알아야할 것: Side effect</h3>
<p>이거 무슨 부작용같이 들리긴 하는데...찾아보니까 
&quot;React 컴포넌트가 화면에 렌더링된 이후에 비동기로 처리되어야 하는 부수적인 효과들이라고 한다.&quot;</p>
<blockquote>
<p><a href="https://www.daleseo.com/react-hooks-use-effect/#:~:text=Side%20Effect%EB%9E%80%3F,Side%20Effect%EB%9D%BC%EA%B3%A0%20%EC%9D%BC%EC%BB%BD%EC%8A%B5%EB%8B%88%EB%8B%A4">https://www.daleseo.com/react-hooks-use-effect/#:~:text=Side%20Effect%EB%9E%80%3F,Side%20Effect%EB%9D%BC%EA%B3%A0%20%EC%9D%BC%EC%BB%BD%EC%8A%B5%EB%8B%88%EB%8B%A4</a>.</p>
</blockquote>
<p>&quot;함수가 실행되면서 함수 외부에 존재하는 값이나 상태를 변경시키는 등의 행위.&quot; -&gt; &quot;함수에서 전역변수의 값을 변경하거나 혹은 함수 외부에 존재하는 버튼의 텍스트를 변경하거나, 파일을 쓰거나, 쿠키저장, 네트워크를 통해 데이터 송신하는 것 등. &quot; -&gt; 함수 밖의 비동기처리들?을 사이드 이펙트라고하나보다.</p>
<p>잘 생각해보면 함수 내부에서 뿐만아니라 외부에서도 동작하기 때문에 비용이 많이 들어 보일 수가 있다. 그런데 사실이다. 비용이 많이든다. 자바스크립트는 동기적으로 풀어나가는 프로그래밍에 비동기적인 요소들을 가미한 언어이다. 어쨌든 Side effect가 있는 일이라고 해도, 프로그램을 읽기 어렵게 하고, 실행상태를 예측하기 어렵게하며, 개발비용을 증가시킨다고 보기때문에 최소화 하는 것이 중요하다고 한다. 잘 생각해보면, 우리가 프로젝트를 할 때, 예측 불가능한 부수적인 효과들이 많을경우 앞으로 만들어진 웹앱에 대해서 유지보수가 힘들어지기 때문에 이것을 줄이는 것이 좋다. </p>
<p>이것을 위해서 useEffect가 등장한 것이다. 나는 단순히 useEffect부분에서만 랜더링을 원할경우, 또는 상태가 변할때 랜더링을 하기 원할경우에만 쓰는 것이라고 단순하게 생각했는데 이렇게 보니까 달라보인다.</p>
<h3 id="클래스형-컴포넌트에서-useeffect-훅-정리">클래스형 컴포넌트에서 useEffect 훅 정리.</h3>
<p>componentDidMount + compnentDidUpdate + componentWillUnmount = useEffect</p>
<pre><code>class Example exgtends Component{
    componentDidMount(){ // 컴포넌트가 마운트 되었을 때 실행되는 코드
    }
    componentDidUpdate(){ // 컴포넌트 리렌더링이 완료되었을 때 실행되는 코드
    }
    componentWiillUnmount(){ // 컴포넌트가 언마운트 되었을 때 실행되는 코드
    }
}</code></pre><p>여기서 componentDidMount + componentDidUpdate -&gt; useEffect내에서 함수역할, componentWillUnmount -&gt; 함수 형태로 return 하는 연할. </p>
<pre><code>useEffect(()=&gt;{

    //컴포넌트가 마운트 or 리렌더링이 완료되었을 때 실행되는 코드

    return () =&gt; {

    //컴포넌트가 언마운트 되었을 때 실행되는 코드

    }

}, [state, props, variables]); // 해당 사이드 이펙트 함수의 의존성 배열, 해당 의존성 배열의 요소 값이 변경 되면 useEffect 실행.</code></pre><h3 id="react-에서-side-effect처리">React 에서 Side-Effect처리</h3>
<pre><code>function UserProfile({name}){
    const message = `${name}님 환영합니다!`; // 함수 반환 값 생성

    //Bad!
    document.title = `${name}의 개인정보`; // 함수 외부와 상호작용하는 Side-effect 코드

    return &lt;div&gt;{message}&lt;/div&gt;
}</code></pre><p>여기서 document.title 이것은 함수내에서 생성하는 값이 아닌, 함수의 밖에서 가져온 값이다. 이런 코드가 이ㅏㅆ을 경우에 컴포넌트가 렌더링 될 때마다 프로그램을 지연시키게 될 것이라고 한다. 따라서 이것을 useEffect를 통해서 분리할 수 있도록 지원한다.</p>
<pre><code>function UserProfile({ name }) {
  const message = `${name}님 환영합니다!`;

  //Side-Effect 코드를 UseEffect로 분리
  useEffect(() =&gt; {
    document.title = `${name}의 개인정보`; 
  }, [name]);
  return &lt;div&gt;{message}&lt;/div&gt;;
}</code></pre><p>이렇게하면 코드가 최적화 되고, 컴포넌트 실행속도를 개선 가능하다고 한다.</p>
<p>여기서 잠깐. </p>
<p>이제 뭔지 알았다.</p>
<h2 id="그렇다면-useeffect와-uselayouteffect의-차이는">그렇다면, useEffect와 useLayoutEffect의 차이는?</h2>
<p>이제 게임 시작이다. 둘이 차이점은 무엇인가. 이름도 비슷비슷하고. 뭔데저거?</p>
<p>Render: DOM Tree를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정.
Paint: 실제 스크린에 Layout 을 표시하고 업데이트 하는 과정. </p>
<blockquote>
<ul>
<li>Render: DOM Tree를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정.</li>
</ul>
</blockquote>
<ul>
<li>Paint: 실제 스크린에 Layout 을 표시하고 업데이트 하는 과정.
useEffect - 컴포넌트들이 render와 paint된 후 실행. (비동기)
useLayoutEffect - 컴포넌트들이 render된 후 실행되며, 그 후에 paint가 된다. (동기)
useEffect는 DOM이 화면에 그려진 이후에 호출된다. useLayoutEffect는 DOM이 화면에 그려지기 전에 호출된다. 따라서 렌더링할 상태가 이펙트 내에서 초기화되어야 할 경우, useLayoutEffect를 활용해야합니다.</li>
</ul>
<p>친구한테 물어보니 이걸 보내줬다. 무엇인진 대충 알겠으나...흠...</p>
<blockquote>
<p><a href="https://pubudu2013101.medium.com/what-is-the-real-difference-between-react-useeffect-and-uselayouteffect-51723096dc19">https://pubudu2013101.medium.com/what-is-the-real-difference-between-react-useeffect-and-uselayouteffect-51723096dc19</a></p>
</blockquote>
<p>useEffect</p>
<blockquote>
<p><a href="https://pubudu2013101.medium.com/what-is-the-real-difference-between-react-useeffect-and-uselayouteffect-51723096dc19">https://pubudu2013101.medium.com/what-is-the-real-difference-between-react-useeffect-and-uselayouteffect-51723096dc19</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/bright_root/post/1a282a58-5061-4ba6-886f-eb135ee878c5/image.png" alt=""></p>
<p>useLayoutEffect</p>
<blockquote>
<p><a href="https://pubudu2013101.medium.com/what-is-the-real-difference-between-react-useeffect-and-uselayouteffect-51723096dc19">https://pubudu2013101.medium.com/what-is-the-real-difference-between-react-useeffect-and-uselayouteffect-51723096dc19</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/bright_root/post/0c5cc207-357d-4e03-b931-6090e2d3716f/image.png" alt=""></p>
<p>구체적인 예가 필요할것같다...</p>
<blockquote>
<p><a href="https://guiyomi.tistory.com/m/120">https://guiyomi.tistory.com/m/120</a></p>
</blockquote>
<p>여기 들어가보면 화면의 flickering (깜빡거림) 에대한 예를 제시하고 알려주신다.</p>
<p>useEffect와 같은 경우에는 render 된 후에 paint 와 layout이 다 실행 되고나서 useEffect가 동작한다. 그렇기 때문에, 깜빡거린다. </p>
<p>반면에 깜빡 거림을 없애고 싶다면, paint 일어나기전에 발생하는 useLayoutEffect를 사용하면 된다. 먼저 동작하고 그다음에 paint하고 layout을 그리기 때문이다. </p>
<h2 id="그렇지만">그렇지만.</h2>
<p>useLayoutEffect는 동기적으로 실행되고 내부의 코드가 모두 실행된 후 painting 작업을 거친다. 따라서, 로직이 복잡할 경우 사용자가 레이아웃을 보는데까지 시간이 오래걸린다. 그러므로 공식문서에서도 그렇고 왠만하면 useEffect만을 사용하는 것을 권장한다고 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React vs Angular vs Vue]]></title>
            <link>https://velog.io/@bright_root/React-vs-Angular-vs-Vue</link>
            <guid>https://velog.io/@bright_root/React-vs-Angular-vs-Vue</guid>
            <pubDate>Wed, 29 Jun 2022 06:26:33 GMT</pubDate>
            <description><![CDATA[<h2 id="갑자기-알고싶어진">갑자기 알고싶어진..</h2>
<p>채용공고를 훑어볼때 내가 유일할게 할 수 있는 것은 React이기 때문에, 필터를 그것으로 해놓고 회사들을 검색한다. 검색해보면 굉장히 많은 회사들이 눈에 보이고, 기술 스택을 보면, 프론트개발에서 Angular, React, Vue가 눈에 띄었다.</p>
<p>이 세개에 대해서 알고싶어졌다.</p>
<p>Reference:</p>
<blockquote>
<p><a href="https://javascript.plainenglish.io/angular-vs-react-vs-vue-js-which-is-the-best-choice-for-2022-5ef83f2257ab">https://javascript.plainenglish.io/angular-vs-react-vs-vue-js-which-is-the-best-choice-for-2022-5ef83f2257ab</a></p>
</blockquote>
<p>이글을 바탕으로 정리를 했다.</p>
<h2 id="자바스크립트가-최고인-세계">자바스크립트가 최고인 세계.</h2>
<p>의심의 여지없이, 당연히 자바스크립트는 프론트엔드 프레임워크 중에서 대중적으로 가장 많이 알려지고 사랑받고있다. </p>
<p>지난 2년간 NPM 다운로드 트랜드를 보면 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/bright_root/post/b75d26fb-bba6-4906-9231-2c9b925c3dc8/image.png" alt=""></p>
<blockquote>
<p><a href="https://www.npmtrends.com/angular-vs-react-vs-vue">https://www.npmtrends.com/angular-vs-react-vs-vue</a></p>
</blockquote>
<p>리액트가 압도적으로 다른 프레임워크들에 비해 월등히 앞선다.</p>
<p>스택오버플로우의 질문들 통계를 보면 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/bright_root/post/4fab00dc-2371-4cba-9d84-f2392d6a582c/image.png" alt=""></p>
<blockquote>
<p><a href="https://insights.stackoverflow.com/trends?tags=angular%2Creactjs%2Cvue.js">https://insights.stackoverflow.com/trends?tags=angular%2Creactjs%2Cvue.js</a></p>
</blockquote>
<p>리액트가 이것도 압도적으로 증가하고있고, 앵귤러는 감소추세, 뷰도 살짝 감소추세가 있긴하다.</p>
<p>&quot;리액트가 짱이다.&quot; 라는 것을 말하기보단, 트렌드를 보기보단, 다른 언어들을 알고싶었다.</p>
<h2 id="간단한-특징들">간단한 특징들</h2>
<h3 id="react">React</h3>
<ul>
<li>2013년 런칭 by Jordan Walke, Facebook</li>
<li>Virtual Dom</li>
<li>단방향 컴포넌트 바인딩 (부모-&gt; 자식)</li>
<li>SSR: Next.js</li>
<li>JSX (Javascript eXtensional markup language)</li>
<li>React Native로 앱개발 가능.</li>
<li>중간단계의 러닝커브</li>
</ul>
<h3 id="angular">Angular</h3>
<ul>
<li>2009년 런칭 by Misko Hevery &amp; Adam Abrons</li>
<li>Type Script 기반</li>
<li>양방향 바인딩</li>
<li>RxJS (Reactive Extensionf for JavaScript): 스트림통한 비동기처리방식 지원.</li>
<li>굉장한 러닝커브..</li>
</ul>
<h3 id="vue">Vue</h3>
<ul>
<li>2014년 런칭 by Evan You</li>
<li>Type Script 기반</li>
<li>양방향과 단방향 다 지원.</li>
<li>Virtual Dom 지원</li>
<li>SSR: Nuxt.js</li>
<li>NativeScript 앱 개발 가능</li>
<li>Single File Component - HTML, CSS, Script까지 하나로 묶어서 컴포넌트 단위로 직관적으로 구성.</li>
<li>낮은 러닝커브</li>
</ul>
<p>내가 봤을땐, 정말 개인적으로...음 많은 사람들의 의견도 들어보았을 때, 지금은 리액트가 트렌디하다고 본다. 사실 Angular도 장점을 많이 가지긴 하지만, 뭔가 러닝커브라던가, 무거운 느낌이 다른것에 비해 다소 들기 때문에, 배우기 쉽고 여러 기능으로까지 확장가능한 뷰나 리액트로 사람들이 선호하지 않을까 생각한다. </p>
<p>그리고 나는 솔직히 리액트를 사용하는 것이 편한것 같다. 하지만 뷰를 보니까 무엇인가 가장 젊은 프레임워크이기도하고, 리액트와 앵귤러의 장단점을 고루고루 다 가져온것같아서 좋다. 
그리고 언어를 보았을때, 자바스크립트에서 더 발전한 정적타입의 타입스크립트가 무엇인가 앞으로 언어적으로 자리잡지않을까 라는 생각이 든다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[컴파일 -> 빌드 -> 배포 개념잡기]]></title>
            <link>https://velog.io/@bright_root/%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EB%B9%8C%EB%93%9C-%EB%B0%B0%ED%8F%AC-%EA%B0%9C%EB%85%90%EC%9E%A1%EA%B8%B0</link>
            <guid>https://velog.io/@bright_root/%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EB%B9%8C%EB%93%9C-%EB%B0%B0%ED%8F%AC-%EA%B0%9C%EB%85%90%EC%9E%A1%EA%B8%B0</guid>
            <pubDate>Tue, 28 Jun 2022 02:20:34 GMT</pubDate>
            <description><![CDATA[<h2 id="대충-알았던-내용들">대충 알았던 내용들</h2>
<p>프로젝트를 혼자하든 팀원들이랑 같이하든, 나는 기능에 집중해서 만드는 것을 참 좋아한다. 그런데, 내가 마무리 하는 단계에 있어서, CI/CD, 아마존배포 등 이런것에 약하다. 왜냐하면, 항상 팀원들이 마지막 단계를 끌고가다시피했다. 무슨말이냐하면, 나는 무엇을 만들까에 대해서만 집중했지, 만들고나서 이것을 어떻게 해야할지에 대해 생각을 잘 못했다는 말이다. 그래서인지, 다른 것을 배울때보다 별로 신경도 안쓰게 되었고, 집중도 되지 않았다. 그래서 대충 뭔지에 대해서 안다. 이번 기회를 통해 깔끔하게 정리하도록. 이상.</p>
<p>굉장한 비유와 배움을 얻었습니다. 
참고: <a href="https://itholic.github.io/qa-compile-build-deploy/">https://itholic.github.io/qa-compile-build-deploy/</a></p>
<h2 id="컴파일-빌드-배포의-개념-및-차이">컴파일, 빌드, 배포의 개념 및 차이</h2>
<ol>
<li><p>나는 번역가이다. -&gt; 나는 개발자이다.</p>
</li>
<li><p>출판사로부터 일을 하나 받았다. -&gt; 고객이든 누구든 아무튼 누군가가 나에게 개발을 요청했다.</p>
</li>
<li><p>영문으로된 글을 한글로 번역하는 일이다. -&gt; 고수준 언어를 저수준 언어로 기계가 이해할 수 있게 하는과정이다. 컴파일 과정이다. </p>
</li>
<li><p>출판사에서 번역된 글들을 적절히 엮어서 책으로 출판할 것이다. -&gt; 이 과정이 빌드이다. (3. ~ 4.)</p>
</li>
<li><p>출판된 책들은 서점에 진열되어 팔릴것이다. -&gt; 배포한다.</p>
</li>
</ol>
<p>이것만 보고서 뭔가 이해가 갑자기 확 되긴 했으나, 그래도 뭔가 글로 제대로 머리에 넣어야할 것 같다.</p>
<ul>
<li>컴파일: 사용자가 작성한 고수준 언어를 컴퓨터가 이해 할 수 있는 저수준 언어로 바꾸는 일</li>
<li>빌드: 컴파일된 코드를 실제 실행할 수 있는 상태로 만드는 일.</li>
<li>배포: 빌드가 완성된 실행 가능한 파일을 사용자가 접근할 수 있는 환경에 배치시키는 일.</li>
<li>컴파일을 포함해 war, jar등의 실행 가능한 파일을 뽑아내기까지의 과정을 빌드한다고 하기도 한다고 한다.</li>
</ul>
<p>여기서 내가 프로젝트 하면서 들었던 이야기들이 있다. 빌드 자동화, 배포 자동화, 테스트 자동화?</p>
<p>자동화 하면 뭔가 공장에서 찍어내는 기계들이 생각이 나긴한다. 이것도 비슷한 내용일 거라는 생각이 들긴하지만~</p>
<h2 id="반복되는-작업들">반복되는 작업들</h2>
<p>완성된 코드를 서버에 올리고 나서가 본격적으로 개발의 시작이라고 할 수 있다고 한다.
왜냐하면 사용자들이 앱을 사용하고나서 버그가 발견되고, 그것을 통해 개선사항이 등장할 것이고, 컴파일, 빌드, 배포등의 과정이 코드수정 후에 반복되어야 하기 때문이다.
이렇게 된다면 너무 비효율적이기 때문이다. 만약 서비스 중인 프로그램의 코드를 변경 한다고 할 경우에, 더 비효율적이다. 또한 이렇게 수정하고 난 코드가 잘 동작하는지 알기 위해서는 테스트 코드도 작성하고, 검증도 다시 한번 하면서 검토하는 등 많은 작업이 필요하다.
이러한 과정들은 복잡하고 사람이 하면 할수록 실수가 나올 수 있기 때문에 
&#39;자동화&#39;가 만들어진것이다.</p>
<p>우리가 자주쓰는 깃 또는 깃헙.
여기다가 그냥 수정된 코드를 올려놓고 나머지는 자동으로 수행되는 것이다. 그리고 위에 과정들이 다 끝나면 자동으로 개발자에게 리포트해준다. 이 과정에서 어느 부분을 자동화 시킬 것인지에 따라 빌드자동화, 배포 자동화, 테스트 자동화 라는 용어가 붙은 것이라고 한다.</p>
<p>그 다음에 CI/CD라는 개념으로 가야한다. 왜냐하면, 자동화 이야기 하고나서 팀원들이 CI/CD하는 곳도 있다던데? 이러면서 다른 조 얘기 많이했다.</p>
<h2 id="cicd란">CI/CD란?</h2>
<h3 id="ci---continuous-integration">CI -&gt; Continuous Integration</h3>
<p>모든 개발이 끝난 이후에 코드 품질을 관리하는 고전적방식의 단점을 해소하기 위해 나타난 개념. 개발을 지속적으로 하면서 코드에 대한 통합을 진행함으로써 품질을 유지하자! 라는 의미.</p>
<p>예)
팀프로젝트를 상상해보면, 팀원들과 나는 깃헙 주소를 각각 클론 받아서 작업을 시작했다. 그리고 나서, 각 깃헙 컨벤션에 따라서 중앙저장소에 코드가 올라간다. 그런데 만약 팀원들이 귀찮아서 안올린다면? 할줄 몰라서 안올린다면 ? (나 깃헙 아무것도 몰랐을때 저랬다...)</p>
<p>이렇게 된다면 나중에 빌드 배포 테스트 이 과정이 정말 최악이고 귀찮은 작업이 된다. 내가 경험해봐서 안다.</p>
<p>작업을 잘 나누어서 일정한 어느 섹션의 작업이 끝날 때마다, 코드에 대해 리뷰 하고 테스트해보고 점검하는 것이 더 효율적이다.</p>
<p>이렇게 하게 된다면, 나중에 최종적인 작업세션에 다다랐을때 보다 높은 퀄리티의 코드를 가질 수 있고, 버그에 대한 개선사항도 줄일 수 있다. </p>
<p>단점: 귀찮다. 모든 인간들은 미리 하는 것에 대해 귀찮음을 느낀다.</p>
<p>그렇기 때문에 이 부분에 대해서 자동화를 돌리면 어떨까 라는 생각에 나온 것이다.</p>
<h3 id="cd---continuous-deploy-or-delivery">CD -&gt; Continuous Deploy or Delivery</h3>
<p>소프트웨어가 항상 신뢰 가능한 수준에서 배포될 수 있도록 지속적으로 관리하자는 개념.</p>
<p>단순하게, CI의 연장선이라고 생각하면 된다.</p>
<p>완전한 설명: CI프로세스를 통해 개발중에 지속적으로 빌드와 테스트를 진행하고, 이를 통과한 코드에 대하여 테스트서버와 운영서버에 곧바로 그 내용을 배포해 반영하는 것이다.</p>
<p>CI (빌드 및 테스트 자동화) + CD (배포 자동화)</p>
<p>이것을!!!!</p>
<p>도와주는 솔루션들이 있는데 그것들이~</p>
<p>CircleCI, Travis, Jenkins, Github Actions 등등.</p>
<p>와 이제 뭔지 알게되었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[useCallback vs. useMemo]]></title>
            <link>https://velog.io/@bright_root/useCallback-vs.-useMemo</link>
            <guid>https://velog.io/@bright_root/useCallback-vs.-useMemo</guid>
            <pubDate>Mon, 27 Jun 2022 01:40:56 GMT</pubDate>
            <description><![CDATA[<h2 id="반드시-알아야-하는">반드시 알아야 하는~</h2>
<p>리액트 훅에 대해서 저번에 한번 정리를 하기 했으나, 완벽하진 않은것 같다.
특히, 내가 요즘 VS CODE에다가 혼자 사용해보면서 우오 이렇구나를 느끼고 있는데, 
usCallback과 useMemo가 헷갈린다. 그리고 useCallback은 내가 심지어 써본 것이기도 한데 이상하게 머릿속에 생각이나지않는다. 내 기억에 이 두개의 차이는 면접에서도 물어본 것 같다. 어찌어찌 대답은 했으나, 딱 들어봤을때 &#39;잘 알지 못하고 일단 외운대로 말하는구나&#39; 라는 인상을 심어줬던 것 같다. </p>
<h2 id="크게-보았을-때의-차이">크게 보았을 때의 차이.</h2>
<p>usCallback과 useMemo는 메모이제이션 된 값을 반환한다. 차이점은 useCallback은 함수를 메모이제이션하고 useMemo 는 값을 메모이제이션한다. </p>
<p>메모이제이션이란?
위키피디아에서는: &quot;메모이제이션(memoization)은 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술이다. 동적 계획법의 핵심이 되는 기술이다.&quot;</p>
<h2 id="차이를-보기전에-알아야-할-것들">차이를 보기전에 알아야 할 것들.</h2>
<p>이 글은 철저히, </p>
<blockquote>
<p><a href="https://leego.tistory.com/entry/React-useCallback%EA%B3%BC-useMemo-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0">https://leego.tistory.com/entry/React-useCallback%EA%B3%BC-useMemo-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</a> </p>
</blockquote>
<p>이곳에서 참고했고, 정리했다. 감사드립니다. 예시도 여기서 확인바란다. 굉장히 정리를 기가막히게 잘해놓으셨다.</p>
<p>리액트에서 리렌더링은 굉장히 중요하다. 성능 향상과 저하에 엄청난 영향을 준다. 
우선 리렌더링 되는 조건은 (1) state가 변경될 때, (2) 부모컴포넌트로부터 props가 변경될때, (3) 부모 컴포넌트가 리렌더링될때 이렇게 3가지이다. </p>
<p>하지만 이 세가지 조건을 다 따르는 컴포넌트들이 만들어 졌다고 하자. 예를 들어, useState를 사용하여 값 (state)이 버튼이라는 컴포넌트를 누를때마다 바뀌고, 이것을 부모 컴포넌트에서 관리 한다고 하자. 여기서 이 모든 세가지 조건이 발동하여, 어느 부분을 누르든 모든것이 리렌더링 될 것이다. 물론, 가끔가다가 어떤 웹을 보면, 의도적으로 이렇게 만들어서, 동작하는 것도 있긴하지만. 이 세가지를 다 포함하는 컴포넌트를 만들게 된다면, 어딜 누르나 상태변화가 일어나기 때문에, 동작이 하나만 되도록 붙잡아 놓는 것이 좋다. 즉, 리렌더링을 줄여아한다.</p>
<h3 id="reactmemo">React.memo</h3>
<p>이름만 봐도 알 수 있듯이, 메모이제이션을 해준다. 특히 이 기능은, 부모컴포넌트로 넘겨받은 props가 같다면 메모이제이션 해둔 렌더링 결과를 가져온다. 메모이제이션한 내용을 재사용하여 렌더링시 가상 DOM에서 달라진 부분을 확인하지 않아 성능상의 이점이 생기게 된다고 한다. </p>
<p>사용법</p>
<pre><code>const MyComponent = React.memo(function MyComponent(props){
렌더링 하는 곳. 
});</code></pre><pre><code>function MyComponent(props){
렌더링 하는 곳.
}
export default React.memo(MyComponent, areEqual);</code></pre><p>하지만, 이것을 반드시 알아야한다. 리렌더링 될 경우에, 새로운 함수를 계속 생성한다. 
React.memo를 이미 사용하여, 메모이제이션되서 리렌더링을 일으키지 않는 컴포넌트가 있다. 그런데, 다른 컴포넌트때문에 리렌더링이 일어났다. 이렇게 될 경우, React.memo가 고장난 것이 아니라, 판단의 오차가 발생 하기 때문이다.</p>
<p>&quot;컴포넌트는 리렌더링 할 때 마다 새로운 함수를 계속 생성하며, React.memo는 부모 컴포넌트로 넘겨받은 props가 변경되었다고 판단하여 계속 리렌더링 하는 것이다.&quot;</p>
<p>내가 참고한 블로그에서 글쓴이는 이와같은 예시를 들어주어서 나의 이해를 높여주었다.</p>
<p>object !== object
리렌더링이 발생되면 해당 컴포넌트의 객체들은 다시 생성된다. -&gt; 함수도 객체이다!!!!!!
처음알았음...함수도 객체라는 사실... 감사합니다...
자바스크립트에서 객체는 참조타입으로 완전히 동일한 값을 가지고 있더라도 참조하는 메모리의 주소가 다르면 서로 다른 객체로 취급한다고 한다.</p>
<p><img src="https://velog.velcdn.com/images/bright_root/post/24bf7c6b-71bc-4170-a0c0-337beef4c2a0/image.png" alt=""></p>
<p>안에 값들이 같더라도 서로 다른 객체를 취급하는 것을 볼 수 있다. wow와 amazing은 같다. 왜냐면 amazing이 wow에서 가져와씩 때문이다. 그러나 wow를 값이 똑같은 새로운 것과 비교했더니 다르다고 한다. 그것은 메모리에 저장된 주소값이 다르기 때문에 그런 것이다. </p>
<p>&quot;컴포넌트는 리렌더링할 때 마다 새로운 함수를 계속 생성하며, React.memo는 부모컴포넌트로 넘겨받는 props가 변경되었다고 판단하여 계속 리렌더링라는 것이다.&quot;</p>
<p>이것을 고치기 위해서, useCallback과 useMemo는 여기서 발생하는 불필요한 렌더링과 불필요한 계산을 방지하는 목적으로 설계되었다고한다.</p>
<h3 id="usecallback">useCallback</h3>
<p>사용법</p>
<pre><code>const 콜백사용법 = useCallback(
()=&gt;{
  doSomething(a, b);
}, 
[a, b], // dependencies
);</code></pre><p>deps안에 넣어준 값이 바뀔때마다 새로운 객체를 생성해준다.
-&gt; 즉, 한번만 렌더링 될 뿐, 리렌더링은 절대 안된다. </p>
<h3 id="usememo">useMemo</h3>
<p>사용법</p>
<pre><code>const 메모이제이션훅사용법 = useMemo(()=&gt; computeExpensiveValue(a,b), [a, b]);</code></pre><p>예시</p>
<pre><code>function App(){
...
return(
    &lt;div className=&quot;App&quot;&gt;
        &lt;div className=&quot;num&quot; onClick={()=&gt;{setNumber(number+1)}}&gt;
            {number}
        &lt;/div&gt; 
        &lt;Button onClick={onClick} style={{backgroundColor: &#39;darkseagreen&#39;}}/&gt;
    &lt;/div&gt; 
...);
}</code></pre><p>이렇게 만들어줄 경우에, 분명히 리렌더링이 모두에게 발생하고, 렌더링시마다 새로운 객체가 만들어진다. 컴퓨터는 메모리에 새로운 주소값을 계속 넣어주고 있을 것이다.</p>
<p>이럴때 useMemo로 값을 홀드해주는 것이다. 그러면 리렌더링이 안되게 방지시킬수있다. 
한마디로 컴퓨터에게 이거 내가 deps에다가 값 넣어주지 않는이상 리렌더링 해주지마. 라고 말을 해주는 것이다. </p>
<pre><code>function App(){
...
const buttonStyle - useMemo(() =&gt; ({backgroundColor: &#39;darkkseagreen&#39;}), []);

return(
    &lt;div className=&quot;App&quot;&gt;
        &lt;div className=&quot;num&quot; onClick={()=&gt;{setNumber(number+1)}}&gt;
            {number}
        &lt;/div&gt; 
        &lt;Button onClick={onClick} style={{buttonStyle}}/&gt;
    &lt;/div&gt; 
...);
}</code></pre><p>이럴경우 다시 렌더링이 일어나지 않는다. </p>
<p><img src="https://velog.velcdn.com/images/bright_root/post/b3587da0-2356-4f07-a0b8-f02f31691b78/image.png" alt=""></p>
<p>deps에는 반드시 의존하는 값이 있으면 넣어줘야한다. 없더라도 반드시 빈 대괄호라도 넣어주는거 잊지말고.</p>
<h3 id="최적화를-위해서는-불필요한-리렌더링을-줄이는-것이-또하나의-관건이다---그래서-usecallback과-usememo를-알아야한다">최적화를 위해서는 불필요한 리렌더링을 줄이는 것이 또하나의 관건이다. -&gt; 그래서 useCallback과 useMemo를 알아야한다.</h3>
<p>지금 정리는 했는데 써보러 가봐야제~</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ECMAScript???]]></title>
            <link>https://velog.io/@bright_root/ECMAScript</link>
            <guid>https://velog.io/@bright_root/ECMAScript</guid>
            <pubDate>Sat, 25 Jun 2022 05:56:49 GMT</pubDate>
            <description><![CDATA[<h2 id="ecma-script-6-es6-">ECMA SCRIPT 6 (ES6) ???</h2>
<p>항상 공부를 할때, 개념을 알기 전에는 왜 그런것이 나왔나를 살펴보는 것이 중요하다.
그래서 역사를 배우는 것이다. 역사는 명분에 따라 움직이기 때문에..전쟁, 발명, 개척 등등, 모두 명분을 만들어서 하는 것들이다. 아무튼 저 요상한 것의 탄생의 비밀부터 시작해보자.</p>
<h3 id="자바스크립트란">자바스크립트란?</h3>
<p>개발자로 커리어 전환하면서 쓰는 나의 메인 언어. 자바스크립트는 1995년 Netscape 웹 브라우져 회사에서 웹페이지에 동적인 요소를 구현하기 위해서 만들어졌다고 한다. 많은 다른 웹 브라우저들이 자바스크립트를 사용하기 시작했고, 그 결과로, 우리가 흔히 볼 수 있는 웹 어플리케이션이 여기저기 나타났다. </p>
<h3 id="ecmascript-라는건">ECMAScript 라는건?</h3>
<p>이렇게 자바스크립트가 점점 다른 웹 브라우저들을 지원하기 시작하면서, 표준 규격이 필요했다. 그래서, ECMA 인터내셔널이라는 국제기구에서 &quot;ECMAScript Standard&quot;라고 불리는 스크립트 표준이 만들어지게 된다. 여기서, 자바스크립트와 ECMA스크립트랑 헷갈린다. 그전에 스크립트라는 공통점이 있는데, 스크립트 언어에 대해서 이번 기회에 좀 파악 해야 할 것 같다.</p>
<h3 id="script-언어란">Script 언어란?</h3>
<p>스크립트 언어라는 것은, 독립된 시스템에서 작동하도로고 특별히 설계된 프로그래밍 언어라고 한다. 여기서 &quot;독립된&quot;이라는 말이 정말 중요한 것 같다. 다시 말하자면, 프로그램을 쓰는 사용자가, 의도에 따라서 동작을 시킬 수 있게 하는 것이다. 스크립트 언어를 이용한 명령어의 실행이, 시스템 내부에서 어떤 원리로 동작하는지 전혀 상관없이, 사용자의 의도에 따라 제어 가능하다는 뜻이다. </p>
<h3 id="그래서-어떻게-이해하면-되는건가요">그래서 어떻게 이해하면 되는건가요?</h3>
<p>Java Script -&gt; 1996년생.
ECMA Script -&gt; 1997년생.</p>
<p>&quot;Java Script는 ECMA Script의 사양을 준수하는 범용 스크립팅 언어이다.&quot;</p>
<p>Java Script는 ECMA Script와 BOM (Browser Object Model) 와 DOM (Document Object Model) 이라는 1개의 코어와, 2개의 모델로 이루어져 있다. </p>
<h2 id="es6-이건">ES6 이건?</h2>
<p>ECMA SCRIPT 6라는 것이고, ECMA-262 표준의 제 6판이라는 뜻이다. 이것은 ECMA Script 사양의 주요 변경 사항 및 개선 사항을 말해준다. 동의어로는 ES6, ES2015, ECMAScript 2015 라고 한다. 
ECMAScript 는 국립국어원 표준어 제정하는곳이라고 생각하면 되는 것이고, 매년 해의 이름을 딴 ECMAScript가 새로 발표된다.
현재 제일 최신 버전은 2021년 6월에 출시한 ECMAScript 20201(ES2021), 12th Edition 이다. 
그런데 왜 ES6를 언급을 많이할까? 왜 내눈에 많이 띌까? 들릴까? 왜?</p>
<p>ES6 는 굉장히 많은 변화가 있던 업데이트다. 구버전 웹브라우저 (Internet Explorer)및 레거시 코드와의 호환성 문제가 심각할 정도로 대격변이 일어났고, 호환성 문제가 엄청나게 발생했다. 그래서 ES6 이후에 표준으로 생긴 기능들이 많기 때문에 중요하게 다루어 진다고 한다. 
즉, 이시기에 새로 추가된 많은 문법과 개념이 생겨났고, 그 이전의 표준에는 설명이 없다. 그렇기 때문에 중요하다는 말이다. 
ECMAScript 6. </p>
<h2 id="주요-기능-업데이트-부분">주요 기능 업데이트 부분.</h2>
<ol>
<li>Class </li>
<li>let &amp; const</li>
<li>Arrow Function</li>
<li>Module</li>
<li>Promise</li>
<li>비구조화 할당 지원</li>
<li>객체 리터럴</li>
<li>Template literals</li>
<li>매개변수 기본값</li>
</ol>
<p>물론 구글링해서 중요하다고 보는 것들로 구성을 했고, 이것을 기반으로 주요 기능이라고 말하는 것이다. </p>
<h3 id="class">Class</h3>
<p>사실 자바 공부 할때부터 이상하게 별거 아닌것 같은 개념인데 클래스, 프로토타입, 인스턴스 등등 이름이 어려워서 그런지 좀 어렵게 느껴진다. 그래서 구글링을 한 2시간 동안 해보면서 이해하려고 공부를 해보았다. </p>
<p><img src="https://velog.velcdn.com/images/bright_root/post/bb20094c-cb8c-44d1-b645-f8ad89ff0f5f/image.png" alt=""></p>
<p>그림에 나와있는 메커니즘으로 ES5프로토타입에서 ES6 클래스의 변화를 볼 수 있다. </p>
<p>-ES5</p>
<pre><code>var Person = (function () {
  // Constructor
  function Person(name) {
    this._name = name;
  }

  // public method
  Person.prototype.sayHi = function () {
    console.log(&quot;Hi! &quot; + this._name);
  };

  // return constructor
  return Person;
})();

// 인스턴스 생성
var me = new Person(&quot;Lee&quot;);
me.sayHi(); // Hi! Lee.

console.log(me instanceof Person); // true</code></pre><p>-ES6</p>
<pre><code>class Person {
  // constructor
  constructor(name) {
    this._name = name;
  }

  sayHi() {
    console.log(`Hi! ${this._name}`);
  }
}

// 인스턴스 생성
const me = new Person(&quot;Lee&quot;);
me.sayHi(); // Hi! Lee

console.log(me instanceof Person); // true</code></pre><p>Person 객체가 생성되면 prototype과 생성자 함수가 생기고 이를 기반으로 인스턴스를 new 예약어로 생성 가능하며 인스턴스는 <strong>proto</strong> 로 다시 Person.prototype 을 가르키게 된다.</p>
<p>이건 한번 제대로 다시 공부해야할것같다. 쉽지않다.</p>
<h3 id="let--const">let &amp; const</h3>
<p>이걸 모르면 지금까지 타입스크립트 쓴 의미도 사라지고, 프로젝트 할 때 진짜 생각없이 해본 것이다. 써봤던 사람은 적어도 왜 썼는지 알아야한다.</p>
<p>let과 const는 블록 스코프, var는 함수 스코프.</p>
<p>셋다 변수 선언 할 때 쓰이는 것이긴 한데,</p>
<ol>
<li><p>var
문제가 많다. 초보자가 좋아할것이다. 함수블럭만을 스코프로 인정하여 전역변수 남용이 발생한다. 변수 선언이 중복적이든 그 이전에 참조를 하든 다 가능하다. 
그렇기 때문에 let과 const가 만들어진것이다.</p>
</li>
<li><p>let &amp; const
블록스코프로 사용한다. 변수 중복 선언이 안된다! 
let은 변수에 재할당이 가능하지만, const는 변수 재선언, 변수 재할당 모두 불가능.
변수 선언 이전에 var같이 참조 이런게 절대 안된다. 왜냐하면 호이스팅 동작은 var와 같지만, 선언 → 초기화 → 할당의 기본 주기중 선언과 초기화 사이에 TDZ(Temporal Dead Zone)이 추가되며 선언 사각지대를 형성하기 때문에 선언 이전 참조시 에러를 발생시키기 때문이다.</p>
</li>
</ol>
<p>나는 그래서 그냥 조용히 const만 쓴다. 이게 개발자로써 맞는것일지는 모르겠지만, 그냥 꽉 묶어놔야 에러도 적게 발생할 것이고, 일단 내가 선언한 변수, 메모리에 할당한 값이 막 바뀐다고 생각해보자. 내가 웹을 만드는데 가뜩이나 보면 머리아픈 상황에 변수까지 바뀐다? 와우...</p>
<h3 id="arrow-function">Arrow Function</h3>
<p>ES6 이전 -&gt; 내가 제일 즐겨썼고, 기본적인 형태</p>
<pre><code>function foo() {
  console.log(&quot;foo&quot;);
}</code></pre><p>ES6 이후 -&gt; 내가 요즘 기본적으로 쓰는 형태, 자바스크립트 하면서 제일 흔하게 쓴다.</p>
<pre><code>const foo = () =&gt; {
  console.log(&quot;foo&quot;);
}</code></pre><p>일반함수와 화살표함수의 차이 -&gt; 일반함수는 자신만의 데이터를 가질수있지만, 화살표함수는 안된다. </p>
<pre><code>function fun(arg){
    console.log(arg)
    return arg
}
fun(1) //1이 출력됩니다.

let fun2 = (arg)=&gt;{
    console.log(arg)
    return arg
}
fun2(1)   //1이 출력됩니다. </code></pre><pre><code>function fun(arg){
    this.name = arg
}
new fun(1234).name  //1234가 출력됩니다.

let fun2 = (arg)=&gt;{  //new 연산자를 통한 생성은 불가능
    this.name = arg
}
new fun2(1234).name  //에러발생!</code></pre><p>이런것까지는 잘...몰랐다..</p>
<h3 id="module">Module</h3>
<p>export, import를 통해 나누어서 개발된 파일간의 관계를 유지해준다.
export를 파일에서 써주고, 다른 파일에서 import를 해주면 export한 파일을 참조한다.</p>
<pre><code>* test.js
export const test_number = 1234

* test2.js
import * as testCode from &quot;./test.js&quot;

console.log(testCode.test_number)  //1234</code></pre><h3 id="promise">Promise</h3>
<ul>
<li>비동기 프로세스 진행시, 순서를 보장할때 사용한다. AJAX~</li>
</ul>
<pre><code>let prom = (num) =&gt; {
    return new Promise((res, fail) =&gt; {
        if (num &gt; 4) {
            res(num)  //성공이면,
        } else {
            fail(&quot;err&quot;)  //에러발생
        }
    })
}

prom(5)
    .then(val =&gt; console.log(val)) // 5 출력
    .catch(err =&gt; console.log(err))</code></pre><p>나중에는 async await 나왔슴!</p>
<h3 id="비구조화-할당">비구조화 할당</h3>
<p>이거는 내 지인들이랑 내가 맨날 말할때마다 명칭이 바뀐다.
어떤 사람은 구조분해할당, 어떤사람은 분해구조 할당, 어떤사람은 구조화 분해 할당 기타등등
나는 깔끔하게 비구조화할당으로 말할것이다. 앞으로.</p>
<p>한마디로 하자면, 구조가 없는 객체를 알맞게 처리하도록 돕는 기능이다.</p>
<pre><code>//일반적인 사용 방법
let arr = [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;]
let [one, two, three] = arr
console.log(one) // 1
console.log(two) // 2
console.log(three) // 3

let [, , wow] = arr  //첫번째, 두번째를 빈값으로 선언
console.log(wow)  //3 


//////////////////////////////////////////////////
//값 할당(서로 바꾸기)
let num = 123;  
let text = &#39;hi&#39;; 
[num, text] = [text, num]
console.log(num, text)


//////////////////////////////////////////////////
//객체의 값에 대해 적용
let data = {width : 100, height : 200}
let {width, height} = data
console.log(width)  //100
console.log(height)  //200

//////////////////////////////////////////////////
//다양한 변환
let param = {
    jsn : {
        name : &#39;hello&#39;,
        number : 1543
    },
    arr : [
        {arr_name : &#39;world&#39;, index : 4567},
        {arr_name : &#39;world record&#39;, index : 5513},
    ],
    param_text : &#39;im param_text&#39;
}

let {jsn : {name : re_name}, arr : [{arr_name : new_name}], param_text} = param

//re_name은 param.jsn.name을 변환하여 별칭을 준 값
//new_name은 param.arr배열의 첫번째 arr_name을 변환하여 별칭을 준 값
//param_text는 param.param_text의 값을 변수명 그대로 사용한 값(별칭부여X)
console.log(re_name, new_name , param_text)</code></pre><h3 id="객체-리터럴">객체 리터럴</h3>
<p>객체를 생성할때 동적이고 간결하게 표현 가능하다고 한다.
한번도 써본적이없는데?,,,,사용해봐야겠다.</p>
<pre><code>let x = 1,
  y = 2;

const obj = { x, y };

console.log(obj); // { x: 1, y: 2 }</code></pre><pre><code>const obj = {
  name: &quot;Lee&quot;,
  // 메소드 축약 표현
  sayHi() {
    // sayHi: function() { 과 같은 표현
    console.log(&quot;Hi! &quot; + this.name);
  },
};

obj.sayHi(); // Hi! Lee</code></pre><h3 id="template-literals">Template literals</h3>
<p>이건 많이 써봤던 것이다. 간단히 말해서 백틱 (<code></code>) 이것을 쓰고 ${} 를 안에다가 넣으면 긴글을 단순하게 표현 가능하게 해주는 기능이다. </p>
<pre><code>const first = &quot;Samuel&quot;;
const last = &quot;slow&quot;;
console.log(`제 이름은 ${first} ${last} 입니다.`);
console.log(`
    긴글을 아무리 써도 단지 개행을 자연스럽게 해주면? // 원래는 + &quot;\n&quot; + 를 해주지만
    따로 \n을 해주지 않더라도 출력시 개행이 되지!
    `);</code></pre><h3 id="매개변수-기본값">매개변수 기본값</h3>
<p>이건 진짜 예상치 못한 기능이다. 그런데 몇번 써봤던 것 같기도 하다. 일단 그냥 예시값? 정도로 들었던 것 같은데, 참 신기하고 굉장히 기본적이고 쉬운 문법이다. 이게 이때 만들어진거구나..</p>
<pre><code>function multiply(a, b = 1) {
  return a * b;
}
console.log(multiply(5, 2)); // 10
console.log(multiply(5, 1)); // 5
console.log(multiply(5)); // 5</code></pre><p>함수의 매개변수에 기본값을 할당하여, 해당 자리에 적절한 값이 없을때 기본으로 들어가게 하는 값이라고 한다. </p>
<h2 id="느낀점">느낀점</h2>
<p>구글링해보면 ES6가 굉장히 많이 나온다. 어딜가나 보인다. 그런데 보기만했지 이것에대해서 진지하게 찾아보진 않았던 것 같다. 그런데 오늘 해냈다는 것에서 뭔가 뿌듯하다.
그런데 찾아보면서 오히려 부족한게 계속 나오는 것 같은데, 찾아보고 정리하면서 발전하는 개발자가 되야할 것이다.</p>
<p>참고:</p>
<blockquote>
<p><a href="https://en.wikipedia.org/wiki/ECMAScript#:~:text=11th%20Edition%20%E2%80%93%20ECMAScript%202020,-The%2011th%20edition">https://en.wikipedia.org/wiki/ECMAScript#:~:text=11th%20Edition%20%E2%80%93%20ECMAScript%202020,-The%2011th%20edition</a>
<a href="https://wormwlrm.github.io/2018/10/03/What-is-the-difference-between-javascript-and-ecmascript.html">https://wormwlrm.github.io/2018/10/03/What-is-the-difference-between-javascript-and-ecmascript.html</a>
<a href="https://takeuu.tistory.com/93">https://takeuu.tistory.com/93</a>
<a href="https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67">https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[React Hooks 정리.]]></title>
            <link>https://velog.io/@bright_root/React-Hooks-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@bright_root/React-Hooks-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 24 Jun 2022 05:25:47 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><img src="https://velog.velcdn.com/images/bright_root/post/a521eb1b-746d-41e9-b8b3-414eb664c6ed/image.png" alt=""></p>
</blockquote>
<h2 id="쓰긴쓰는데">쓰긴쓰는데..</h2>
<p>그렇다. 쓰긴쓰는데 뭔가 그냥 쓰는 기분이다. </p>
<p>성격상  100%는 아니더라도 80~90% 정도는 되어야 쓸때 아 이래서 쓰는구나를 체감하면서 쓰는데, 훅은...아직 나랑 덜 친한 기분이다. 아무 좀 뭔가 뿌듯함이 없다.
왜냐하면 잘 몰라서가 아닐까?</p>
<p>정리가 잘된 블로그를 통해 한번 정리하면서 왜 쓰는건지 정확히 이해하기로 했다. 
그리고 공식문서를 확인하면서 정리하였다. 왜냐하면, 가끔 이상하게 해석해서 올린 글들을 확인했..ㅠ</p>
<blockquote>
<p>나의 정리를 도와줄 블로그 출처:
<a href="https://defineall.tistory.com/900">https://defineall.tistory.com/900</a></p>
</blockquote>
<h2 id="react-hooks">React Hooks?</h2>
<p>내가 느끼는 훅: 편안하게 해준다. 내가 코딩할때, 편하게 해준다. 그런데, 왜그런지 모르겠다. 훅쓰면 편하다. &#39;왜&#39;를 알아야한다는 것을 알았다.</p>
<p>Hook, 이름부터 왜 &#39;훅&#39;인지는 알수없으나, 리액트 16.8 버전에서 새로 추가되었다 (생각보다 젊은 기술이네).</p>
<ul>
<li>함수형 컴포넌트에서만 사용 가능하고 클래스에서 사용 불가능. </li>
<li>내장 훅 (useEffect, useState, useContext 등등) 이 있고, 커스텀 훅 (직접 만들어서 쓸 수 있다) 이 있다. -&gt; props, state, context, refs 그리고 lifecycle과 같은 개념에 기반을 두었다.</li>
<li>클래스 컴포넌트 문제점을 적극적으로 해결하기 위해서 만들어 진 것이다 (?)</li>
</ul>
<h3 id="등장배경을-알아야한다">등장배경을 알아야한다.</h3>
<p>이상하게 역사를 알아야 할 것 같다. 등장배경? 이 바로 그것이다. </p>
<p>(1) Class 컴포넌트 와 Function 컴포넌트</p>
<ul>
<li>Class 컴포넌트: 지금 내가 사용하고 있는것은 함수형 컴포넌트. 훅이 나오기 전까지 class컴포넌트를 사용했었고, 많은 문제를 떠안고 있었다고 한다. 상태값(state) 에 접근, 생명주기 기능 (lifecycle features)을 사용할때 클래스형 컴포넌트 선언을 해줘야 했다. 
문제점: 컴포넌트간에 로직의 재사용이 불가능 -&gt; 라이프사이클을 기반으로 하는 컴포넌트들과 상태값들. 그리고 써봤지만, 적응되면 편한데, 복잡한 코드를 짤 경우에, 에러가 발생할 경우 찾기가 힘들다. 뭔가 &lt;&gt;안에 뭔가 많다. 보기에도 안좋고 props타고타고 올라가고 해결할때 문제덩어리다. 그래서 내가 아는 사람들은 클래스형 컴포넌트 공부 안하고 바로 함수형부터 본다고한다.
사실 리액트에서는 함수형컴포넌트 사용을 장려한다. 클래스형 없어진다(?)는 이야기를 듣긴했다. </li>
</ul>
<p>아무튼 간단히 전문적으로 말하면 -&gt; render props나 HOC(High order component, 고차 컴포넌트)와 같은 패턴으로 코드의 추적이 어렵다. 이렇게 계속 코드를 짤경우 wrapper hell을 겪게되고 (많은 레이어들로 둘러쌓인), 코드가 복잡해진다. 
(내가 배우면서 사용했을때의 문제점으로 인하여 함수형으로 전환 되었다는 것을 알고나서 좀 신기했다.)</p>
<ul>
<li>Function 컴포넌트: 대신 함수형 컴포넌트는 메모리상에서 한번만 호출되고 메모리상에서 사라진다고 한다. 그래서 예전같이 상태값접근과 라이프사이클 구현이 불가능하다고한다. 
위에서 언급한 클래스형 컴포넌트의 문제점을 보완하기 위해서 훅이 나왔고, 훅과 함께 함수형 컴포넌트로 전환하는 시대가 왔다. </li>
</ul>
<h2 id="클래스와-함수-코드-비교">클래스와 함수 코드 비교.</h2>
<ol>
<li>클래스형<pre><code>import React, { Component } from &#39;react&#39;;
</code></pre></li>
</ol>
<p>class Example extends Component {
  state = {
    count: 0,
  };</p>
<p>setCount(num) {
  this.setState({
    count: num,
  });
}
render() {
  const { count } = this.state;
  return (
    <div>
     <div>
      <p>You clicked {count} times</p>
      &lt;button
       onClick={() =&gt; {
        this.setCount(count + 1);
     }}
    &gt;
       Click Me!
     </button>
    </div>
   </div>
  );
 )
}</p>
<p>export default Example;</p>
<pre><code>
2. 함수형</code></pre><p>import React, { useState } from &#39;react&#39;;</p>
<p>function Example() {
  const [count, setCount] = useState(0);</p>
<p>  return (
    <div>
     <p>You clicked {count} times</p>
     &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
       Click Me!
       </button>
      </div>
  );
}</p>
<p>export default Example;</p>
<pre><code>
클래스형은 보기만해도 숨이 턱턱 막힌다. this.이부분. 저것 보기만해도 싫다. 자바 할때부터 보기싫었다. 나만 그런가. 아무튼 함수형을 보면 뭔가 속이 뚫린다. 편하다. 굳이 저렇게 this.안해줘도 다 내장되어있으니까. render() -&gt; return() 으로 바뀌긴 했지만, 뭔가 렌더 그대로 사용했으면 어떨까 라는 생각이 든다. 뭔가 더 뿌려준다는 느낌이 더 든다. 

3. 훅을 사용할 경우 (함수형)</code></pre><p>import React, { useState } from &#39;react&#39;;</p>
<p>funtion App() {
  const [name, setName] = (&#39;&#39;);
  const [age, setAge] = (35);
  const [coffee, setCoffee] = (&#39;Latte&#39;);
}</p>
<p>export default App;</p>
<pre><code>훅을 통하여 여러개의 state를 사용 하는 것도 가능한다.


## HOOK 사용규칙.
1. 같은 훅을 여러번 호출 가능하다.

2. 최상위 에서만 훅을 호출해야 한다. 훅을 호출하는 순서는 항상 같아야 한다
* 반복문, 조건문, 중첩된 함수 내에서 Hook을 사용하면 안된다.
    왜 훅의 호출 순서가 같아야 하는 걸까?
    * 리액트가 상태값을 구분할 수 있는 유일한 정보는 훅이 사용된 순서이기 때문이다. 리액트가 훅이 호출된 순서에 의존한다는 것이다.
    * 예시로 반복문 안에서 훅을 호출했을 때 반복문이 true라면 괜찮겠지만 값이 false라면 건너뛰게 된다. 이렇게 하면 실행순서가 바뀔 수 있어 오류를 일으킨다 조건문 혹은 반복문을 사용하고 싶을때는 useEffect안에 넣어 사용하면 된다.

3. 블록 스코프 안에서는 사용 불가능! </code></pre><p>export default function App(){
  return {
    <div>
      // 불가능
      <div>{const [value, setvalue] = useState()}</div>
    </div>
  }
}</p>
<pre><code>
4. 비동기 함수(async 키워드가 붙은 함수)는 콜백함수로 사용할 수 없다.
</code></pre><p>export default function App(){
  // useEffect Hook 내부에, 비동기 함수가 들어가므로 에러 발생
  useEffect(async () =&gt; {
    await Promise.resolve(1)
  }, [])</p>
<p>  return {
    <div>
      <div>Test</div>
    </div>
  }
}</p>
<pre><code>
## React Hook 배우기.
내가 팀 프로젝트건, 혼자 VS code 켜놓고 코딩을 하던 제일 많이 쓰는 훅이 있다.
useState와 useEffect. 사실 정리를 하는 이유는, 어떤 훅들이 있는지 알려고 한거였는데, 처음부터 개념 잡으니까 확실히 도움이 된다. 

### 기본 Hooks.
1. useState
&gt; state란 -&gt; React에서 사용자의 반응에 따라, 화면을 바꿔주기(렌더링) 위해 사용되는 트리거역할을 하는 변수. React가 state를 감시하고, 바뀐 정보에 따른 화면을 표시해준다.
( state와 setState함수의 반환값을 비교 )

사용법.</code></pre><p>import { useState } from &quot;react&quot;;</p>
<p>// const [state, state변경함수] = useState(기본 state값);</p>
<p>const [isLoggedIn, setIsLoggedIn] = useState(false);</p>
<pre><code>
state를 변경하고싶다?
</code></pre><p>// 전에 만든 &quot;isLoggedIn&quot; state의 값을 true로 변경한다.</p>
<p>setIsLoggedIn(true);</p>
<p>// ** useState함수를 사용해 만든 &quot;state 변경 함수&quot;를 사용하여야 한다.</p>
<pre><code>
2. useEffect / useLayoutEffect
참고:
&gt; https://medium.com/@jnso5072/react-useeffect-%EC%99%80-uselayouteffect-%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C-e1a13adf1cd5#:~:text=%ED%99%94%EB%A9%B4%EC%9D%B4%20%EA%B9%9C%EB%B9%A1%EA%B1%B0%EB%A6%AC%EB%8A%94%20%EC%83%81%ED%99%A9,%EC%9D%B4%20%EA%B9%9C%EB%B9%A1%EA%B1%B0%EB%A0%A4%EC%A7%80%EA%B8%B0%20%EB%95%8C%EB%AC%B8%EC%97%90

* Render: DOM Tree를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정.
* Paint: 실제 스크린에 Layout을 표시하고 업데이트하는 과정.

useEffect -&gt; 비동기방식 -&gt; render and paint 이후 실행. Paint 된 이후에 실행되서 화면의 깜빡임을 보게된다. 
useLayoutEffect -&gt; 동기방식(끝날때까지 리액트가 기다려줌) -&gt; render된 후에 useLayoutEffect 실행되고 -&gt; paint 한다. 화면깜빡임을 볼 수 없다. -&gt; 레이아웃까지 보는데 시간 오래걸리니까 useEffect 권장.
</code></pre><p>// React에 기본적으로 내장되어 있는 useState와, useEffect 불러오기</p>
<p>import { setState, useEffect } from &quot;react&quot;;</p>
<p>...</p>
<p>function App() {
  const [data, changeData] = setState(false)</p>
<p>  // useEffect(실행할 함수, 트리거가 될 변수) 또는 useLayoutEffect(실행할 함수, 트리거가 될 변수) 사용하면된다. </p>
<p>  useEffect(() =&gt; {
    if (data.me === null) {
      console.log(&quot;Data changed!&quot;)
    }</p>
<pre><code>return () =&gt; console.log(&quot;컴포넌트 파괴, 언마운트 됨&quot;)</code></pre><p>  }, [data]);  </p>
<p>  // data변수가 바뀔때마다, react가 이를 감지해, 콘솔창에 &quot;Data changed!&quot; 출력</p>
<p>  return (
    <div>
      <button value="적용" onClick={changeData(!data)} />
    </div>
  )
}</p>
<p>export default App;</p>
<pre><code>3. useContext

* React에서 부모와 자식 컴포넌트간에 props나 state 전달이 가능하다.
* 중간에 컴포넌트들을 하나씩 거치지않고, 한번에 전달하려는 목적지로 전달 가능.
* context 전용 파일을 만들어준다.

간단한 예시일뿐. 실제로 사용해보면 장난아니다. 그런데 편하긴하다.
</code></pre><p>// newContext.js</p>
<p>import { createContext } from &quot;react&quot;  // createContext 함수 불러오기</p>
<p>// context안에 homeText란 변수를 만들고, 공백(&quot;&quot;) 문자를 저장한다.
const newContext = createContext({
  homeText: &quot;&quot;,
})</p>
<pre><code></code></pre><p>// App.js</p>
<p>import React from &quot;react&quot;;
import { View } from &quot;react-native&quot;;
import Home from &quot;./Home&quot;; // 자식 컴포넌트 불러오기</p>
<p>import { newContext } from &quot;./newContext&quot;; // context 불러오기</p>
<p>export default function App() {</p>
<p>  // context에 저장할 정보를 입력한다.
  const homeText = &quot;is Worked!&quot;</p>
<p>  // NewContext.Provider로 우리가 만든 context를 사용할 부분을 감싸준다.
  return (
        &lt;newContext.Provider value={{ homeText }}&gt;
          <View>
            <Home />
          </View>
        &lt;/newContext.Provider&gt;
  );
}</p>
<pre><code></code></pre><p>// Home.js</p>
<p>import React from &quot;react&quot;;
import { Text, View } from &quot;react-native&quot;;</p>
<p>import { useContext } from &quot;react&quot;;
import { newContext } from &quot;../newContext&quot;;</p>
<p>export default function Home() {</p>
<p>  // useContext hook 사용해서, newContext에 저장된 정보 가져오기
  const { homeText } = useContext(newContext);</p>
<p>  // 불러온 정보 사용하기!!
  return (
    <View>
      <Text>{homeText}<Text>
    </View>
  );
}</p>
<pre><code>4. useMemo, useCallback

useMemo
Memoization : 과거에 계산한 값을 반복해서 사용할때, 그 값을 캐시에 저장하는 것
- 재귀함수에 사용하면, 불필요한 반복 수행을 대폭 줄일 수 있다.
- 의존성을 가지므로, 첫렌더링시에만 저장할 변수를 설정할 수 있다.
</code></pre><p>export default function App(){
  const data = useMemo(()=&gt; &quot;data&quot;,[]);
  // 데이터 변수는 의존성 배열 []에따라 선언된다. ( []사용시, 첫 렌더링 시에 1번만 선언 )
  return &lt;&gt;&lt;/&gt;
}</p>
<pre><code>useCallback
의존성을 사용해, 첫렌더링시에만 실행할 함수를 설정할 수 있다.</code></pre><p>export default function App(){
  const avatarPressed = useCallback(() =&gt; Alert.alert(&#39;avatar pressed.&#39;), []);
  return &lt;&gt;&lt;/&gt;
}</p>
<pre><code>
써본적 있는데... 이제 뜻을 제대로 알다니...하아...진짜 왜그럴까..

5. useRef
HTML요소(태그)나 컴포넌트의 메모리주소를 포인팅해서, 객체(레퍼런스) 형식으로 관리할 수 있다. 그냥 특정 돔을 가르키기 위해서 사용하는 것이라고 보면 된다. 하지만, 재밌는 사실은, 이거는 쓰면 리렌더링이 안일어난다고 한다. 한번 딱쓰면 한번 끝이라고 한다.</code></pre><p>export default App(){
  const viewRef = useRef(null)</p>
<p>  // viewRef 객체에 있는 메소드를 사용한다.
  function testFunc(){
    viewRef.current?.메소드()
  }</p>
<p>  /// viewRef요소에, 해당 메모리 주소 전달
  return <View ref={viewRef}>
    <Text>Test</Text>
  </View>
}</p>
<pre><code>간단히 쓰여있긴한데... 더 찾아봐야겠다. 사용해본적은 있는데, 크게 인상적으로 막 주의깊게 본적은 없고 그냥 썼었다..

6. forwardRef
부모 컴포넌트에서, 자식 컴포넌트를 객체 형식으로 관리할 수 있다.
이것은 마치 useRef와 forwardRef 간 무엇인가 교환하는 느낌? 이건 진짜 직접 써보고 입력해보면서 알아야할것같다.. 어려운 개념이었다.

참고:
&gt; https://www.daleseo.com/react-forward-ref/

먼저 &lt;Audio/&gt; 자식 컴포넌트와 &lt;Controls/&gt; 자식 컴포넌트로 이루어진 &lt;Player/&gt; 부모 컴포넌트가 있다고 가정하자.</code></pre><p>// Player.jsx
import React, { useRef } from &quot;react&quot;;
import Audio from &quot;./Audio&quot;;
import Controls from &quot;./Controls&quot;;</p>
<p>function Player() {
  const audioRef = useRef(null);</p>
<p>  return (
    &lt;&gt;
      <Audio ref={audioRef} />
      <Controls audio={audioRef} />
    &lt;/&gt;
  );
}</p>
<p>export default Player;</p>
<pre><code>useRef()를 사용하여 audoRef를 만들어서 Audio자식에 넘겨주고, Controls자식에는 audio prop으로 넘겨주고 있다.

Audio 자식이 ref prop을 Player 부모로부터 제대로 받으려면, forwardRef()함수를 사용하여야 한다. 아 이쯤되니까 무엇인가 이해가기 시작. 아 알겠다이제대충.
두번째 인자 ref로 넘어온다..
</code></pre><p>// Audio.jsx
import React, { forwardRef } from &quot;react&quot;;
import music from &quot;./music.mp3&quot;;</p>
<p>function Audio(prop, ref) {
  return (
    <figure>
      <figcaption>Eyes on You (Sting) - Network 415:</figcaption>
      <audio src={music} ref={ref}>
        Your browser does not support the
        <code>audio</code> element.
      </audio>
    </figure>
  );
}</p>
<p>export default forwardRef(Audio);</p>
<pre><code>
이 외에도, useImerativeHandle, useReducer, useDebugValue 가 있다. 

핵심적으로 많이 쓰이는 것들만 정리를 했다. 나머지는 공식문서를 보면서, 구글링을 하면서 연습을 해봐야겠다. 깃헙에서 하나 만들어서 사용해보고 있는데, 내가 이상하게 좀 공포증(?) 같은것이 있나보다. 뭔가 처음에 익숙하지 않으니까, 두려움이 앞선다. 우선 내지르고 코드를 짜봐야 실력이 좋아진다는 것은 코딩하면서 항상 느낀다.  열심히 잘 해봐야지!!

</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[NPM VS. YARN 차이..오..]]></title>
            <link>https://velog.io/@bright_root/NPM-VS.-YARN-%EC%B0%A8%EC%9D%B4..%EC%98%A4</link>
            <guid>https://velog.io/@bright_root/NPM-VS.-YARN-%EC%B0%A8%EC%9D%B4..%EC%98%A4</guid>
            <pubDate>Wed, 22 Jun 2022 08:58:38 GMT</pubDate>
            <description><![CDATA[<h2 id="npm과-yarn의-차이">NPM과 YARN의 차이.</h2>
<p>엄청난 질문이였다. 기술면접에서 물어보시는데 말문이 턱 막혔다. 뭐가 뭔지 모르겠다. 도대체 무엇일까. 와 이것은 예상하지도 준비도하지 못한 질문이였다.
질문 듣자마자 잠시 뇌가 멈췄다. 내 뇌 라이브러리에 없으니까...</p>
<p>알고 넘어갑시다.</p>
<p>우선, 그것은 안다. NPM이 YARN보다  먼저 나온것이다. 그리고 내가 알기로는 YARN의 뭔가 더 효율적이다(?) 라고 어디서 얼핏 들어봤던 것 같다. </p>
<p>나는 처음부터 YARN쓰라고 배웠다. 그래고 내가 궁금해서 왜그러냐고 물어봤지만, 일단 이거 쓰라고 그랬다. 그래서 시작하게 되었는데...왜 쓰는지 놓치고 있었네..</p>
<p>YARN &gt; NPM ? -&gt; 크게 보면 속도가 빠르고 보안성이 훨씬 좋다고 한다.</p>
<p>한마디로 말하면 YARN은 NPM 개선 버전이라고 한다.</p>
<h2 id="자바스크립트-패키지-매니저-javascript-pakage-manager">자바스크립트 패키지 매니저 (JAVASCRIPT PAKAGE MANAGER)</h2>
<p>그 둘은 자바스크립트 패키지 매니저라고 한다. 패키지는 알고있듯이 NPM이라는 곳에 올라온 노드 모듈들을 말한다. Node Packaged MANAGER. Node.js로 만들어진 package(module)를 관리해주는 툴이라고 보면 된다. CMD를 통해서 NPM을 설치하면 pakage.json이라는 파일이 만들어진다. </p>
<pre><code>{
  &quot;name&quot;: &quot;application-study&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;dependencies&quot;: {
    &quot;http-server&quot;: &quot;0.9.0&quot;,
    &quot;rimraf&quot;: &quot;2.6.1&quot;,
    &quot;webpack&quot;: &quot;2.2.1&quot;,
    &quot;worker-loader&quot;: &quot;0.8.0&quot;
  },
  &quot;scripts&quot;: {
    &quot;prebuild&quot;: &quot;rimraf dist&quot;,
    &quot;build&quot;: &quot;webpack --config webpack/webpack.config.js&quot;,
    &quot;http-server&quot;: &quot;http-server -c-1&quot;
  },
  &quot;repository&quot;: {
    &quot;type&quot;: &quot;git&quot;,
    &quot;url&quot;: &quot;git+https://github.com/aaa/bbb.git&quot;
  },
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;,
  &quot;bugs&quot;: {
    &quot;url&quot;: &quot;https://github.com/aaa/bbb/issues&quot;
  },
  &quot;homepage&quot;: &quot;https://github.com/aaa/bbb#readme&quot;
}</code></pre><p>이런식으로 흔하게 나온다. 객체형태로. 
나 궁금한게 있었다. 여기서 scripts와 dependencies저거 있었는데 구글링 해보려고 했는데 여기서 나오네. 
scripts -&gt; 우리가 cmd에 run 명령어를 통해서 실행할 것들 리스트라고 한다.
dependencies -&gt; 설치할 모듈들을 의미한다고 한다. 패키지에서 사용하는 패키지들을 말한다.</p>
<p>그리고 yarn.lock 이런식의 파일이 나오는데 이것도 제대로 알게된것인데 package.json에 의존하는 서로 다른 환경이 서로다른 버전의 패키지 의존성을 가지는 것을 방지하기 위해 yarn.lock파일을 사용하여 정확한 버전을 명시한다.</p>
<p>재밌는게 뭐냐면...사용하면서 그냥 알긴알았다..그냥 뭔가 아 이런거구나는 알았지만, 이렇게 정확하게 무엇인지에 대한 정의를 들었을때는 말하지 못한다. 왜그런 것일까? </p>
<p>아마 사용은 해봤지만 정리하면서 하지 않아서 그런것 같다. </p>
<p>좀 알고쓰자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Promise VS. Callback ]]></title>
            <link>https://velog.io/@bright_root/Promise-VS.-Callback</link>
            <guid>https://velog.io/@bright_root/Promise-VS.-Callback</guid>
            <pubDate>Mon, 20 Jun 2022 04:41:51 GMT</pubDate>
            <description><![CDATA[<h2 id="이름이-둘다-독특하다">이름이 둘다 독특하다.</h2>
<p>하나는 약속이라는 뜻을 가진 Promise. 다른 하나는 회신이라는 뜻을 가진 Callback. 아무튼, 이름 진짜 독특하게 짓긴한것같기도하다. 뭔가 한눈에 이해하기 어려운건 사실이다.
내가 생각했을때, 프로미스와 콜백에 대해서 알긴 알지만, 그 깊은 알맹이 뜻을 제대로 모른채, 넘어간것같다. </p>
<p>조금 정리를 해야할 필요성을 느낀다.</p>
<p>일단, 내가 놓치고 있는 것부터!</p>
<h2 id="callback-함수란">Callback 함수란?</h2>
<p>구글링을 해서 콜백함수가 무엇인지 대충 보면, </p>
<ol>
<li>함수를 함수의 인자로써 이용하는 함수.</li>
<li>어떤 이벤트에 의해 호출되어지는 함수. </li>
</ol>
<p>쓰도코드로 보면~</p>
<pre><code>// The callback method
function meaningOfLife() {
    log(&quot;The meaning of life is: 42&quot;);
}


// A method which accepts a callback method as an argument
// takes a function reference to be executed when printANumber completes
function printANumber(int number, function callbackFunction) {
    print(&quot;The number you provided is: &quot; + number);
}

// Driver method
function event() {
   printANumber(6, meaningOfLife);
}
출처: https://satisfactoryplace.tistory.com/18 [만족:티스토리]</code></pre><p>printANumber()의 두 번째 매개변수로 function 타입의 callbackFunction을 인자로 받고있었고,
 
event()내부에서 printANumber(6, meaningOfLife); 를 하고 있는데,
meaningOfLife는 printANumber의 매개변수인 callbackFunction에 전달된고있기때문에,</p>
<p>callback 함수라고 할 수 있다.</p>
<p>나는 지금까지 무슨 콜백함수와 화살표 함수에 대해서 헷갈려 하고 있었다. 헷갈릴 것을 헷갈려야지 뭐하냐진짜로....</p>
<p>그런데, 만약에 콜백 함수를 갖고 비동기작업을 실시할 경우에 복잡해진다.</p>
<p>이걸보면된다~</p>
<pre><code>const add5 = (number, callback) =&gt; {
    setTimeout(() =&gt; callback(number + 5), 1000);
};

const add10 = (number, callback) =&gt; {
    setTimeout(() =&gt; callback(number + 10), 1000);
};

const add15 = (number, callback) =&gt; {
    setTimeout(() =&gt; callback(number + 15), 1000);
}

const log = (number) =&gt; {
    console.log(number);
}

add5(0, (number) =&gt; add10(number, (number) =&gt; add15(number, log)));
</code></pre><p>add5(0, (number) =&gt; add10(number, (number) =&gt; add15(number, log)))
꼬리에 꼬리를 미친듯이 물고 넘어가는 중이다. -&gt; 가독성이 굉장히 떨어진다. 딱 보자마자 눈에 보이지 않는다. </p>
<p>그리고 코드의 유지보수성을 나쁘게 만들기땨문에 지양하는것이 좋다고한다. </p>
<p>이러한 이유로 Promise ES6부터 생겨났다. 
가독성이 좋아지고, 제일 중요한, 유연한 비동기 처리가 가능하다고 한다. </p>
<h2 id="promise의-유연한-대처">Promise의 유연한 대처.</h2>
<p>비동기 작업의 상황에 pending, resolved, failed 3가지 상태로 나타낸다.</p>
<pre><code>const add10 = number =&gt;
  new Promise(resolve =&gt;
    setTimeout(() =&gt; {
      resolve(number + 10);
    }, 1000),
  );

const add15 = number =&gt;
  new Promise(resolve =&gt;
    setTimeout(() =&gt; {
      resolve(number + 15);
    }, 1000),
  );

const log = number =&gt; new Promise(resolve =&gt; setTimeout(() =&gt; console.log(number), 1000));

add5(0)
  .then(number =&gt; add10(number))
  .then(number =&gt; add15(number))
  .then(number =&gt; log(number));

출처: https://simsimjae.tistory.com/420 [104%:티스토리]</code></pre><p>사실 then으로 연결된 Promise체인이 코드를 훨씬 보기 좋게 만들어 준다고 하긴하는데...내눈엔... 그게 그거같다. ㅋㅋㅋㅋㅋㅋ</p>
<p>아무튼 이러한 이유로 코드 유지보수성이 좋아졌다고는 하는데...그렇다한다.</p>
<p>아무튼 결론은 이렇기때문에,,,,,</p>
<p>비동기작업의 추가/수정이 Promise가 더 좋고,</p>
<p>코드유지보수성증가가 Promise에서 이루어진다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[var, let, const의 차이]]></title>
            <link>https://velog.io/@bright_root/var-let-const%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@bright_root/var-let-const%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Sat, 18 Jun 2022 06:25:27 GMT</pubDate>
            <description><![CDATA[<h2 id="알아보기전에미안해요다들">알아보기전에....미안해요다들...</h2>
<p>이건 내가 예전부터 C언어 배울때부터, 자바, 파이썬 그리고 자바스크립트를 대충 거치고 배우면서 너무 당연시하였지만, 자바스크립트를 요즘 리액트 개발자가 되려고 배우면서 건드리게된다.</p>
<p>분명 변수의 선언과 동시에 메모리에서 일어나는 일에 대해서 배웠겠지만, 그만큼 항상 코딩에만 집중할뿐, 개념에는 집중하지 못했다. 이제와서 좀 무슨일이 일어나는지 알게되는 것 같아 스스로에게 반성한다. 모르고 쓰다니...그래놓고 연구프로젝트라던가, 간단한 팀프로젝트라던가 등등 할때 모르고 썼다니...괜히 부끄럽고 미안하다. </p>
<p>이 정리는, 자바스크립트 공식문서와 한 블로거님의 엄청난 글을 기반으로 했다</p>
<blockquote>
<p><a href="https://www.howdy-mj.me/javascript/var-let-const/">https://www.howdy-mj.me/javascript/var-let-const/</a></p>
</blockquote>
<p>열심히 공부할게요감사해요!!</p>
<h2 id="변수">변수</h2>
<p><img src="https://velog.velcdn.com/images/bright_root/post/cdcf81a1-f122-4297-9fe0-8ff4f5811f5d/image.png" alt=""></p>
<p>이 그림 보자마자 한번에 알아들었다. 왜냐하면, 많이써봤으니까. 그런데 저 사실을 잠시 잊고있었다. 메모리에 내가 선언한 변수가 들어간다는것. 와...기분 묘했다. 
이 그림의 상황을 코딩해보면,</p>
<pre><code>const myNumber = 23;
// 변수명(식별자): myNumber
// 해당 값의 위치(메모리 주소): 0012CCGWH80
// 변수 값(저장된 값): 23</code></pre><p>이거다. 이거 한줄 딱 치면 변수명이 저런 애가 메모리 주소가 저것이고, 저장된 값은 저것이다.</p>
<p>그림과 같이 하는 것을 할당(assignment)라고 하고, 여기서 그림에 저장된 값들을 불러들여오는 것을 참조(reference)라고 한다. 그리고 const myNumber이런것을 선언(declaration)이라고 한다~</p>
<h2 id="변수선언">변수선언</h2>
<p>나는 프로젝트하면서 const만 썼다. 쓴 이유는, 값이 바뀌거나 그 값들이 다른 곳에서 쓰이는 것을 막기 위해서다. 즉, 재할당, 재선언등을 방지하기 위해서이다. 그래서 var과 let에 대해 좀 가물가물해졌다. 대신 그것은 안다. var이라는 친구는 정말 웃기다는 것을. 아무튼 머릿속에 꼬깃꼬깃한 개념을 펴줘야 하니까 차근차근 해보자고~</p>
<p>선언과 초기화 단계 두개를 가진다. 
선언: 변수명을 등록하여 자바스크립트 엔진에 변수의 존재를 알린다. 
초기화 단계: 값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undefined를 할당해 초기화 한다. </p>
<pre><code>var root
console.log(root) // undefined</code></pre><p>값 자체를 아무것도 일단 안넣어 줬으니까, 일단 undefined를 메모리 공간에 할당한다.</p>
<pre><code>console.log(root) //undefined
var root</code></pre><p>반대로 이렇게 해도 undefined나온다. </p>
<p>자바스크립트 쓰면서 제일 놀랐던 것중 하나. 
&quot;이게 된다고? 왜?&quot;</p>
<p>자바스크립트 엔진은 소스코드를 한줄 씩 순차적으로 실행하기에 앞서, 변수 선언을 포함한 모든 선언문을 찾아내 먼저 실행한다. 즉 변수선언이 어디에 있든 상관없이, 먼저 찾아내서, 다른 코드보다 먼저 실행되는 특징 -&gt; 호이스팅(hoisting)이라고 한다. var, let, const, function, class등 선언하는 모든것들은 먼저 호이스팅 된다. </p>
<h2 id="변수-할당">변수 할당</h2>
<pre><code>var root //변수선언
root = &quot;bright&quot; //값 할당

var root = &quot;bright&quot; // 변수 선언과 할당</code></pre><p>할당을 이렇게 하면 되는 것이고,</p>
<pre><code>console.log(root) // undefined

var root = &quot;bright&quot;
console.log(root)//bright</code></pre><p>실행 위치에 따라 아웃풋이 다르고~</p>
<pre><code>console.log(root) // &quot;bright&quot;
 root=&quot;pirate&quot;
 console.log(root)// &quot;pirate&quot;</code></pre><p> 이렇게 되는것을 재할당이라고 한다. 
 그런데! 변경이 안된다면 상수(constant)라고 한다. *const!</p>
<h2 id="함수-호이스팅">함수 호이스팅!</h2>
<pre><code>// 1. 함수 선언문
// 함수 이름 생략 불가능
function add(x, y) {
  return x + y
}

// 2. 함수 표현식
// 함수 이름 생략 가능
var add = function(x, y) {
  return x + y
}
// 함수 이름 작성 시,
// var add = function plus(x, y) {
//   return x + y
// }

// 3. Function 생성자 함수
var add = new Function(&#39;x&#39;, &#39;y&#39;, &#39;return x+ y&#39;)

// 4. 화살표 함수
var add = (x, y) =&gt; x + y</code></pre><p>이러한 방법으로 함수를 선언하고 표현할 수 있다. 정말 다양하다...오...생각보다 많네..나는 개인적으로 1번이랑 4번 많이쓰고 4번이 뭔가 화살표도 보이고 이쁘다.</p>
<p>호이스팅 결과:</p>
<pre><code>// 함수 참조
console.dir(add) // output: f add(x, y)
console.dir(sub) // output: undefined

// 함수 호출
console.log(add(2, 5)) // output: 7
console.log(sub(2, 5)) // output: Uncaught TypeError: sub is not a function

// 함수 선언문
function add(x, y) {
  return x + y
}

// 함수 표현식
var sub = function(x, y) {
  return x + y
}</code></pre><p>여기서 함수 선언문만이 호이스팅 가능이고 함수 표현식은 undefined가 나오는 것을 볼 수 있다. </p>
<h2 id="스코프">스코프</h2>
<p>이름만 어렵지 사실 진짜 별 것 없는 개념이다. 스코프는 한글로하면 그냥 영역이라는 뜻이다. 쉽게 말하면, 함수 안에서 변수가 선언되면 그 변수는 함수 안에서만 활동 가능하다. 반면에 함수 밖, 즉 그냥 맨 화면에다가 선언하면 함수 안에서도 가능하고 이곳저곳 가능하다. 그럴때 전자를 지역변수, 후자를 전역변수라한다. </p>
<p>지역레벨 스코프를 if, for while, try/catch등에서만 가능한 것을 블록 레벨 스코프라한다. 
var이 참 오픈마인드다.</p>
<pre><code>var a = 1

if (true) {
  var a = 5
}

console.log(a) // output: 5</code></pre><p>항상 내 생각 밖의 무엇인가를 만드는 것 같다 ㅋㅋㅋㅋㅋ 진짜 이건 상상도 못했다. </p>
<p>함수가 아닌 곳에서 var 선언하고 전역변수 취급되다가, 변수 중복 선언되면 다시 변경된 값으로 변해버린다. 
따라서 오로지 함수 코드 블록만을 지역스코프로 인정하는 var 대신, 블록레벨 스코프를 지원하는 const와 let을 사용 하는 것을 권장한다고 한다. </p>
<h2 id="최종-정리-그러면-var--let--const-차이">최종 정리: 그러면 var | let | const 차이</h2>
<h3 id="var-키워드는-문제투성이">var 키워드는 문제투성이</h3>
<ul>
<li>변수 중복 선언 가능</li>
<li>함수 레벨 스코프로 인해 함수 외부에서 선언한 변수는 모두 전역 변수로 된다.</li>
<li>변수 선언문 이전에 변수를 참조하면 언제나 undefined를 반환한다.</li>
</ul>
<h3 id="변수-중복-선언-불가">변수 중복 선언 불가.</h3>
<p>(1) let
변수 중복 선언 불가 / 재할당 가능.</p>
<pre><code>let name = &#39;kmj&#39;
console.log(name) // output: kmj

let name = &#39;howdy&#39; // output: Uncaught SyntaxError: Identifier &#39;name&#39; has already been declared

name = &#39;howdy&#39;
console.log(name) // output: howdy</code></pre><p>(2) const
반드시 선언과 초기화를 동시에 진행해줘야해.</p>
<pre><code>const name; // output: Uncaught SyntaxError: Missing initializer in const declaration
const name = &quot;what&quot;</code></pre><p>알고보면 다른 언어에서는 정상적인 모습이라고 난 알 고 있 다...</p>
<p>재선언 재할당 불가하고, 원시값 불가능하지만 객체만 가능. </p>
<pre><code>// 원시값의 재할당
const name = &#39;what&#39;
name = &#39;howdy&#39; // output: Uncaught TypeError: Assignment to constant variable.

// 객체의 재할당
const name = {
  eng: &#39;what&#39;,
}
name.eng = &#39;howdy&#39;

console.log(name) // output: { eng: &quot;howdy&quot; }</code></pre><h3 id="블록레벨-스코프">블록레벨 스코프</h3>
<p>let 과 const는 함수레벨스코프만 좋아하는 var과 다르게 블록레벨 스코프를 따른다.</p>
<pre><code>let a = 1

if (true) {
  let a = 5
}

console.log(a) // output: 1</code></pre><p>const도 이와같이 움직인다. var보다 훨씬 낫다.</p>
<h3 id="변수-호이스팅">변수 호이스팅</h3>
<p>(1) let
let 키워드로 선언한 변수는 선언 단계와 초기화 단계가 분리되어 진행된다. 즉, 런타임 이전에 자바스크립트 엔진에 의해 선언 단계가 먼저 실행되지만, 초기화 단계가 실행되지 않았을 때 해당 변수에 접근하려고 하면 참조 에러가 뜬다.</p>
<pre><code>console.log(name) // output: Uncaught ReferenceError: name is not defined

let name = &#39;wow&#39;</code></pre><p>따라서 let 키워드로 선언한 변수는 스코프의 시작 지점부터 초기화 단계 시작 지점까지 변수를 참조할 수 없는 일시적 사각지대(Temporal Dead Zone: TDZ) 구간에 존재한다.</p>
<p>(2) const
앞에서 말했듯이 선언이랑 초기화 둘다 동시에 진행된다. 당연히 얘도 똑같다.  </p>
<pre><code>console.log(name) // output: Uncaught ReferenceError: name is not defined

let name = &#39;wow&#39;</code></pre><p>let 키워드로 선언한 경우, 런타임 이전에 선언이 되어 자바스크립트 엔진에 이미 존재하지만 초기화가 되지 않았기 때문에 name is not defined라는 문구가 떴다. 하지만 const 키워드로 선언한 경우, 선언과 초기화가 동시에 이루어져야 하지만 런타임 이전에는 실행될 수 없다. 따라서 초기화가 진행되지 않은 상태이기 때문에 Cannot access &#39;name&#39; before initialization 에러 문구가 뜬다.</p>
<blockquote>
<p>참고: 모던 자바스크립트 Deep Dive, 이웅모 (2020)</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[SSR과 CSR, 좀 멋있는 이름인걸?]]></title>
            <link>https://velog.io/@bright_root/SSR%EA%B3%BC-CSR-%EC%A2%80-%EB%A9%8B%EC%9E%88%EB%8A%94-%EC%9D%B4%EB%A6%84%EC%9D%B8%EA%B1%B8</link>
            <guid>https://velog.io/@bright_root/SSR%EA%B3%BC-CSR-%EC%A2%80-%EB%A9%8B%EC%9E%88%EB%8A%94-%EC%9D%B4%EB%A6%84%EC%9D%B8%EA%B1%B8</guid>
            <pubDate>Fri, 17 Jun 2022 13:08:42 GMT</pubDate>
            <description><![CDATA[<h2 id="이름이-멋있는-친구들-ssr--csr">이름이 멋있는 친구들: SSR &amp; CSR</h2>
<p>이상하게 이름 볼때마다 특수부대 느낌난다. 나만그렇지 그치? </p>
<p>아무튼 항상 여기에 정리할땐 이상한 이야기로 시작해야 뭔가 워밍업하고 쓰는 기분이야.</p>
<p>이건 특수용어가 절대 아니야. 쫄지마. 알았지?</p>
<p>별거없어.</p>
<p>저 이름을 보면서, 리액트 생각해주면서, 뭔가 뒤엉켜있을거같은 보이지않는 서버쪽 생각하면서, 마음을 가다듬고 저 용어들을 지긋이 바라봐.</p>
<p>SSR...흠 뭔가 S 둘중 하나는 Server...흠...R뭔가..음...랜더링? Rendering? ok...</p>
<p>역시 SSR -&gt; Server Side Rendering.</p>
<p>한국어 그대로 말하면~ 서버 쪽 렌더링. 서버 렌더링? 자, 다음 드루와.</p>
<p>CSR...흠 C..C...라 내 대학교때 학점이 왜 생각나지 아무튼 조용히하고...음...C...Computer? 오 Client! (사실 구글링해서 뭔지 보긴했음).. 
R도 뭐 마찬가지겠지. 짝궁으로 둘이 설명 나오는거보니까.
그렇지. CSR -&gt; Client Side Rendering! </p>
<p>그럼 한국어로 뭐겠어? 클라이언트 쪽 렌더링! 꼬불꼬불 뒤얽혀있을 것 같은 서버쪽이 아니라 우리쪽! 클라이언트 바깥쪽! 이느낌에서 렌더링을 뙇!</p>
<p>렌더링이 뭐야?
렌더링은 서버로부터 요청해서 받은 내용을 브라우저 화면에 표시해주는것!</p>
<p>ㅇㅋㅇㅋ.. 느낌옴 대충 뭔지는 알겠음. 누군가 물어보면 대답할 것 같아. 하지만!</p>
<p>내 스타일상 정확히 느낌 빡 안오면 잠이 안온다.</p>
<p><img src="https://velog.velcdn.com/images/bright_root/post/86d31f95-94d6-4250-9c2d-585bdce4bd43/image.png" alt=""></p>
<h2 id="csr">CSR</h2>
<p>SPA, Single Page Application (기억나지? 나 저번에 정리해놨음. 다시봐야징~) 와 CPU 성능 + JS 표준화 (리액트, 앵귤러 라이브러리 및 프레임워크) 발전과 함께 시작되었다고한다.</p>
<p>SPA-&gt; 한번 페이지를 서버에서 가져와서 로딩한다음에, 사용자가 원하는 데이터만 보고싶으면 그것만 불러와서 로딩. </p>
<p>서버에서 HTML을 다 요청하는게 아닌 (SSR이랑 다르게), 브라우저에서 자바스크립트로 콘텐츠를 렌더링 한다고 한다.</p>
<p>예를 들면, body에 id= &quot;root&quot;만 있는데, 자바스크립트 링크만 들어있다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/bright_root/post/42ea394e-7a3d-4054-83d7-ab36009e7d81/image.png" alt="">
<a href="https://ctdlog.tistory.com/46">https://ctdlog.tistory.com/46</a></p>
</blockquote>
<p>블로거님께 감사드립니다..정리 잘하겠습니다.
아무튼, 최초로 서버에서 클라이언트 쪽으로 끌고올때, 텅텅 빈것을 볼 수 있다. 위에 위에 맨처음 그림에서 볼 수 있듯이, 자바스크립트 다운로드 할 동안, html은 로딩상태이고 다 완료 되었을때, 자바스크립트로 프레임워크 및 라이브러리 작동시키고, 사용자가 원할때마다 원하는 부분만 서버에서 딱딱 가져온다.</p>
<p>단점: </p>
<ol>
<li>사용자가 첫 화면을 보기까지 시간이 오래걸릴 수 있다. (진짜다. 이건 내가 프로젝트때 겪었고, 마음아팠다. 분명 코드 가지런하게 다하고, 구글링하면서 했는데 왜케 느리지?)</li>
<li>SEO 가 잘 안된다...걍 안된다..</li>
</ol>
<p>SEO -&gt; SEARCH ENGINE OPTIMIZATION</p>
<blockquote>
<p>Search Engine Optimization
웹 어플리케이션을 만드는 이유는 뭘까? 일반적으로 내 제품을 홍보하는것 이것 자체가 서비스 비즈니스.
효과적인 서비스 홍보를 위해서는 내가 만든 웹페이지가 상위에 노출되어야한다.
SEO가 그래서 필요하다. 검색엔진 최적화.
검색엔진에서 더 찾기 쉽도록 사이트를 개선하는 프로세스. 즉, 구글의 검색엔진이 찾을 수 있고, 이해할 수 있는 사이트를 만들어야 검색결과가 최상위에 보인다. 
React는 기본적으로 잘 안되어있다. <a href="https://rbals0445.tistory.com/65">https://rbals0445.tistory.com/65</a>
구글봇은 html/css로 되어있는 웹사이트는 잘 크롤링한다 왜냐하면 렌더링 하기에 좋은 형태니까. 하지만 js로 되어있으면 리액트는 리액트컴포넌트를 html css 로 변환해야하기때문에 잘 안된다.
SPA는 부분적으로 랜더링해서 보여주기때문에 키워드를 통해서 검색엔진 상위랭크에 넣게 하는것이 힘들다. 
방법으로는 REACT는 NEXT.JS쓰면 된다고한다. React helmet등등. 
두번째는 프리렌더링-&gt; 프로젝트 배포전에 렌더링이 일어나는 것. 미리 html 만들어 두고, 서버에서 요청할때 그에맞는 html로 바꿔주는 것. </p>
</blockquote>
<p>그렇기 때문에, SSR, 특수부대이름같은 아이가 등장!</p>
<h2 id="ssr">SSR</h2>
<p>얼마나 답답하면, 그냥 일단 서버에서 다 가져올 생각을 할까. 찔끔찔끔 사용자 생각해서 원할때마다 서버에서 가져오는 것으로 하려고 했는데? 얼마나 답답하면 그냥 다 끌고왔을까. 말그대로 일단 웹사이트 접속하면 서버에서 필요한 데이터 삭다 HTML 파일 만들고, 만들어진 HTML을 동적으로 조금 제어가능한 소스코드와 함께 클라이언트에 슝 보낸다. 그러면 사용자는 모든 것을 다 한번에 마지막에 보게되는 것이다. 위에 위에 그림에 참고~
로딩이 훨씬 빠르고, SEO가 훨씬 효율적이다. html요소들을 한꺼번에 가져오니까! 그것으로 딱 구글 봇이 키워드 잘 찾아내고, 등등 해서 검색창 우리가 딱 치면 잘 나오겠지?</p>
<p>단점 물론 있죠:</p>
<ol>
<li>사용자가 &#39;아 새로고침 해야지.&#39; 이러고 딱 새로고침 누르는 순간, 다시 서버에서 처음부터 끝까지 다 불러와야한다. 그래서, 이게 BLINKING ISSUE라고 한다. 깜빡거리는 이슈. 보기 좋지않다. 다시 깜빡이니까.</li>
<li>html요소들이 많거나, 사용자가 엄청 많다. 그러면 서버에서 계속 끌고오겠지? 그러면 서버 과부하 걸리지...</li>
<li>마지막으로 TTV(time to view) 와 TTI(time to interactive) 위에 위에 그림 보면 알것이다. CSR은 html만 받아왔을때는 비어있지만, 점점 로직을 처리하는 자바스크립트 파일을 가져오면서 웹사이트가 보여지기때문에 동시에 인터랙션 즉 사용자가 누르고 뭐 이것저것 가능하다. 반면에 SSR은 그 전까지 불가능..다 가져올때까진..</li>
</ol>
<h2 id="리액트-개발자로서-그럼-csr단점-어떻게-해결해야함">리액트 개발자로서, 그럼 CSR단점 어떻게 해결해야함?</h2>
<p>요즘 SSG(STATIC SITE GENERATION)이런게 나왔다. 말그대로 정적 사이트 발생. 우리가 코딩짜면 만든 웹 어플리케이션을 정적으로 웹페이지를 미리 생성해두고 서버에 배포하게 만드는 그런것이다. 그리하여 라이브러리 이름은 GATSBY. 이거 왁스이름아닌가...아무튼..조용히하고 집중해. 그리고 동적인 요소들도 충분히 가져올 수 있으니까 좋지. 아주좋아. </p>
<p>그다음에 NEXT.JS. 이건 리액트 검색하면 맨날 뜨는것이다. 이게 도대체 뭐지. 그리고 왜 리액트 할줄알면 저거 많이 쓴다는데 왜지? 라는 의문이 생겼는데 이것을 쓰면 SSR을 지원한다고 한다. 리액트가 CSR인데 리엑트에서 SSR가능하게 해주는 프레임 워크라고 한다.</p>
<p>이상!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[COOKIE | SESSION | WEB STORAGE]]></title>
            <link>https://velog.io/@bright_root/COOKIE-SESSION-WEB-STORAGE</link>
            <guid>https://velog.io/@bright_root/COOKIE-SESSION-WEB-STORAGE</guid>
            <pubDate>Thu, 16 Jun 2022 07:37:30 GMT</pubDate>
            <description><![CDATA[<h2 id="알긴-알아-알겠는데쿠키-세션-웹스토리지">알긴 알아. 알겠는데...쿠키 세션 웹스토리지</h2>
<p>난 쿠키 세션 웹스토리지에 요즘 부쩍 친숙해졌다. 그냥 프로젝트를 혼자 꾸역꾸역 하고있는데, 거기서 많이 보는 친구들이다. 쓰는건 간단하다. 그냥 getCookie setCookie등 이런식으로 정해진 코드만 딱딱 써주면 되니까. 근데 문제가 있다. 이상하게 개념이 헷갈린다.
쿠키랑 세션? 뭐지? 무슨 느낌이랄까. 아이패드랑 태블릿pc느낌? 두개 비슷하긴한데 뭔가 기능면에서 살짝 다르긴한데 제조사도 다르고 막! 아무튼 개념잡기 실시. </p>
<h2 id="http-한계를-보안하기-위해서-나왔다고-한다">HTTP 한계를 보안하기 위해서 나왔다고 한다.</h2>
<p>내가 전에도 정리했지만, HTTP -&gt; STATELESS 그리고 connectionless하다. -&gt; 서버는 클라이언트를 구별할 수 없다.</p>
<p>CONNECTIONLESS -&gt; HTTP에서, 클라이언트가 요청을 서버에 보내고, 서버는 클라이언트에게 응답하고, TCP/IP연결 끝는 특성.</p>
<p>STATELESS -&gt; 연결을 끊는 순간 클라이언트와 서버의 통신이 끝나며 상태정보를 유지하지 않는 독립적인 특성!</p>
<h2 id="쿠키">쿠키</h2>
<h3 id="뭔가-브라우저-클라이언트-느낌-서버-밖의-세상-이름도-쿠키-서버에서는-과자-구우면-맛없을-느낌-더-클라이언트랑-친한느낌적인-느낌">뭔가 브라우저, 클라이언트 느낌. 서버 밖의 세상. 이름도 쿠키. 서버에서는 과자 구우면 맛없을 느낌. 더 클라이언트랑 친한느낌적인 느낌.</h3>
<ol>
<li>브라우저의 클라이언트에 키:밸류 형태로 저장되어있는 작은 파일.</li>
<li>클라이언트의 상태 정보를 로컬에 저장했다가 참조한다.</li>
<li>클라이언트에 300개까지 쿠키저장 가능, 하나의 도메인당 20개의 값만 가질 수 있으며, 하나의 쿠키값은 4KB까지 저장이 가능하다. </li>
<li>Response Header에 Set-Cookie 속성을 사용하면 클라이언트에 쿠키를 만들 수 있다.</li>
<li>쿠키는 사용자가 따로 요청하지 않아도 브라우저가 Request 시에 Request Header를 넣어서 자동으로 서버에 전송한다.</li>
</ol>
<h2 id="세션">세션</h2>
<h3 id="이름에서-보이는-뭔가-고급스러움-느낌적인-느낌-ㅅ이-많은-것을-보니-뭔가-서버의-냄새가-난다-그렇다-서버측에서-관리한다">이름에서 보이는 뭔가 고급스러움. 느낌적인 느낌. ㅅ이 많은 것을 보니 뭔가 서버의 냄새가 난다. 그렇다. 서버측에서 관리한다.</h3>
<ol>
<li>사용자 정보를 파일 브라우저에 저장하는 쿠키와 달리 세션은 서버 측에서 관리한다.</li>
<li>서버에서 클라이언트를 구분하기 위해 세션 ID를 부여하며, 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지한다.</li>
<li>접속 시간에 제한을 두어 일정 시간 응답이 없다면 정보가 유지되지 않게 설정 가능하다.</li>
<li>데이터를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 사용자가 많아질수록 서버 메모리를 많이 차지하게 된다.</li>
</ol>
<h2 id="쿠키-vs-세션-비교">쿠키 VS. 세션 비교.</h2>
<ol>
<li>데이터 저장위치: 쿠키는 클라이언트, 세션은 서버.</li>
<li>보안: 저장위치 때문에 쿠키는 스니핑 (중간에 해커가 가로채서 정보 바꿔가갖고 사용자 정보 빼돌리는 것) 에 당할 우려가 있지만, 세션은 쿠키를 이용해 세션 아이디만 저장하고 서버에서 처리하기 때문에 보안성은 쿠키보다 세션이 더 크다고 한다.</li>
<li>라이프사이클: <ul>
<li>쿠키는 브라우저를 종료해도 만료기간이 남아있으면 존재하지만,</li>
<li>세션은 브라우저 종료해도 만료기간에 상관없이 끝 -&gt; 그냥 브라우저 끄면 끝.</li>
</ul>
</li>
<li>속도: 쿠키 &gt;  세션. (아무래도 서버는 복잡하니까 속도도 더 뭔가 느릴것같은?)</li>
</ol>
<p>업데이트되면 당연히 항상 보이는것은 버그픽스 아니면 보안 업그레이드. 상당히 보안쪽으로 중요한 것을 알 수 있다. 그런데 궁금한게, 그런데 왜 우리나라는 보안에 뭔가 투자를 안하는 느낌이지? 내가 몰라서 그런가...아무튼 보안 굉장히 중요한것이다.. 우리나라 해커들 화이팅! 블랙해커말고....화이트해커들만!</p>
<h2 id="웹스토리지-로컬-스토리지와-세션스토리지">웹스토리지 (로컬 스토리지와 세션스토리지)</h2>
<h3 id="업그레이드-된-버전이다html5부터-추가된-저장소라고한다-오-분명-보안-업그레이드-될것이고-뭐-용량도-커졌을것이고그러지않을까">업그레이드 된 버전이다!HTML5부터 추가된 저장소라고한다! 오! 분명 보안 업그레이드 될것이고 뭐 용량도 커졌을것이고...그러지않을까?</h3>
<ol>
<li>클라이언트에 데이터를 저장할 수 있도록 HTML5부터 추가된 저장소</li>
<li>간단한 Key-Value 스토리지 형태</li>
<li>쿠키와 달리 자동 전송의 위험성이 없음</li>
<li>오리진(Origin)(도메인,프로토콜,포트) 단위로 접근이 제한되는 특성 덕분에 CSRF로 부터 안전. </li>
</ol>
<blockquote>
<p>CSRF 공격(Cross Site Request Forgery)은 웹 어플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 만드는 공격입니다.CSRF를 통해 해커는 희생자의 권한을 도용하여 중요 기능을 실행하는 것이 가능합니다. 예를들어, 페이스북에 희생자의 계정으로 광고성 글을 올리는 것이 가능해 집니다. (물론 페이스북은 CSRF 공격에 대해 잘 대응을 하였겠지만, 이번 글에서 피해 서비스 = 페이스북으로 설명하겠습니다.) 와우..
출처: <a href="https://itstory.tk/entry/CSRF-%EA%B3%B5%EA%B2%A9%EC%9D%B4%EB%9E%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-CSRF-%EB%B0%A9%EC%96%B4-%EB%B0%A9%EB%B2%95">https://itstory.tk/entry/CSRF-공격이란-그리고-CSRF-방어-방법</a> [덕&#39;s IT Story:티스토리]</p>
</blockquote>
<ol start="5">
<li>쿠키보다 큰 저쟝 용량 지원(모바일 2.5MB, 데스크탑 5~10MB)</li>
<li>서버가 HTTP 헤더를 통해 스토리지 객체를 조작할 수 없음(웹 스토리지 객체 조작은 JavaScript 내에서만 수행)</li>
<li>오직 문자형(string) 데이터 타입만 지원</li>
<li>로컬 스토리지(Local Storage)와 세션 스토리지(Session Storage)가 있으며, 같은 Storage 객체를 상속하기 때문에 메서드가 동일</li>
</ol>
<p>3.1 LOCAL STORAGE</p>
<ol>
<li>사용자가 데이터를 지우지 않는 이상, 브라우저나 OS를 종료해도 계속 브라우저에 남아있음 (영구성) -&gt; 스토리지계의 쿠키?</li>
<li>단, 동일한 브라우저를 사용할 때만 해당.</li>
<li>지속적으로 필요한 데이터 저장(자동 로그인 등).</li>
</ol>
<p>3.2 SESSION STORAGE</p>
<ol>
<li>데이터가 오리진 뿐만 아니라 브라우저 탭에도 종속되기 때문에, 윈도우나 브라우저 탭을 닫을 경우 제거</li>
<li>일시적으로 필요한 데이터 저장(일회성 로그인 정보, 입력폼 저장 등)</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[R.E.S.T. +-ful A.P.I]]></title>
            <link>https://velog.io/@bright_root/R.E.S.T.-ful-A.P.I</link>
            <guid>https://velog.io/@bright_root/R.E.S.T.-ful-A.P.I</guid>
            <pubDate>Thu, 16 Jun 2022 03:12:25 GMT</pubDate>
            <description><![CDATA[<h2 id="restful-api-rest-api">RESTFUL API? REST API?</h2>
<p>프로젝트하면서 백엔드에서,</p>
<p>&quot;API 만들었어요 확인하고 문제되는거 말씀해주세요.&quot;</p>
<p>그럼 혼자 나는,</p>
<p>&quot;그래요, 잠시만요, GET요청부터 해볼게요&quot;</p>
<p>400 500 등 이상한 에러가뜨면,</p>
<p>나는, &quot;xxxxxx/xxxx 안되고있어요 확인해주세요&quot;</p>
<p>백엔드가그러면, &quot;엇, 그럴리가...엇 안되네요 알겠습니다!&quot;</p>
<p>아니면 내가, &quot;엇 제가 다르게 하고있었어요 죄송합니다!&quot;</p>
<p>처음 혹은 백엔드와 통신할때 이런다항상.</p>
<p>기획 회의할때부터 저 말은 나온다. </p>
<p>&quot;REST API 사용 할거에요~ RESTFUL~&quot;</p>
<p>RESTFUL? -&gt; 편안한 뭔가 편한 이런뜻인데... 
RESTFUL API? -&gt; 편한 API? 내가 개발자 공부하면서 인생 편한적 없었는데아직?</p>
<h3 id="rest부터">REST부터</h3>
<blockquote>
<p>REST -&gt; REpresentational State Transfer 뭔가 표현적인 상태 이동? 구상적인 표현?
&quot;자원을 이름 (자원의 표현)으로 구분해 해당 자원의 상태(정보)를 주고받은 모든것을 의미.&quot;
-&gt; RESOURCE자원의 REPRESENTATION표현에 의한 상태전달이라는 뜻이라는데... 흠...</p>
</blockquote>
<p>&quot;REST는 CLIENT 와 SERVER사이의 통신 방식 중 하나입니다.&quot;</p>
<ul>
<li><p>자원: 말그대로 소프트웨어가 가지는 모든 자원들. 문서, 그림, 데이터, 소프트웨어가 관리하는 모든것들 등등</p>
</li>
<li><p>표현: 그 자원을 잘 표현한것.
예) DB을 열었다. 요리 레시피 정보가 쫘르르르륵 나온다. 이 쫘르르륵 나온 정보에 대해서 단순히 깔끔하게 표현할 때 -&gt; cookingrecipe 를 자원의 표현으로 정할 수 있다.</p>
</li>
<li><p>상태전달: 위에서 cookingreciple라고 하는 자원의 상태로 표현한 것을 요청하고 응답한다. 이때 형식은 나는 JSON을 많이 써봤다. (일반적으로, JSON 과 XML 을 많이 쓴다고함.)</p>
</li>
</ul>
<p>왜 이걸 쓸까 라는 생각이 드는 순간, 감사하게도 내가 찾은 기술 블로그에서 설명해주신다: 기존의 웹기술과 HTTP 프로토콜을 그대로 활용하기 때문에.</p>
<p>여기서 잠깐!</p>
<p>나 이상하게 헷갈린다...URI, URL 등등. 이상하게 좀 어정쩡하게 아는 기분이다. 이참에 제대로 알고 넘어갑시다. </p>
<p><img src="https://velog.velcdn.com/images/bright_root/post/9c305a74-bdeb-4cf1-a155-c39a15ada39e/image.png" alt=""></p>
<blockquote>
<p>URI는 Uniform Resource Identifier
URL은 Uniform Resource Locator
URN은 Uniform Resource Name
URI = URN + URL</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/bright_root/post/c6d17cb2-dad0-423d-891e-c4737ad8aa4c/image.png" alt=""></p>
<p>그림이랑 내가 현재 글쓰고 있는 주소창에 있는 URL보고 한번에 이해. 자 다시 REST시작.</p>
<h3 id="rest의-구성요소">REST의 구성요소</h3>
<p>내가 프로젝트를 하면서도 느끼지만, REST는 다음과 같은 세가지 구성요소를 갖는다.</p>
<p>(1) 자원(Resource) -&gt; URI = URL + URN
지금 쓰고있는 이 벨로그 글 URI 보여주면~
<a href="https://velog.io/write?id=24e52e79-f5f6-44e3-889a-6a6219ac962d">https://velog.io/write?id=24e52e79-f5f6-44e3-889a-6a6219ac962d</a>
id=24e@!#!@#!@#!@# 이 부분이 지원 구별하는 id. 서버에 존재한다.
이것으로 Client는 서버와 통신할때 자원을 찾는다.
여담이지만, 미국에서 한 챕터의 프레젠테이션을 찾았는데, 그 다음 챕터의 자료도 있을까싶어서 뒤에 id에서 번호라던가 알파벳을 나름 머리써서 올렸더니 다음챕터 나와서 와우 했었다. 그런데 이렇게까지 id가복잡하진 않았지...</p>
<p>(2) 행위(Verb) -&gt; Method
CRUD(CREATE, READ, UPDATE, DELETE) -&gt; GET POST PUT PATCH DELETE 메소드! 이걸로 내가 필요한것을 요청하고 서버에서 저 메소드 대로 응답해준다. 이것들은 HTTP프로토콜의 METHOD라고 하는데 이 부분이 강력하게 왜 RESTFUL API를 사용하는지 말해주는 것 같다.
내 경험 곁들여보면:
POST (CREATE -&gt; 무엇인가를 입력해서, 서버에 무엇인가를 요청을 하면 서버에서 내가 원하는 정보를 응답해준다.)
GET (READ -&gt; 서버에 무엇인가를 입력한다기 보단 요청을 하면, 서버에서 응답을 할때 자세하게 답해주는게 아니라 요청에 대해서 반응만 해주는 느낌이다? 클라이언트에서 요청만 한 느낌. 
PUT (UPDATE -&gt; 서버에 있는 내가 입력했던 전체 정보들을 바꿀때)
PATCH (UPDATE -&gt; PUT이랑 비슷한데, 대신에 다 바꾸는게 아니라 딱 어느 일부분만 바꾼다.)
DELETE (DELETE -&gt; 말그대로 서버에 있는 정보를 삭제할때 쓴다. 나도 이것은 써본적이 없다. 그런데 안전성 문제로 서버에서 비활성화 시킨다고 한다. 아하! 그럼 말좀 해주지..몰랐어</p>
<p>(3) 표현(Representation of Resource)</p>
<ul>
<li>CLIET 와 SERVER가 일반적으로 데이터를 주고받는 형태는 JSON, XML, TEXT, RSS등이 있다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/bright_root/post/08910f1b-b11f-49a4-a9bd-52e90db946b1/image.png" alt=""></p>
<p>XML (eXtensible Markup Language) 
JSON (JavaScript Object Notation) </p>
<p>와 잠깐 여담인데... 이거 쓰면서 그동안 막 아무것도 모르고 &#39;일단 머리박고 쓰자&#39;에서 점점 뭔가 개념 잡혀간다. 확실히 머리박고 써보고나서 개념정리하는 것도 또하나의 공부법이긴 한가보다. 나는 원래 개념 안익히고 바로 시작하면 어질어질해서 집중도 잘 안되고 진도도 안나가는데...이게 되는구나...신기할뿐이다 아무튼 특징에 대해서 공부해봅시다.</p>
<h3 id="rest의-특징">REST의 특징</h3>
<p>(1) 지금까지 내가 프로젝트 한 경험으로 말한다면, SERVER-CLIENT(서버-클라이언트 구조) 그냥 나는 프론트 - 백엔드 구조로 느낌으로 알고 넘어가려한다.
자원이 있으면 SERVER, 자원을 요청하면 CLIENT. 
CLIENT: 사용자 인증, context(세션, 로그인정보) 직접 관리.
REST SERVER: API제공하고, 비즈니스 로직 처리 및 저장 책임.</p>
<p>오 신기해. 내가 해본 모든 경험이 개념화 되어있다니 ㅋㅋㅋㅋ</p>
<p>(2) Stateless (무상태)</p>
<blockquote>
<p><a href="https://www.interviewbit.com/blog/stateful-vs-stateless/#:~:text=Stateful%20expects%20a%20response%20and,the%20state%20of%20the%20request.&amp;text=This%20makes%20the%20design%20heavy,data%20needs%20to%20be%20stored">https://www.interviewbit.com/blog/stateful-vs-stateless/#:~:text=Stateful%20expects%20a%20response%20and,the%20state%20of%20the%20request.&amp;text=This%20makes%20the%20design%20heavy,data%20needs%20to%20be%20stored</a>.</p>
</blockquote>
<p>이것은 STATEFUL VS. STATELESS 차이이다. 일단 간단하게, stateful은 모든 것을 다 알고싶은 우리엄마, stateless 일단 냅두고 지켜보는 우리아빠 정도로 느낌 가져가자. </p>
<ul>
<li>HTTP -&gt; STATELESS -&gt; REST도 마찬가지. 왜냐하면 HTTP기반으로 REST 동작하니까.</li>
<li>CLIENT의 context를 Server에 저장하지 않습니다. <ul>
<li>세션과 쿠키 신경 안써도 되서 구현이 단순하다고한다....</li>
</ul>
</li>
<li>각 Server의 &quot;각각각각각&quot;들의 요청을 완전히 별개의 것으로 인식하고 처리한다.<ul>
<li>각 API서버는 Clinet의 요청만을 단순 처리한다.-&gt; 각각 처리한다고 했으니까 그만큼 요청들을 단순 처리한다는 말인 것 같다.</li>
<li>즉, 이전요청이 다음 요청의처리에 연관되면 안된다 -&gt; 모든지 각각 개인주의 차가운 느낌으로 처리해야하는데 연관되면 안된다는 느낌인 것 같은데...(DB에 의해 바뀌는 것은 허용)</li>
<li>Server의 처리 방식에 일관성을 부여하기 때문에 서비스의 자유도가 높아집니다! -&gt; 차가운 아이인건 맞지만 그래도 심성은 따뜻하다. 왜냐하면 서비스 자유도 주니까. 능력주의인듯.</li>
</ul>
</li>
</ul>
<pre><code>난 저렇게 내 느낌대로 써야 뭔가 공부가 잘되더라. 아무튼. 쉿 하고.</code></pre><p>(3) Cacheable (캐시 처리 기능) </p>
<p>캐시에 대해...참고사항</p>
<blockquote>
<p><a href="https://mangkyu.tistory.com/69">https://mangkyu.tistory.com/69</a></p>
</blockquote>
<p>와 OSI 계층, TCP 인터넷 계층 말고 저장공간 계층구조....이거 학부때 배웠던것인데 와 생각났다진짜신기하다. 사람의 뇌라는게 참. 갑자기 확 스파크...이게 생각이나네..</p>
<p>우선 조용히하고 쉿하고. 쉿. </p>
<p>캐시는 이런 느낌으로 알면 된다. 내가 이 벨로그 작성하고 닫았어. 그런데? 엇? 나 지금 글 수정 해야할것같아 하고서 브라우저 다시 킨다. 킨다음에 우리는 url에다가 주소를 입력할 것이다.
<a href="https://velog.io...a#@$!#!@#!@%EA%B7%B8%EB%9F%B0%EB%8D%B0">https://velog.io...a#@$!#!@#!@그런데</a>. 때마침 우리가 잘 알다시피 주소창에 자동으로 저렇게 치다보면 전에 방문했던 기록들을 참고해서 자동완성으로 주소를 입력해준다. 그런데 여기서 자동완성 검색기능이 캐시가 아니라 자동검색되게 방문기록을 찾아보았을때 확인해 주는 것을 가능하게 해주는게 캐시다. 캐시는 한마디로 데이터를 미리 메모리에 데이터 저장해 놓았다가 우리가 다시 필요로 할때, 불러다 써주는 느낌!</p>
<p>그래서, </p>
<ul>
<li>캐싱기능 적용 가능</li>
<li>대량의 요청을 효율적으로 처리 가능</li>
</ul>
<p>(4) Layered System (계층구조) -&gt; 이거 살짝 네트워크적 요소가 강해서...잘 모르긴하는데 열심히 찾아봤음..</p>
<p>우선 프록시와 게이트웨이를 알아야 할 것 같아서...뒤적거려본결과...</p>
<blockquote>
<p><a href="https://swimjiy.github.io/2020-04-11-web-gateway">https://swimjiy.github.io/2020-04-11-web-gateway</a></p>
</blockquote>
<p>감사합니다...블로거님...</p>
<ul>
<li>Client 는 RESTAPI SERVER 만 호출가능. -&gt; 당연하지 </li>
<li>REST SERVER는 다중계층으로 구성가능. -&gt; 사실 이말 무슨말인지 100% 이해는 아니다..찾아봅시다....나중에...<ul>
<li>보안, 로드밸런싱, 암호화 등 (-&gt; 대충 보안 강화한다 이런뜻같다) 을 위한 계층을 추가하여 구조를 변경 할 수 있습니다.</li>
<li>Proxy, Gateway와 같은 네트워크 기반의 중간매체를 사용할 수 있습니다.</li>
<li>단, Client 쪽에서 중간매체서버인지 어디랑 통신하는지 몰라요~</li>
</ul>
</li>
</ul>
<p>(5) Uniform Interface (인터페이스 일관성)</p>
<ul>
<li>URI로 지정한 Resource 에 대한 요청을 통일되고, 한정적으로 수행하는 아키텍쳐 스타일을 의미합니다. -&gt; crud 이런게 한결같이 폼의 형태로 그 형태 그대로 요청하고 응답한다는 그런 말 같아요!</li>
<li>HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하며, Loosely Coupling (느슨한 결함) 형태를 갖습니다.<ul>
<li>즉, 특정 언어나 기술에 종속되지 않음.</li>
</ul>
</li>
</ul>
<p>(6) Self-Descriptive (자체표현) -&gt; 요청 메세지만 보고도 쉽게 이해할 수 있는 자체 표현 구조로 되어있다.</p>
<hr>
<h2 id="rest-api에-대해-이제-시작-그동안은-rest-개념탑재">REST API에 대해 이제 시작. 그동안은 REST 개념탑재.</h2>
<p>와 이제 드디어 REST API에 대해 알아간다.</p>
<p>그런데 이미 내가 프로젝트때 많이 써본것이여서, 전반적으로 내가봤을때 REST 개념에 API합친듯하 느낌.</p>
<p>REST API란-&gt; REST특징을 기반으로 서비스 API를 구현한것. 많은 Open Api (카카오맵, 구글맵, 공공데이터 등등) 마이크로서비스(하나의 큰 어플리케이션을 여러개의 작은 어플리케이션으로 쪼개어 변경과 조합이 가능하도록 만든 아키텍처) 등을 제공하는 기업 대부분이 REST API 제공한다고 한다. JSON 형식의 데이터로 API 보여주던데...그렇구나....</p>
<p>REST API특징-&gt; 이건 내가 처음에 맨 처음으로 axios사용해서 백엔드랑 통신할때도 느낀거지만, 그냥 아무것도 개념도 없는 상태로 봐도, 대충 영어로 메소드 읽고 데이터 정보 무엇이 담겨있나정도 확인하다보면 대충 추론 가능하다. 이것이 큰 특징이라고한다.</p>
<h2 id="rest-api-디자인-가이드">REST API 디자인 가이드</h2>
<p>갑자기 무슨 디자인이냐? 그런데. 이게 꾀나 중요하다. 나는 만들어 본 적은 없지만, 백엔드에서 하는 것을 흠칫 옆에서 들어보고 봤는데, 솔직히 내 눈에서 보면 그냥 URI이름짜고 그러고 있는건데 별거 아닌것 같이 보이지만, 이것이 API설계시 가장 중요하다고 한다.
-&gt; 2가지로 요약 가능하다고 한다.</p>
<ul>
<li>첫번째, URI는 정보의 자원을 표현해야한다. -&gt; </li>
<li>두번째, 자원에 대한 HTTP Method (GET, POST, PUT, PATCH, DELETE)로 표현한다.<ul>
<li>행위(Method)는 URI에 포함하지 않는다.</li>
</ul>
</li>
</ul>
<p>REST API 설계 규칙.</p>
<ol>
<li><p>URI는 명사를 사용한다.(리소스명은 동사가 아닌 명사를 사용해야 한다.)
 1-1. 아래와 같은 동사를 사용하지 말 것</p>
<p> /getAllUsers
 /getUserById
 /createNewUser
 /updateUser
 /deleteUser</p>
</li>
<li><p>슬래시( / )로 계층 관계를 표현한다.</p>
</li>
<li><p>URI 마지막 문자로 슬래시 ( / )를 포함하지 않는다.</p>
</li>
<li><p>밑줄( _ )을 사용하지 않고, 하이픈( - )을 사용한다. -&gt; 이건 기억난다. 저번에 백엔드 어떤분이 오셔서 이거 밑줄 사용하지 말아야한다고 지적하고 갔었다...</p>
</li>
<li><p>URI는 소문자로만 구성한다. -&gt; 이거는 지켜지지 못했던것같다. 프로젝트 한것 기억해보면...아직 있는듯...</p>
</li>
<li><p>HTTP 응답 상태 코드 사용</p>
</li>
</ol>
<ul>
<li>클라이언트는 해당 요청에 대한 실패, 처리완료 또는 잘못된 요청 등에 대한 피드백을 받아야 한다.
HTTP 상태 코드 정리</li>
<li><blockquote>
<p>굉장한 에러의 바다에 빠지게 해준다. 아주좋다.</p>
</blockquote>
</li>
</ul>
<ol start="7">
<li>파일확장자는 URI에 포함하지 않는다.
Ex) <a href="http://dev-coco.tistory.com/restapi/220/photo.jpg">http://dev-coco.tistory.com/restapi/220/photo.jpg</a> (X)</li>
</ol>
<h2 id="rest-api-vs-restful-api-차이는">REST API VS. RESTFUL API 차이는?</h2>
<p>RESTFUL, 우리의 편안한 RESTFUL API는 위와 같이 REST설계규칙을 잘 준수한 것이다.
즉, REST의 원리를 잘 따르는 시스템을 RESTFUL이란 용어로 지칭된다고 한다.
잘 준수된 RESTFUL API를 보면 눈에 확 들어온다! 그것에 모든 정보가 다 잘 담겨있다. </p>
<p>요약하자면-&gt; URI로 무슨 정보 무슨자원 표현이 가능하고, 자원이 어떻게 이동하고 이런 메소드들을 HTTP METHOD에 명시한다는 것!!</p>
<hr>
<p>참고, 굉장히 많이 참고, 잘배웠습니다:</p>
<blockquote>
<p><a href="https://dev-coco.tistory.com/97">https://dev-coco.tistory.com/97</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[눈에 보일때마다 아오...OSI 7계층.]]></title>
            <link>https://velog.io/@bright_root/%EB%88%88%EC%97%90-%EB%B3%B4%EC%9D%BC%EB%95%8C%EB%A7%88%EB%8B%A4-%EC%95%84%EC%98%A4...OSI-7%EA%B3%84%EC%B8%B5</link>
            <guid>https://velog.io/@bright_root/%EB%88%88%EC%97%90-%EB%B3%B4%EC%9D%BC%EB%95%8C%EB%A7%88%EB%8B%A4-%EC%95%84%EC%98%A4...OSI-7%EA%B3%84%EC%B8%B5</guid>
            <pubDate>Tue, 14 Jun 2022 05:51:20 GMT</pubDate>
            <description><![CDATA[<h2 id="osi-7계층과-tcpip-4계층">OSI 7계층과 TCP/IP 4계층.</h2>
<p>학부때부터 아주 눈에 가시였다. 아주 보기싫다. 나름 간단히 정리해서 표로 막 우리 학생들한테 잘보이려고 이쁘게 7가지 무지개 색깔로 칠해놓고 자잘자잘 설명하고. 그런데, 다 못외우면 교수가 뭐라하고. 학부때, Information Systems시간에 배웠는데 이상하게 졸업과 동시에 다 까먹었다. 이상하다. 분명 밤새면서 한문제라도 더 맞으려고 공부했던 내용인데. 잠시 생물 연구 일을 하다가 돌아왔더니 아무것도 생각이 안나네? </p>
<p>내가 이 7계층을 다시 리마인드하고 정리하려는 이유는...TCP/IP를 보거나, 아니면 어떤 인터넷 관련 데이터교환 및 여러가지 발생하는 일들을 공부하려할 때 갑자기 뜬금없이 눈에 보일때가 있다. </p>
<p>OSI 라는 말 자체부터 쉽지않다.
인생은 쉽지않다. 하나를 알기위해서 여기저기서 온갖 지식을 끌어와야한다. </p>
<p>Open System interconnection Reference Model: 개방형 시스템 상호연결 모델.
쉽게말해서, 그냥 우리가 매일 쓰는 인터넷! 여기서 데이터가 나가고 들어오는 통신과정을 보기좋게 7단계로 나눈것이다. 이렇게 나누어야 어디 단게에서 아 이부분이 문제구나 오 이게 이거구나 하면서 평범한 사람들이 고칠수있게? 교육을 위해 만들어진 것이라고 한다. 또한 네트워크 표준이라고 한다. 참고로 ISO:International Organization for Standardization 여기서 만들었다. </p>
<p>왜냐하면 지금은 정리정돈이 잘 되어있었지만, 옛날같은 경우에는 네트워크 개념들이 정비가 되지 않았었다고 한다. 그래서 저렇게 단순하게 7계층을 만들었다고한다...ㅠ</p>
<p><img src="https://velog.velcdn.com/images/bright_root/post/0017d1a9-9edb-4f2d-a661-5bbba39ca4a6/image.png" alt=""></p>
<p>그렇지. 이거다. 날 항상 설레게해서 머리를 아프게하는 이 무지개 7계층. 
꼭대기로 올라갈수록, 사용자의 눈에 보이는 익숙한 그런 모습을 갖고있다 (난 아닌걸...?).</p>
<p>TCP/IP 4계층은 진짜 있는줄도 몰랐다..그냥 눈에 안들어온다. 왜그런지 잘 생각해보면, 아마, 시험보기위해서 빠짝 공부하고 메모리에서 바로 비웠나보다 ㅋㅋㅋㅋㅋㅋ</p>
<p>그런데 최근에 TCP에 대해서 공부하면서 다시 기억을 되살려 보았다. 이것은 인터넷에 적용한 모델이다. OSI 는 전반적인 네트워크에 대해 다루었다면, TCP/IP는 인터넷에 집중해서 네트워크 계층과 서로 밀접한 관계가 있는 것들끼리 묶어서 4계층으로 만든것이다. </p>
<blockquote>
<p>TCP-&gt; Transmission Control Protocol의 약자이고, 말 그대로 프로토콜이다. IP는 Internet Protocol 약자이다.
한마디로 전송제어 프로토콜이다. 인터넷 프로토콜을 기반으로 데이터를 전송하고 수신할때 사용되는 프로토콜이란 말이다.
데이터를 전송할때는 3way handshake를 하고, 데이터 전송을 끊을때는 4way handshake를 한다.
<a href="https://velog.io/@hidaehyunlee/TCP-%EC%99%80-UDP-%EC%9D%98-%EC%B0%A8%EC%9D%B4">https://velog.io/@hidaehyunlee/TCP-%EC%99%80-UDP-%EC%9D%98-%EC%B0%A8%EC%9D%B4</a>
이거 참고.</p>
</blockquote>
<p>오 구글링 해서 더 자세한 설명 찾아보니까 이렇게 나온다. 이거 좋다.</p>
<p><img src="https://velog.velcdn.com/images/bright_root/post/07f72a2c-23ea-4480-96b7-2e327d627b80/image.png" alt=""></p>
<p>이분의 글에서 괜찮은 것이 많아 가져와본다. 감사합니다 글쓴이님.</p>
<blockquote>
<p><a href="https://velog.io/@jehjong/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%9D%B8%ED%84%B0%EB%B7%B0-TCPIP-4%EA%B3%84%EC%B8%B5">https://velog.io/@jehjong/%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%9D%B8%ED%84%B0%EB%B7%B0-TCPIP-4%EA%B3%84%EC%B8%B5</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/bright_root/post/64fc44ac-f67b-422f-9ca2-fdf3cbdd49ea/image.png" alt=""></p>
<blockquote>
<p><a href="https://www.stevenjlee.net/2020/02/09/%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-osi-7%EA%B3%84%EC%B8%B5-%EA%B7%B8%EB%A6%AC%EA%B3%A0-tcp-ip-4%EA%B3%84%EC%B8%B5/">https://www.stevenjlee.net/2020/02/09/%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-osi-7%EA%B3%84%EC%B8%B5-%EA%B7%B8%EB%A6%AC%EA%B3%A0-tcp-ip-4%EA%B3%84%EC%B8%B5/</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[CORS란 무엇인가? 알고쓰자...?]]></title>
            <link>https://velog.io/@bright_root/CORS%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EC%95%8C%EA%B3%A0%EC%93%B0%EC%9E%90</link>
            <guid>https://velog.io/@bright_root/CORS%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EC%95%8C%EA%B3%A0%EC%93%B0%EC%9E%90</guid>
            <pubDate>Mon, 13 Jun 2022 13:35:47 GMT</pubDate>
            <description><![CDATA[<h2 id="cors-에러-백엔드랑-협업할때-자주보던것">CORS 에러, 백엔드랑 협업할때 자주보던것.</h2>
<p>백엔드와 프로젝트를 진행하다보면, 항상 마주하는 에러: CORS에러.
&quot;무슨에러에요?&quot;
&quot;CORS에러라는데요..?&quot;
&quot;제잘못인가요? 그쪽잘못인가요?&quot;
&quot;둘다인것같은데요&quot;</p>
<p>백엔드든 프론트엔드든 우리 둘다 처음 웹프로젝트 하는 사람들이라...검색해봤었다.</p>
<p>잘못이 있다고 친절하게 말을 해주면 뭔지 알고 다음에 마주치지 않도록 해야하는것.</p>
<p>좀 알아봅시다.</p>
<h2 id="sop부터-알아야한다더라">SOP부터 알아야한다더라...</h2>
<p>그냥 CORS만 알기엔 내가 너무한가보다. 구글링 해보니까, 각종 블로그에 개발자들이 써놓은 글들을 보면 SOP가 빠지지 않는다. 대학교에서 공부할때, 특히 지원할때 SOP는 나에게, Statement of Purpose. 즉,지원동기서 이런 서류였는데... 아무튼 조용히하고.</p>
<p>Same Origin Policy -&gt; 같은 출처 정책. 자바스크립트 엔진 표준 스펙 저책인데, 같은 출처에서만 자원들을 공유 할 수 있도록 하는 뭔가 좀 굉장히 배타적인 정책이다.</p>
<p>여기서 자바스크립트 엔진이란, 내 머릿속에 알고있는것은 콜스택, 콜백큐, 이벤트루프, 메모리 힙 이런 구조로 이루어져 있는 것이다. 주로 웹 브라우저를 사용할때, 코드가 엔진에서 어떤 원리로 돌아가는지를 보여주는 그런 것이다. 어차피 이것도 공부해야하니 나중에 설명.</p>
<p>보안을 지키기 위해 만들어진 정책이 SOP라고 한다. 같은 출처에서만 자원 공유가능하도록. 누구든지 내 계정의 비밀번호를 가져가는 스크립트 (XSS, Cross-Site Scripting) 같은 것을 만들 가능성을 안만들기 위해서 그렇단다.</p>
<h2 id="여기서-잠깐-같은-출처-라는-말이-좀-거슬려">여기서 잠깐, &#39;같은 출처&#39; 라는 말이 좀 거슬려.</h2>
<p><img src="https://velog.velcdn.com/images/bright_root/post/dd306ecc-a4c5-4719-ba7a-a0d6c4492448/image.png" alt=""></p>
<p>URL에는 다음과 같이 생겼다. Origin = Protocol + Host + Port / Path</p>
<p>Origin이라는 것을 통해서 같은 출처인지 아닌지를 비교해 본다고 한다. </p>
<p>URL포트번호가 생략 되있는 경우가 많다고 한다. </p>
<p>예)
스프링 백엔드쪽 -&gt;  <a href="http://localhost:8080">http://localhost:8080</a>
리액트 프론트쪽 -&gt; <a href="http://localhost:3000">http://localhost:3000</a></p>
<p>두개는 다른 SOP를 가진다. 왜? 포트 번호가 다르잖아. 딱 보이잖아.</p>
<p>리액트랑 스프링이 서로 접근하려면 당연히 뭐해야겠어?
-&gt; 그래서 프로젝트 할때, 로컬끼리 포트가 달라서 CORS설정 해줘야 한다. 
왜? 포트번호가 다르다는 것은 SOP가 다르다는 뜻이니까.
이해했어?</p>
<h2 id="드디어-cors-이제-대충-알듯">드디어 CORS. 이제 대충 알듯.</h2>
<p>SOP정책이랑 CORS 랑 다른 것이 아니다. CORS: Cross-Origin Resource Sharing. 이것은 SOP정책 안에 있는것이다. 이것은 SOP정책에서 예외 상황을 두어서 ORIGIN (Protocol + Host + Port) 끼리도 자원을 주고 받을 수 있는 정책을 넣어준 것이다.</p>
<p>차이를 말하자면: 이전에는 동일한 도메인에서만 자료를 받아왔지만, 클라이언트에서 도메인이 다른 서버를 사용하는 일이 많아지면서 CORS등장!</p>
<p>스프링 백엔드쪽. 즉, 서버측에서 CORS를 설정해 줘야한다. -&gt; ORIGIN, METHOD로는 접근만 가능 -&gt; 제한적인 접근이 가능하다는 말.</p>
<h2 id="백엔드에서-설정해-줘야-하는건-맞는데-동작-원리-알면-더좋을거같습니답">백엔드에서 설정해 줘야 하는건 맞는데, 동작 원리 알면 더좋을거같습니답.</h2>
<p><img src="https://velog.velcdn.com/images/bright_root/post/fc0b31d6-4448-455e-8408-0b4ef800fd6f/image.png" alt=""></p>
<p>기본적인 동작-&gt; CORS 동작-&gt; Simple Request랑 Preflight가 있다고한다.</p>
<p>클라이언트에서 W3C 사양에 따라서, 브라우저는 지원되는 메소드가 서버에서 유효한지 아닌지 확인하기 위해서 실제 요청을 보내기전에 OPTIONS요청을 보낸다고 구글링해보니까 그런다.
(<a href="https://velog.io/@entry_dsm/%EC%8A%88%EC%8A%89-%EC%8A%88%EC%8A%89.-%EC%8A%89.-%EC%8A%89.C..C.CORS-%EB%86%88%EC%95%84">https://velog.io/@entry_dsm/%EC%8A%88%EC%8A%89-%EC%8A%88%EC%8A%89.-%EC%8A%89.-%EC%8A%89.C..C.CORS-%EB%86%88%EC%95%84</a>)
(<a href="https://medium.com/@f2004392/cors-preflight-request-options-9d05b9248e5a">https://medium.com/@f2004392/cors-preflight-request-options-9d05b9248e5a</a>).</p>
<h3 id="simple-request">Simple Request:</h3>
<h4 id="simple-request-로-보낼때는-세가지-조건이-충족-되어야한다">Simple Request 로 보낼때는 세가지 조건이 충족 되어야한다:</h4>
<ol>
<li>GET, HEAD, POST 메서드를 사용해야한다.</li>
<li>User agent에서 자동으로 설정한 헤더 외에 수동으로 설정할 수 있는 헤더는 Fetch에 정의되어 있는 헤더 뿐입니다.</li>
<li>Content-Type사용할 경우: application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용.</li>
</ol>
<p>HTTP요청시에, 심지어 application/json도 설정 불가능이라고 한다.</p>
<h3 id="preflight">Preflight:</h3>
<h4 id="simiple-request가-생각보다-너무-복잡해서-주로-사용하는-요청이라고-한다-사전요청--예비요청-이라고-생각하면-된다고한다">Simiple Request가 생각보다 너무 복잡해서, 주로 사용하는 요청이라고 한다. 사전요청 / 예비요청 이라고 생각하면 된다고한다.</h4>
<p><img src="https://velog.velcdn.com/images/bright_root/post/25b30f22-573f-4717-8c58-d9c18c8b8ec5/image.png" alt=""></p>
<p>Fetch API사용하여 브라우저에게 리소스 받아오라고 명령보낸다. 그러면 다음과 같이 예비요청과 본요청으로 나뉘어진다. 
예비/사전 요청: </p>
<ol>
<li>OPTIONS -&gt; 목표 리소스와의 통션 옵션을 설명하기 위해 사용되는 메소드</li>
<li>ACCESS-CONTROL-ALLOW-ORIGIN: 직역하면, 컨트롤하는거 접근하는거 허락하는 출처? 그런느낌이다. 즉, 어떤 메소드 출처등을 허용하는 지에 대한 정보를 헤더에 보내서 응답한다.</li>
</ol>
<p>이러고 나서, 브라우저가 이때 받은 응답과 보낼 요청을 비교하고, &quot;아, 서버랑 비교해보니까 뭐 이정도면 안전한거같고..음...일단 서버에서 받은 응답데이터 자바스크립트에 보내주고 통신하면 될듯.&quot; 이라 생각하고 동작한다.</p>
<p>CORS의 기본적인 것에대해서 기록을 남겨보았다. 상당히 유용하고 왜 이제서야 제대로 알게되었는지참. 프로젝트 할때, 아무것도 모르고, 그냥 &quot;이거 서버잘못이에요 제잘못이에요?&quot; 이러고 있던 내가 참. CORS에러만 뜨면 구글링하고 스쳐 지나가는 그런 범죄를 일으켰다.</p>
<p>기본적인 개념을 그래도 알게 되어서 다행이다. </p>
<blockquote>
<p>그리고 <a href="https://velog.io/@entry_dsm/%EC%8A%88%EC%8A%89-%EC%8A%88%EC%8A%89.-%EC%8A%89.-%EC%8A%89.C..C.CORS-%EB%86%88%EC%95%84">https://velog.io/@entry_dsm/%EC%8A%88%EC%8A%89-%EC%8A%88%EC%8A%89.-%EC%8A%89.-%EC%8A%89.C..C.CORS-%EB%86%88%EC%95%84</a></p>
</blockquote>
<p>여기 글써주신분 덕분에 오늘 공부 제대로 했다. 감사합니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SPA, MPA 뭔지는 알겠어. 근데?]]></title>
            <link>https://velog.io/@bright_root/SPA-MPA-%EB%AD%94%EC%A7%80%EB%8A%94-%EC%95%8C%EA%B2%A0%EC%96%B4.-%EA%B7%BC%EB%8D%B0</link>
            <guid>https://velog.io/@bright_root/SPA-MPA-%EB%AD%94%EC%A7%80%EB%8A%94-%EC%95%8C%EA%B2%A0%EC%96%B4.-%EA%B7%BC%EB%8D%B0</guid>
            <pubDate>Sun, 12 Jun 2022 02:42:52 GMT</pubDate>
            <description><![CDATA[<h1 id="그래-spa-mpa-알겠다고">그래, SPA, MPA. 알겠다고.</h1>
<blockquote>
<p><img src="https://velog.velcdn.com/images/bright_root/post/767e2579-46c5-43ca-8974-c2dcebf8eb8a/image.png" alt=""></p>
</blockquote>
<p>SPA, MPA. SPA가 뭐에요? MPA가 뭐에요? 딱보니까 영어로 해보면...대충 페이지 관련된것이니까, Singe Page? A는 개발쪽에서 항상 보면 A는 Application 이런거로 많이 하니까...Ajax는 아닌것같고..Singe Page Application?오 맞았어. 그러면 MPA는? 음...페이지 관련이니까, 싱글은 하나, 여러개? Multiple? Multiple Page Application? 오 맞았다. </p>
<p>항상, 동료들이 이런거 뭐냐고 물어보면 (나한테 왜 물어보는지 모르겠다. 잘해보이나보다.) 대충 저렇게 생각했다. 뭐 페이지 하나만 렌더링 여러개 렌더링 이런식으로 대충 알고있었다. 그런데 개념에 대해 여기저기 구글링을 해보니 대충 맞았다.</p>
<h2 id="spa-와-mpa-간단히">SPA 와 MPA 간단히.</h2>
<p>Single Page Application -&gt; 한개의 페이지로 구성된 어플리케이션. 웹 어플리케이션에 필요한 모든 정적 리소스를 최초 한번에 다운로드한다. 그 이후 새로운 페이지 요청 있을때, 페이지 갱신에 필요한 데이터만 전달받아서 페이지를 갱신한다. -&gt; CSR (Client Side Rendering)
Multiple Page Application -&gt; 여러개의 페이지로 구성된 어플리케이션. 새로운 페이지 요청 있을때마다 정적 리소스가 다운로드 된다. 매번 전체페이지가 다시 렌더링 된다. -&gt; SSR (Server Side Rendering)</p>
<p>정적 리소스: HTML, CSS, JavaScript 등.</p>
<p>알기쉽게이해: SPA는 첫 요청에서, 한번에 다 서버에서 불러온다. 그다음에 사용자가 어느 부분만 누르면 그 부분에 대해서만 비동기 요청해서 서버에서 데이터 가져온다. MPA는 매 요청마다 밑에 그림같이 서버에다가 말한다. 그래서 전체 페이지가 리 랜더링 된다. 그래서 깜빡거린다. </p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/bright_root/post/542bd0c6-8fd6-4896-8ffc-e6f79d3cfded/image.png" alt="">
<a href="https://lvivity.com/wp-content/uploads/2020/08/spa-mpa-lifecycle.jpg">https://lvivity.com/wp-content/uploads/2020/08/spa-mpa-lifecycle.jpg</a></p>
</blockquote>
<h2 id="장점">장점</h2>
<h3 id="spa의-장점">SPA의 장점</h3>
<ol>
<li>좋은 사용자 경험!
 (1) 전체 페이지를 업데이트를 할 필요가 없기 때문에 빠르다! (웹사이트의 성능과 직결된다.)
 (2) 전체 페이지를 업로드하면서 발생하는 &#39;깜박&#39; 거림이 없다. 페이지의 일부만 바뀌는 것이기 때문에 application의 반응이 빠르다.</li>
<li>개발하기에 더 심플하다.
 (1) 서버의 사용없이도 개발을 시작할 수 있다.
 (2) 크롬으로 디버깅하기 쉽다.</li>
<li>로컬 데이터를 효과적으로 캐시(cache)* 할 수 있다.
 (1) SPA의 Appication은 서버에게 정적리소스를 한번만 요청한다. 그리고 받은 데이터는 전부 저장해놓는다.
 (2) 이 데이터는 오프라인에서도 사용 가능하다.</li>
</ol>
<p>(참고) 캐시(cache)란 데이터나 값을 미리 복사해 놓는 임시 장소를 가리킨다.
캐시에 데이터를 미리 복사해 놓으면 계산이나 별도의 접근 시간 없이
더 빠른 속도로 데이터에 접근할 수 있다.</p>
<h3 id="mpa의-장점">MPA의 장점</h3>
<p>SEO(Search Engine Optimization, 검색 엔진 최적화) 관점에 유리하다.* MPA는 완성된 형태의 HTML파일을 서버로부터 전달받는다. 따라서 검색 엔진이 페이지를 크롤링하기에 적합하다.</p>
<p>(참고) SEO는 홈페이지 혹은 콘텐츠를 검색 결과의 상단에 위치시키는 작업이다.
검색 엔진은 &#39;크롤링(Crawling, 웹 크롤러로 웹사이트 관련 데이터를 가져오는 과정)&#39;과
&#39;인덱싱(Indexing, 크롤링을 통해 얻은 정보를 검색 색인에 저장하는 과정)&#39;을 통해
정보를 카테고리화 한다.</p>
<h2 id="단점">단점</h2>
<h3 id="spa의-단점">SPA의 단점</h3>
<p>(1) 초기 구동 속도가 느리다.
    초기에 웹 애플리케이션에 필요한 모든 정적 리소스를 한번에 다 받기 때문!
(2) SEO(Search Engine Optimization, 검색 엔진 최적화) 관점에 불리하다.*
    근데 구글링하다보니 SPA에서도 단점(SEO 등)을 극복하기 위해 CSR이 아닌 SSR방식을 적용하는 케이스가 있었다. </p>
<h3 id="mpa의-단점">MPA의 단점</h3>
<p>(1) 새로운 페이지를 이동하면 화면이 깜빡인다.
    새로운 페이지를 요청할 때마다 전체 페이지를 다시 렌더링 하기 때문이다.
(2) 프론트엔드와 백엔드가 밀접하게 연관되어있다. (Tightly coupled!)
    프론트엔드와 백엔드가 서로 연관이 높아 개발이 복잡해질 수 있다.</p>
<h2 id="결론">결론</h2>
<p>SPA, MPA 둘 중에 어느 것을 사용해야 하는지는 확실히 정해진 바는 없다.</p>
<p>현재 개발하고 있는 프로그램이 베타 버전인지, 계획중인 비지니스가 어떤 고객을 타겟팅하고 있는지,SEO 관점이 중요한지 등, 현재의 상황이 어떤건지 파악하고 SPA, MPA 각자의 장단점을 고려하여 정하면 된다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99일 후, 1주일 재정비 시간.]]></title>
            <link>https://velog.io/@bright_root/99%EC%9D%BC-%ED%9B%84-%EC%9E%AC%EC%A0%95%EB%B9%84%EC%9D%98-%EC%8B%9C%EA%B0%84%EB%93%A4</link>
            <guid>https://velog.io/@bright_root/99%EC%9D%BC-%ED%9B%84-%EC%9E%AC%EC%A0%95%EB%B9%84%EC%9D%98-%EC%8B%9C%EA%B0%84%EB%93%A4</guid>
            <pubDate>Sun, 12 Jun 2022 02:16:16 GMT</pubDate>
            <description><![CDATA[<h2 id="개발자-세계-입문-후-재정비">개발자 세계 입문 후, 재정비.</h2>
<p>내가 항상 듣는 사람들에게 듣는 말이 있다.</p>
<p>&quot;너가? 와? 신기해. 어떻게했어? 진짜?&quot;</p>
<p>생긴건 그냥 어느 포유류와 다 닮았다. 생각은 많다. 추진력이 있다. 열심히한다 -&gt; 이건 내가 나를 돌아봤을 때 느끼는 것들이다. </p>
<p>어렸을때 부터 항상 세계를 쏘다녔고, 남들보다 다양한 경험들이 있다. 미국, 영국, 독일에서 공부랑 일이랑 연구도 해보고, 아프리카가서 연구도 해보고. </p>
<p>부모님은 말한다. &quot;그냥 좀 하던거 조용히 하면 평범하게 잘 사는데 왜 굳이 그러느냐?&quot;</p>
<p>&quot;응...뭔가 부족해.. 성취감이없어.&quot;</p>
<p>나는 돈을 많이 벌기보다는 무엇인가, 내 눈앞에 발전된 모습, 기여하는 모습, 도움이 되는 모습을 내 인생에서 추구한다. 돈은 그 후에 따라온다고 생각한다. 저것들이 먼저 나에게 보여질 경우, 나는 진정한 성취감을 갖는다. 코로나 시대를 맞아서, 나는 과감히 커리어 전환에 나섰다. 그래서 내린 결론은, 개발자를 하자. </p>
<p>학부때부터, 친구와 노트북 붙잡고 침대든 바닥이든 공원이든 집앞이든 물어보고 코딩하고 생각하고 스트레스받고 울고 화나고 웃고 행복해하고. 이상하게, 묘한 성취감을 느끼는 것은 코딩. 그래서, 하던일 관두자마자, 부트캠프에 신청하고 99일동안 버티고 수료하고 오랜만에 1주일동안 생각정리도하고, 부족한거 점검도하고 그러고있다.</p>
<p>사실, 이 블로그는 부트캠프 매니저가 쓰라고 권유+협박+제안+충고+ 등등 의 이유로 시작했다. 그런데, 아니 생각을 해보자. 내가 이 블로그 꼭 남들한테 보여주려고 하는건 아니잖아? 나는 어렸을 때 일기를 매일매일 꾸준히 써서 상도타고 대회도 나가고 칭찬도 많이 받아봤다. 그때는 어려서인지 하루하루가 즐거워 일기를 쓸수밖에 없다. 하지만 커가면서 점점 그런 시간이 없어진다. 왜냐하면 인생의 고독과 험난함을 알아버려서...ㅋㅋㅋㅋㅋ 귀찮아지고, 할것도 많은데 일기 쓰려느 힘들어서... 그런데 1주일동안 공부한것들도 많고, 머릿속도 정리도 안되고, 제일 중요한 건, 혼자 방에서 개발자로 커리어전환을 준비하니까 나와 대화할 것이 필요하다. 요즘 AI로 뭐 많기도하고, 사람들과 의사소통하는 SNS도 많고 하지만, 뭔가 나를 위한 공간?이 필요해서 자연스럽게 스스로 찾게되었다. 마치 안네의 일기느낌이랄까. 아무튼.</p>
<p>재정비의 시간을 갖으면서, 부트캠프에서의 99일동안 스쳐 지나갔던 모든것들이 생각난다. 이상하게 기억력은 또 좋아가지고, 내가 코딩하면서, 시간이 부족해서 일단 쓰고 나중에 이해하자 라고 생각했던 부분들이 보이고, 반드시 알아야할 기초개념들도 숭숭 뚫려있는 것도 보이고. 그래서, 면접도 면접인데, 아니 상식적으로 개발자면 좀 알고 써야지 모르고 쓰면 좀 그렇다. 예를들어 종교를 가진 사람이 있다하자. 자신이 믿는 신이 누구인지에대해 제대로 모르면서 믿기만한다면, 신앙이 그래도 생길수도있지만, 더 깊게 믿으려면 뭔지는 알아야한다.</p>
<p>이런 느낌 갖고, 이 블로그. 아니 이 일기장에, 내가 이해한것, 깨달은것 한번 필요할때마다 적으려고 한다. 일요일 아침부터 참 일어나자마자, 뭔가 갑자기 쓰고싶어서 썼다.
그리고, 바빠서 벨로그에 대해 뭔지도 모르고 초반에 그냥 생각없이 알고리즘 문제 보고 이해한것 모르는것 써놓고, 프로젝트 쓴거 해놓고, 이런식으로 했었다. 시간이 있는김에 이것저것 만져보니 대충 기능들에 대해 알게되었다. 역시 뭐든지 모르면 이것저것 눌러보면서 시행착오 가져야한다. 아무튼 그렇다. </p>
<p>요약: 연구할때도 뭔지 알고 연구해야, 연구진행속도가 나고, 퀄리티가 좋아진다. 사실 모르고 연구도 가능하다. 하지만, 개념이 없으면 개념없는 결론만 날뿐. 개발도 마찬가지. 알고써야 개발의 퀄리티가 좋아지지. 그리고, 알아야 최신기술들을 받아들이기가 가능하고 훨씬 수월하다. 그러니까, 일기장에 정리하면서 잘 해봅시다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트로 처음으로 협업해본 실전 프로젝트.]]></title>
            <link>https://velog.io/@bright_root/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-%EC%B2%AB-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@bright_root/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-%EC%B2%AB-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Mon, 06 Jun 2022 05:43:28 GMT</pubDate>
            <description><![CDATA[<h2 id="🐝-쉼없이-달린-그동안의-나의-생활들">🐝 쉼없이 달린 그동안의 나의 생활들.</h2>
<h3 id="🐛전과-후의-차이">🐛전과 후의 차이.</h3>
<p>연구하는 사람에서 개발하는 사람으로. 
다른점이 무엇일까? 힘든점이 무엇일까? 내가 개발자 커리어로 전환하려는 이유는: (1) 학부때 개발(?) 비슷하게 자바를 사용해서 팀을이루어 수업시간에 프로젝트를 했던 경험이 정말 기억에 남았다. (2) 내가 알고있는 지식을 빠르게 적용 가능하다. 연구할때는 그게 부족했다. 분야 자체가 오랜 기다림을 필요로하고, 연구 이외의 다른 것들도 신경쓸게 많기때문이다. 알고리즘 공부주간 이후 주특기 PBL과 실전프로젝트 기간, 내가 느낀 것은 하나. 모든 분야는 다 똑같다. 어떤 직업을 갖든간에 인내와 기다림은 필수이며, 늘 겸손한 마음가짐으로 팀원들과 결과물을 만들어내야한다. 여기서 내가했던 연구와 앞으로 내가 할 개발의 차이. 개발은 결과와 성취감이 훨씬 빠르게 나오며, 사람들에게 빠르게 도움을 줄 수 있다. 하지만, 그정도 레벨에 오르기위해서, 많은 배움과 연습이 당연히 필요하다는것. 처음부터 끝까지 항상느꼈다.</p>
<h3 id="🐌한달-반동안">🐌한달 반동안.</h3>
<p>알고리즘주간 2022-03-01 -&gt; 2022-04-07
주특기PBL주간 2022-04-08 -&gt; 2022-04-28
실전프로젝트주간 2022-04-29 -&gt; 2022-06-03</p>
<p>많은 일들이 일어나고, 나의 실력에 당연히 변화가 있었다. 사람은 극한 상황에 처하면 어떻게든 살아남기위해 온갖 수단과 방법을 가리지 않는다. 사실, 주특기와 실전프로젝트 기간 내내 긴장되고 너무바빴다. 배우고 알아야할것들이 정말 많았다. </p>
<p>&lt;주특기PBL주간&gt; 
알고리즘 공부하면서 얼른 주특기 공부를 하고싶다는 생각에 하루하루 버티었다. 나는 프론트엔드 개발자가 나에게 적성에 맞다는 생각이 들었기 때문에 선택했다. 그런데 3주안으로 리액트와 함께 파이어베이스와 비동기통신을 동시에 다 다루면서 해보니까...장난아니였다. 장난아니였다. 바로바로 모르는 것이 있으면 구글링하고, 로직도 생각해야했고, 강의도 보고, 팀원에게 물어보고, 매니저에게 물어보고. 어떻게든 하나라도 만들어 보고 싶다는 생각에, 해냈다고 생각한다. 비록 내가 만든 것은 이상한 형태(?)의 웹이였지만...그래도 나는 스스로에게 만족한다. 어떻게 만드는지, 어떤원리인지 파악하기에 충분했다. 오히려 자신감이 생기는 기간이기도 했다. 태어나서 처음으로 사용해본 언어 + 라이브러리 + 데이터베이스 + 통신 임에도 불구하고 따라갔다는 내 자신이 자랑스러웠기 때문이다. 하지만, 나는 전에 경험을 살려서 이러한 상태에 대한 내 자신에 대해 진단했다. &quot;아직 아는게 없으니까 대단해보이는거야. 정신차려.&quot;</p>
<p>&lt;실전프로젝트&gt;
실전프로젝트주간 2022-04-29 -&gt; 2022-06-03
-팀 구성
프론트 개발자: 나, 슈퍼팀원 (현직자), 하루슈퍼팀원 (이직준비자)
백엔드 개발자: 팀원1, 팀원2, 팀원3
디자이너: 디자이너1, 디자이너2</p>
<p>우리팀의 구성은 이렇게 되었고, 험난한 여정이 시작되었다.
우선 거의 4주만, 아니 3주만에 결과물을 만들어 내어야만했다. 그리고 프론트 2명.... 그것도 첫 프로젝트에... 이번 항해 기수에서는 프론트엔드 개발자가 압도적으로 적었기 때문에 8개의 팀중 3개의 팀은 한명의 현직자와 함께 두명이 프론트를 이루어 진행하였다. 시간과의 싸움이었다. 절대적으로 시간이 부족했다. 특히, 나는 현직자와 함께 하기때문에, 현직자는 오로지 퇴근한 늦은 밤에만 시간이 가능했다. 특히 기획단계와 초반 디자인 단계에서는 속도를 낼수가 없었다. 우리팀은 문제가 정말 많은 팀으로 유명했다. 나는 컴퓨터 화면이 고장나기도 했으며, 백엔드에서도 마찬가지로 있었고, 심지어 중간에 팀원3이 하차를 하기도했다. 나머지 조들이 중간점검때 얼추 다 만든 결과물을 갖고 기술적 멘토링을 받을때 우리는 그런것 하나 없었다. 아무것도 내놓지 못했다. 절망이였다. 하지만, 어떻게든 극복했다.</p>
<p>🐜난관.
짧은 시간인 1주일 안에 기획 + 디자인구상을 함께 해야했다. 디자이너들도 대학생 또는 이제 막 취업한 사람이기때문에 시간이 부족했다. 항해자들인 우리 개발자들은 낮에 기술적으로 필요한 부분들에 대해 이야기하고, 밤에 본격적으로 팀전체가 회의하였다. 처음에는 색깔을가지고 취향을 고려한 인스타그램같은 것을 만들 기획을 진행하여 제출했다. 리더로써 각기 다른 팀원들의 의견을 취합하기란 굉장히 어려웠다. 디자이너는 디자이너의 눈으로, 개발자들은 각자 개발의 눈으로. 거기다가 현직자는 가능 불가능의 문제애 대해 말하고. 이것을 합의하고 맞추는 것이 난관이었다. 결국에 처음에 제출한 기획을 갈아엎기에 이르렀다. 저것은 색깔 취향을 고려하는 특정한 매니아층(?) 사람들에게만 선호될뿐 좋은 아이디어가 아니라는 생각이 들었기 때문이다. 그래서 우리는 사회적거리두기에서 일상으로 돌아가는 요즘, 밖에서 그룹 스터디를 원하는 사람들을 타겟으로, 사람들이 회원가입을 하고, 위치를 등록하면, 위치간의 중간거리를 계산하여 스터디 카페를 추천해주는 서비스를 만들기로 결정이 났다. 이 기획은 거의 개발 2주 반정도 남은 상태에서 결정났다. 디자이너들은 디자인을 하느라 바빴고, 개발자인 우리는 바뀐 기획에 맞춰서 다시 개발을 수정하고 바꾸고...나의 문제는 우리 슈퍼팀원이 일이 바빴기때문에, 혼자 있는 시간이 초반에 길었다. 그래서 다른조에 비해 많이 뒤쳐졌지만, 혼자 꾸역꾸역 낮에 열심히 천천히 코드를 짜보고, 밤에 슈퍼팀원에서 피드백을 받고 코드리뷰를 받으면서 우리의 페이스대로 갔다. 태어나서 처음 만지는 리액트인데, 어떻게 카카오 서버에서 데이터를 가져와야하고, 리덕스 툴킷을 어떻게 사용하여야 하는지, 툴킷쿼리는 뭔지...? 타입스크립트는 또 무슨 언어인지...이 모든것을 고려해서 2주반동안 오로지 완성에만 초점을 두었다. 지금 글쓰면서 생각을 해보는데...참..어이가없다. 이걸 해낸 내가 참 신기하다. 백엔드는 프론트가 고군분투하는동안, 나름대로 구조적으로 프론트와 통신을 할 준비를 철저히 하고, 보안에 대해서 신경을 썼으며, 테스트 코드를 작성하고 있었다. 특히 고마운점은, 우리가 필요로 할때 항상 괜찮다면서 통신이 되는지 안되는지 도와주었다. 
마지막까지 디자이너들은 디자인의 방향에 대해 우리에게 물어봐주면서 수정하고 추가하고 삭제하고를 반복하였다. 나는 우리 슈퍼팀원과 거의 1주일은 3~4시에 자고 일어나고, 주말에는 쉬지도 않고 달렸다. 그리고 중간에 우리가 너무 힘든게 보였는지, 하루 슈퍼팀원이 들어와서 우리에게 힘을 주고 나갔다. 주로 CSS적인 컴포넌트를 많이 만져주시고 나갔다. 하루인데 단비같은 존재였다. 너무 감사하다. 그분 만들어놓은 컴포넌트를 남은기간 효율적으로 잘 썼다. 비록 중간에 백엔드 팀원이 한명 하차하긴했지만, 흔들리지 않았다. 흔들리지 않았다기보다는, 흔들릴 시간이 없었다 ㅋㅋㅋㅋㅋㅋ 그냥 누가 나가든 뭘 하든 그냥 일단 우리 모두에게 첫 프로젝트이기에 미친듯이 완성에만 집중했다. 나는 늘 팀원에게 말했다. &quot;그냥 하면돼. 어떻게 되겠지. 일단 하자 할수있다 다왔다!&quot; 이말 하고나서 에러창 보이면 열받긴 했다.</p>
<p>🐞완성했지만, 아직은 고칠게많아.
한달반동안 나는 잠을 4시간 이상 자본적도 없고, 제때에 밥을 가족과 먹어본 시간도 없다. 엄마얼굴, 아빠얼굴을 본 시간은 우리 팀원들 얼굴 본 시간보다 적었으며, 검은색 바탕의 코드창은 내가 하늘을 본시간보다 많았다. 기획의 방향성, 그냥 지나칠수없는 디자인의 중요성, 프론트 엔드 개발자의 시각에서 바라본 타임라인과 기술의 사용성. 이 글에서는 오로지 내가 느끼고 극복하고 그동안 어떤일이 나에게 일어났는지에대해 자세하게 기록해 놓았다. 왜냐하면, 개발자가 되는 길 위에 일어났던 엄청난 일을 적어놓고 싶었기 때문이다 ㅋㅋㅋ 3주만에 웹하나완성 ㅋㅋㅋㅋ
사실 완성도를 보자면 70점을 주고싶다. 나머지 30점은 치명적이다. 코드 리팩토링도 부족하고, 기능이 불완전하다. 렌더링이 늦다거나, 리덕스의 동작이 불완전 하다거나, 디자인을 수정/추가를 안했다거나.. 다른 조에비해 우리는 굉장히 늦게 제출했다. 꼴등으로 아마 제출했을걸(?) 기간에 상관없이 완성도를 높여서 제출하고 싶었으나, 우리팀은 그것도 중요하지만, 스케줄대로 진행해보면서 어떻게 개발자가 기한을 미친듯이 맞추고, 코드를 다시 보완하는 작업을 하는지 느끼고 싶다에 합의를 했기때문에, 일단 달렸다. 앞으로 다가올 시간들은 우리가 주변 지인들에게 서비스를 제공해보고 부족한점 피드백 받고 고치고, 기술적으로 문제있는 것들을 모두 보완할 예정이다. 이 과정이 없다면 무의미 할 것 같다. </p>
<p>다 써놓고 나니까 다를게 없다. 힘든척하는 내 개발자 친구. 그래 너 힘든거 알겠는데, 내가 했던 연구나 너가 하고있는 개발이나 다를게없단다. 그냥 본인이 하는게 제일 힘든거야. 그리고 인내는 무엇을 하든 필수라는 것을 다시한번 느꼈고, 제일 좋았던 점은: 개발도 어차피 사람이 하는 일이다. 무슨 거대한 그런 것이 없다. 모르는 것에대한 불안감과 걱정으로 코딩을 하기보다 대범하게 문제해결에 중점적으로 신경쓰면서 코딩을 하면 된다. 이런 말을 할 수 있다는 것은, 그래도 내가 어느정도 익숙해 졌다는 것이다. </p>
<p>우리 팀원들 다 고맙고, 우리가 해냈지만, 보완해야할점 당연히 있다는 것 알아줘다들!!</p>
<p>다른 포스트에 쓰긴 할거지만, 호오옥시나 궁금할까봐:</p>
<blockquote>
<p><a href="https://chip-monarch-04f.notion.site/CAPIN-4434d09828c645cfba03a3acacde3bcf">https://chip-monarch-04f.notion.site/CAPIN-4434d09828c645cfba03a3acacde3bcf</a></p>
</blockquote>
<p>그리고 그동안 못했던 노션정리좀하고....깃허브도 좀 정리하고....너무 급속도로 완성하느라...참 보여줄게 안되서 그나마 저거일단 자랑할만하다...딴건 보지말고..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코딩: 말하기 듣기 쓰기-9]]></title>
            <link>https://velog.io/@bright_root/%EC%BD%94%EB%94%A9-%EB%A7%90%ED%95%98%EA%B8%B0-%EB%93%A3%EA%B8%B0-%EC%93%B0%EA%B8%B0-8</link>
            <guid>https://velog.io/@bright_root/%EC%BD%94%EB%94%A9-%EB%A7%90%ED%95%98%EA%B8%B0-%EB%93%A3%EA%B8%B0-%EC%93%B0%EA%B8%B0-8</guid>
            <pubDate>Thu, 07 Apr 2022 05:03:56 GMT</pubDate>
            <description><![CDATA[<h2 id="다이나믹-프로그래밍">다이나믹 프로그래밍</h2>
<p>살다살다 개발자가 되기로 마음먹고 알고리즘을 배우기 시작해서 여기까지 이르렀다. 마짐가 단원인 다이나믹 프로그래밍. 이건 책에서나 그리고 블로그에서도 많은 정의가 나오기에 정확한 정의보다는 내가 이해한 것을 바탕으로 쉽게 말하겠다. 그냥, 최단 거리를 계산하는데, 중복적으로 그 전에 한번 건든 것은 건들지 않기위해서 머리를 쓴것이다 (메모이제이션: 한번 구한 결과를 메모리 공간에 메모해두고 같은 식을 다시 호출하면 메모한 결과를 그대로 가져오는 기법 by 동빈). 이것은 주로 점화식을 기반으로 푸는 것 같다. 왜냐하면, 보통 문제들을 보니까, 스테이지별로 나누기가 가능하다. 스테이지별로 한단계, 한단계 진행되는데, 단계별로 관계를 식으로 잘 정리해서 점화식을 디테일하게 코딩하는 것이 관건이다. 여기서 두가지 방식이 있는데, Top-Down 과 Bottom-Up 이 있는데, 전자는 재귀방식으로 푸는 것이고, 후자는 반복문 방법이다. DP 테이블을 자주 사용하는데, 이것은 그냥 쉽게말해서 문제를 보고 리스트나 행렬이 만들어지는데, 그것을 0이나 무한숫자로 채워서 만든 테이블이다. 이것안에 있는 수를 주로 바꾸거나 한다. 이런식으로한다. </p>
<h3 id="정수삼각형">정수삼각형</h3>
<p>이 문제는...일단 쉬워보인다. DP말고 그냥 for문 두개로 돌려서 풀면 끝나긴한다. 하지만, DP를 연습핳기위해서, 최대한 DP적으로 생각을 해보았다. 하지만, 실패. for문 두개를 이용해서 푸는 것은 동일했으나, DP적으로 생각하는 것은 아직 불가능했다. </p>
<blockquote>
<p>정수삼각형 프로그래머스 문제.
<a href="https://programmers.co.kr/learn/courses/30/lessons/43105">https://programmers.co.kr/learn/courses/30/lessons/43105</a></p>
</blockquote>
<pre><code>import sys

input = sys.stdin.readline
n = int(input())
dp = []
&#39;&#39;&#39;
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
&#39;&#39;&#39;

for _ in range(n):
    dp.append(list(map(int, input().split())))

for i in range(1, n):
    for j in range(i + 1):
        if j == 0:
            up_left = 0
        else:
            up_left = dp[i - 1][j - 1]
        if j == i:
            up = 0
        else:
            up = dp[i - 1][j]
        dp[i][j] = dp[i][j] + max(up_left, up)
print(max(dp[n - 1]))</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/cloudflare/bright_root/ad7eb7b6-956e-4be2-8547-cea73595891d/image.png" alt=""> by 데이터분석가 후이</p>
</blockquote>
<p>이분의 문제해설이 이해하기 쉬워서 가져왔다. 위에 코드에 대한 설명이 너무 좋다. 아무튼 두가지 경우로 나누어야한다.</p>
<p>파란색: 바깥으로 왼쪽끝/오른쪽끝 둘중 하나 라인타서 더해주는 경우
분홍색: 중심에서 왼쪽/오른쪽 숫자중 큰것 더해주는 경우</p>
<blockquote>
<p>위에 코드를 바탕으로 이중 for문을 돌릴경우 이렇게 된다:
[[7], [10, 15], [8, 1, 0], [2, 7, 4, 4], [4, 5, 2, 6, 5]]
[[7], [10, 15], [18, 16, 15], [2, 7, 4, 4], [4, 5, 2, 6, 5]]
[[7], [10, 15], [18, 16, 15], [20, 25, 20, 19], [4, 5, 2, 6, 5]]
[[7], [10, 15], [18, 16, 15], [20, 25, 20, 19], [24, 30, 27, 26, 24]]</p>
</blockquote>
<p>여기서 잘보면, 누적된 값을 확인할 수 있는데, 이중에서 제일 큰 누적값을 선택하면 된다. max()를 이용해서 확인 가능하다. 여기서!! 30!!! 그래서 30이 답이다. </p>
<p>DP...점화식을 만드는게 관건. 그말인 즉슨, 어떻게 답으로 출력되는가를 입력값부터의 흐름을 파악하는게 제일 중요한게 아닌가...이걸 느끼게 된 계기가 되었다.</p>
<h3 id="입국심사">입국심사</h3>
<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/43238">https://programmers.co.kr/learn/courses/30/lessons/43238</a></p>
</blockquote>
<p>이 문제는 우리팀에서 이진탐색을 공부할때, 찾아서 풀었던 문제이기도하다. 문제로 남아서, 다시 보았던 문제를 꼴도보기싫고 머리가 다시 아프기싫어서 넘기려고했으나. 진정한 개발자가 되기위해서는 당연히 풀어야지. 인생 쉽지않아. 아무튼 다시 풀어보았다. 신기한게, 분명 보았던건데, 까먹었다. 이래서 복습 많이하는게 중요한갑다. 아무튼 이진탐색으로 풀어야하는 문제였다. 이진탐색은 이분탐색이라고도하고 어디서는 이진검색이라고도하고 뭔가 말이 많다. 아무튼 중요한 것은 이것을 어떻게 접근할 것인지에 대한 것인데... 무조건 큰수와 작은수를 알아내어야 한다. 그래야 범위가 어느정도이고, 이 범위에서 최댓값과 최솟값을 알아야 중간값을 알아내서 이진검색을 실시할수있다. 이런문제는 제일먼저 보자마자 최댓값을 생각하는 연습을 해야한다는 것을 알았다. 이것은 팀원들과 이야기를 해보았는데, 내가 범위를 설정한것은 단순히 제일 심사가 오래 걸릴경우, 즉 최댓값과 그냥 문제에 있는 예시문제의 최솟값을 맞추어서 했다. 하지만 우리 팀원중 한명은 코딩을 하기전에 최대한 범위를 답 근처에 있도록 모든 수를 고려해서 설정을 했다. 그래서 왜 그렇게까지 했냐고하니까 그래야 시간복잡도를 줄일수있다는 뭐 어쩌구저쩌구를 하긴했는데. 뭐 이러나저러나 뭐 맞기만하면되긴하지만, 나쁘지 않은 것 같다. 중간값은 중간값동안 심사한 사람의 수. 그리고 만약에 심사한 사람의 수가 심사받아야할 사람의 수보다 같거나 많을 경우에 주어진 시간을 줄이고 (right = mid - 1), 심사받아야 하는 사람의 수보다 작을 경우에는 시간이 부족한것이니까 주어진 시간을 늘려준다 (left = mid + 1) 이런식으로.</p>
<pre><code>def solution(n, times):
    answer = 0
    # right는 가장 비효율적으로 심사했을 때 걸리는 시간
    # 가장 긴 심사시간이 소요되는 심사관에게 n 명 모두 심사받는 경우이다.
    left = min(times)
    right = max(times) * n
    while left &lt;= right:
        mid = (left + right) // 2
        checked = 0
        for time in times:
            # people 은 모든 심사관들이 mid분 동안 심사한 사람의 수
            checked += mid // time
            # 모든 심사관을 거치지 않아도 mid분 동안 n명 이상의 심사를 할 수 있다면 반복문을 나간다.
            if checked &gt;= n:
                break

        # 심사한 사람의 수가 심사 받아야할 사람의 수(n)보다 많거나 같은 경우
        if checked &gt;= n:
            answer = mid
            right = mid - 1
        # 심사한 사람의 수가 심사 받아야할 사람의 수(n)보다 적은 경우
        elif checked &lt; n:
            left = mid + 1

    return answer</code></pre><p>left 와 right를 좁혀가면서 답을 점점 숨죽여서 찾아가는것. 참 재밌는 것같다. 점점 숨통을 조여서 확 답을 낚아채는것. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코딩: 말하기 듣기 쓰기-8]]></title>
            <link>https://velog.io/@bright_root/%EC%BD%94%EB%94%A9-%EB%A7%90%ED%95%98%EA%B8%B0-%EB%93%A3%EA%B8%B0-%EC%93%B0%EA%B8%B0-7-hdpnecw3</link>
            <guid>https://velog.io/@bright_root/%EC%BD%94%EB%94%A9-%EB%A7%90%ED%95%98%EA%B8%B0-%EB%93%A3%EA%B8%B0-%EC%93%B0%EA%B8%B0-7-hdpnecw3</guid>
            <pubDate>Tue, 05 Apr 2022 08:40:25 GMT</pubDate>
            <description><![CDATA[<p>이 문제드을 풀기에 앞서, 나는 중요한 주제를 배웠다. 바로 최단경로에 대한 문제였다. 최단경로를 풀기위해서는 노드, 엣지, 그리고 거리를 이용하여 어떻게 목표하는 경로를 최단으로 갈 수 있을까를 고민하여야한다. 그러기 위해서 여러가지 알고리즘이 있지만, 다익스트라 와 플로이드-워셜 알고리즘에 대해 배웠다.
다익스트라: 그래프에서 여러 개의 노드가 있을 때, 특정한 노드에서 출발하여 다른 노드로 가는 각각의 최단 경로를 구해주는 알고리즘.
플로이드-워셜: 모든 지점에서 다른 모든 지점까지의 최단 경로를 모두 구해야 하는 경우
이 두문제는 각각 이 방식으로 풀었다. </p>
<h2 id="화성탐사">화성탐사</h2>
<blockquote>
<p>By 이것이 코딩테스트다, 나동빈, 39번문제, 388쪽.
화성 탐사 기계가 존재하는 공간은 N x N 2차원 공간이며 각각의 칸을 지나기 위한 비용이 존재한다. 가장 왼쪽 칸에서 가장 오른쪽 아래 칸인 위치로 이동하는 최소 비용을 출력하는 프로그램을 작성하세요. 화성 탐사 기계는 특정한 위치에서 상하좌우 인접한 곳으로 1칸씩 이동할 수 있습니다. </p>
</blockquote>
<p>문제보자마자 드는 생각은...최단경로를 찾아줘야 하는 것을 깨달았다. 그리고 2번째로, 2차원 배열을 써야한다는 생각 입력. 지나기 위한 비용은 거리라는것을 깨달아버렸고. 이건 무조건 다익스트라를 써야한다. 맞나요? 우선 이렇게 생각하고 접근했다. 그리고, 상하좌우로 왔다갔다 할 수 있다는 것을 생각해보면, 네비게이션모드를 사용해야한다. 상하좌우 한칸씩 검사하는 것을 나는 이렇게 부른다. 아무튼 이렇게 접근을 하고 풀었다. 다익스트라 구현포맷 소환해서 풀었다. </p>
<pre><code>&#39;&#39;&#39;
input:
3
3
5 5 4
3 9 1
3 2 7
5
3 7 2 0 1
2 8 0 9 1
1 2 1 8 1
9 8 9 2 0
3 6 5 1 5
7
9 0 5 1 1 5 3
4 1 2 1 6 5 3
0 7 6 1 6 8 5
1 1 7 8 3 2 3
9 4 0 7 6 4 1
5 8 3 2 4 8 3
7 4 8 4 8 3 4
output: 20 19 36
&#39;&#39;&#39;

import heapq
import sys
input = sys.stdin.readline

INF = int(1e9)

dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]


for T in range(int(input())):
    N = int(input())
    graph = []
    for i in range(N):
        graph.append(list(map(int, input().split())))
    distance = [[INF] * N for _ in range(N)]

    x, y = 0, 0
    q = [(graph[x][y], x, y)]
    distance[x][y] = graph[x][y]


    while q:
        dist, x, y = heapq.heappop(q)
        if distance[x][y] &lt; dist:
            continue
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if nx &lt; 0 or nx &gt;= N or ny &lt; 0 or ny &gt;= N:
                continue
            cost = dist + graph[nx][ny]
            if cost &lt; distance[nx][ny]:
                distance[nx][ny] = cost
                heapq.heappush(q, (cost, nx, ny))
    print(distance[N-1][N-1])</code></pre><p>힙을 쓰는 이유는 최저거리를 위해서이다. 힙은 구조상 부모노드가 자식노드보다 작아야한다. 그렇기때문에, 최저인 것이 제일 앞으로 오고, pop을 하게된다면 제일먼저 나온다. 그렇기때문에 힙을 통해서 최단경로를 찾기 좋은 것이다. 그리고, 항상 기존에 있던 경로와 새로 가본 경로중, 값을 잘 비교해서 최단경로를 저장해주어야한다. </p>
<h2 id="운동">운동</h2>
<blockquote>
<p><a href="https://www.acmicpc.net/problem/1956">https://www.acmicpc.net/problem/1956</a>
백준 1956번, 운동 문제
V개의 마을와 E개의 도로로 구성되어 있는 도시가 있다. 도로는 마을과 마을 사이에 놓여 있으며, 일방 통행 도로이다. 마을에는 편의상 1번부터 V번까지 번호가 매겨져 있다고 하자.
당신은 도로를 따라 운동을 하기 위한 경로를 찾으려고 한다. 운동을 한 후에는 다시 시작점으로 돌아오는 것이 좋기 때문에, 우리는 사이클을 찾기를 원한다. 단, 당신은 운동을 매우 귀찮아하므로, 사이클을 이루는 도로의 길이의 합이 최소가 되도록 찾으려고 한다.
도로의 정보가 주어졌을 때, 도로의 길이의 합이 가장 작은 사이클을 찾는 프로그램을 작성하시오. 두 마을을 왕복하는 경우도 사이클에 포함됨에 주의한다.</p>
</blockquote>
<p>문제를 보자마자, 모든 지점에 대해서 각각 최단경로가 어떻게 되는지 계산해봐야한다. 즉, 플로이드-워셜 알고리즘을 사용하여야한다. 그리고, 사이클임을 주의하여야한다. 사이클이라는 것은 갔다가 다시 돌아온다는 뜻이다. 즉 각 노드간의 방향이 갔다가 오는 것을 찾고, 그것의 거리에 대한 합을 찾아야 한다는 것이다. 나는 이 문제를 풀때 사이클을 생략하고 풀어서 이상하게 풀게되었다. 플로이드-워셜 접근은 맞았으나...아쉬웠다. </p>
<pre><code>import sys

input = sys.stdin.readline

V, E = map(int, sys.stdin.readline().split())
INF = int(1e9)
graph = [[INF] * (V + 1) for _ in range(V + 1)]
# print(graph)
for _ in range(E):
    a, b, c = map(int, sys.stdin.readline().split())
    graph[a][b] = c
# print(graph)

for k in range(1, V + 1):
    for i in range(1, V + 1):
        for j in range(1, V + 1):
            graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j])

answer = INF
for i in range(1, V + 1):
    answer = min(answer, graph[i][i]) #사이클이니까 i로한다
if answer == INF:
    print(-1)
else:
    print(answer)</code></pre><p>3중 for문을 써야한다....시간복잡도가 무려...어마어마하다. 아무튼 그러고난후 마지막 answer부분을 처리하는것에서 미숙하여, 해결하지 못했다. 사이클이니까 갔다가 다시 오는 방향으로 코드를 짜려면 graph[i][i]로 설정해 주어야 하지만, 그것을 생각하지 못했다. </p>
]]></description>
        </item>
    </channel>
</rss>