<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev_ming.log</title>
        <link>https://velog.io/</link>
        <description>sin prisa pero sin pausa </description>
        <lastBuildDate>Mon, 02 May 2022 14:45:34 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev_ming.log</title>
            <url>https://images.velog.io/images/alicia-mkkim/profile/c0379deb-3a6c-4235-93cf-c48988ebccdc/스크린샷 2022-02-18 오후 1.50.18.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev_ming.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/alicia-mkkim" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[2차 프로젝트 회고록 ]]></title>
            <link>https://velog.io/@alicia-mkkim/2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@alicia-mkkim/2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Mon, 02 May 2022 14:45:34 GMT</pubDate>
            <description><![CDATA[<h1 id="1-team-ajeom">1. Team Ajeom</h1>
<blockquote>
<p>클론 사이트: Brunch
진행기간: 4월 18일 - 4월 30일
front-end : <a href="https://github.com/wecode-bootcamp-korea/justcode-4-2nd-ajeom-front">아점프론트깃허브</a>
back-end:  <a href="https://github.com/wecode-bootcamp-korea/justcode-4-2nd-ajeom-back">아점백깃허브</a>
시연영상: <a href="https://youtu.be/ydv4rAPWln4">아점시영영상</a></p>
</blockquote>
<ul>
<li><p>Front</p>
<ul>
<li>Header</li>
<li>Nav</li>
<li>Footer</li>
<li>메인</li>
<li>List (포스트글 목록)</li>
<li>Detail (포스트)</li>
<li>로그인/회원가입 (카카오 소셜 로그인)</li>
<li>글쓰기 에디터</li>
<li>북브런치 에디터</li>
<li>작가의 서랍</li>
<li>작가 신청</li>
<li>마이프로필/ 작가프로필</li>
</ul>
</li>
<li><p>Backend</p>
<ul>
<li>유저</li>
<li>리스트</li>
<li>북</li>
<li>포스트</li>
<li>키워드</li>
<li>write</li>
</ul>
</li>
</ul>
<h1 id="브런치를-선택하게-된-이유">브런치를 선택하게 된 이유?</h1>
<ul>
<li>깔끔한 UI</li>
<li>1차보다는 도전하자</li>
</ul>
<p>브런치를 선택하게 된 이유는 간단했다.  깔끔한 UI였다. 팀원들 각자 하고 싶은 사이트를 2개씩 골라와 결정하기로 했다. 내 마음은 원래 중고 판매사이트 Kream이였지만, 세련된 브런치 UI를 보고 마음을 바꿨다.</p>
<h1 id="내가-맡은-부분">내가 맡은 부분</h1>
<ul>
<li>로그인 (카카오 소셜로그인)</li>
<li>마이프로필/작가프로필</li>
</ul>
<h1 id="공유하고-싶은-코드-카카오--소셜로그인">공유하고 싶은 코드 (카카오  소셜로그인)</h1>
<p>내가 이 코드를 공유하고 싶은 이유는  그냥 처음해봐서여다. 엄청 잘 짠 코드도 아니다. 하지만 나름의 도전이었기에 공유하고 싶다. </p>
<h2 id="loginjs">login.js</h2>
<pre><code class="language-jsx">&lt;div className={styles.kakaologinBox}&gt;
    &lt;Button href={KAKAO_AUTH_URL} kakao&gt;
      &lt;img
        src={process.env.PUBLIC_URL + &#39;/image/kakaotalk.png&#39;}
        alt=&quot;&quot;
      /&gt;
      카카오로 계정 시작하기
    &lt;/Button&gt;
&lt;/div&gt;</code></pre>
<h2 id="authjs">Auth.js</h2>
<pre><code class="language-jsx">const code = new URL(window.location.href).searchParams.get(&#39;code&#39;);
  const bodyData = {
    grant_type: &#39;authorization_code&#39;,
    client_id: REST_API_KEY,
    redirect_uri: REDIRECT_URI,
    code: code,
    client_secret: CLIENT_SECRET,
  };

  const queryStringBody = Object.keys(bodyData)
    .map(k =&gt; encodeURIComponent(k) + &#39;=&#39; + encodeURI(bodyData[k]))
    .join(&#39;&amp;&#39;);

  useEffect(() =&gt; {
    fetch(&#39;https://kauth.kakao.com/oauth/token&#39;, {
      method: &#39;POST&#39;,
      headers: {
        &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded;charset=utf-8&#39;,
      },
      body: queryStringBody,
    })
      .then(res =&gt; res.json())
      .then(data =&gt; {
        Kakao.init(KAKAOINIT);
        sendData(data);
      });
  }, [Kakao, queryStringBody]);</code></pre>
<ol>
<li>인가코드 받기 </li>
</ol>
<p>카카오톡 소셜 로그인을 하기로 했다면, 인가코드를 가장 먼저 받아야한다.  사이트 내에서 카카오톡 로그인 후, 내 애플리케이션에서 Rest-api-key와 redirect_uri 키를 받아 볼 수 있다. 그 다음 카카오톡에게 인가코드를 달라고 요청을 해야한다. Auth.js의 제일 상단 const code가 바로 인가코드이다.  </p>
<ol start="2">
<li><p>카카오로부터 액세스 토큰 받기</p>
<p>카카오 개발자 문서에서 인가코드는 시작일뿐, 액세스 토큰을 받고 넘겨줘야 로그인을 할 수 있다는 글이 적혀있었다. 프론트, 카카오, 백엔드 사이에서 무엇이 오고가야하는지 이해가 제대로 되지 않은 상태에서 시작하다보니, 나는 무엇을 받고 넘겨줘야하는지 헷갈렸고, 긴 삽질의 시간을 가졌다. </p>
</li>
</ol>
<p>내가 이해한 바는 바로 아래와 같다. </p>
<blockquote>
</blockquote>
<p> “카카오야!  클라이언트가 우리사이트에서 카카오로 로그인 했거든! 니네 카카오에 해당 클라이언트 정보 있니? 인증해줘! 내가 너한테, Client_id, redirect_uri, code, client_secret를 post 형식으로 request 날릴게! </p>
<blockquote>
</blockquote>
<p>클라이언트 인증되면 너는 res로 access token 주렴!안되면 error로 날려!”</p>
<p>access-token을 받는 과정도 순탄치 않았다. 나는 계속해서, parameter를 json형태로 보내고 있었고, 카카오문서에서는 분명 type=string으로 보내라고 했는데, 그 부분을 제대로 인지하지 못했다... 왜 자꾸 invalid_client KOE010 에러만 보내주는거지? ...아...json  (이 부분을 캐치하고 함께 고쳐준 팀원분들께 ㅜㅜ넘나 감사해요) 다시 string 형태로 보내주자 카카오로부터 access token을 받을 수 있었다. 감격의 눈물!!!</p>
<ol start="3">
<li>카카오로부터 받은 access token을 backend 보내주기  </li>
</ol>
<pre><code class="language-jsx">const sendData = async data =&gt; {
    await fetch(&#39;http://localhost:8000/user/login&#39;, {
      method: &#39;post&#39;,
      headers: { &#39;Content-Type&#39;: &#39;application/json&#39; },
      body: JSON.stringify(data),
    })
      .then(res =&gt; res.json())
      .then(res =&gt; {
        if (!res.token) return;
        localStorage.setItem(&#39;token&#39;, res.token);
        navigate(&#39;/&#39;);
        window.scrollTo(0, 0);
      });
  };</code></pre>
<p>프론트에서 access token을 백에게 보내주면서 req를 날린다. (백엔드, access-token 줄테니까 아점 토큰만들어서 줘요!)
이후는 백엔드의 영역이다. 백엔드는 다시 한번 카카오에게 요청을 날린다.</p>
<blockquote>
</blockquote>
<pre><code>“카카오!  프론트한테 access-token 받았다. 이제 우리가 원하는 해당 클라이언트 정보 보내줘!!!” </code></pre><blockquote>
</blockquote>
<p>   백엔드는 카카오에서 받은 정보를 API로 만든다.  프론트가 요청한 Token을 res로 보내주면 끝!  </p>
<h1 id="아쉬웠던-점">아쉬웠던 점</h1>
<ul>
<li>숲을 보는 능력: 내가 맡은 부분은 프론트엔드이다. 그렇다고 하더라도 백엔드가 어떻게 돌아가는 지는 인지하고 있었어야 했는데,  그부분을 놓치고 간거 같았다. 예를 들어서 , 백엔드에 req를 날리고, 정확히 어떤 res를 받아야하는지 알려줬어야 했는데, 백엔드 분에게 그부분을 잘 이해시키지 못했다는 점이 조금 아쉬웠다.</li>
<li>체력적인 문제 : 사실 프로젝트 시작부터 몸이 좋지 않았다. 이전까지는 나름 운동을 꾸준히 하고 있었는데, 1,2차 프로젝트를 시작하면서 운동을 거의 하지 못했다.  2주동안의 짧은 프로젝트 때문에 그렇긴 했지만, 앞으로 회사 다니면 장기전으로 갈텐데 운동을 해야겠다는 생각이 들었고, 건강관리 필수. 눈관리 필수</li>
<li>styled-components과 modules.scss를 함께 쓴 나. 다음에는 하나만 써보는 걸로 해보겠습니다.</li>
</ul>
<h1 id="회고">회고</h1>
<ul>
<li>1차 프로젝트 때도 말한 바 있지만 나는 이번에도 좋은 팀원들을 만났다. 본받고 싶은 점을 간략하게 적어봐야겠다<ul>
<li>미친 성장속도 - 2차도 함께한 1차 프로젝트 팀원.  우리코드에만 한정하지 않고, 다른 프로젝트도 보면서 이것저것 시도해 보는 모습. 또 좋은 코드가 있으면 본인 코드에 활용하는 모습에 보기 좋았다. 또 엄청난 성장속도에 또 한번 놀랬다. 내 코드에 갖혀있지 말고, 좋은 코드 많이 보고 공부해야겠다.</li>
<li>코드 이해하는 능력 - 단기간 프로젝트가 같은 경우, 시간의 압박에......남의 코드가 잘 보이지 않는다. 한 팀원은 찬찬히 남의 코드를 보더니 빠르게 이해하고, 고쳐주는 센스</li>
<li>즐기는 자는 이기지 못한다 -  한 팀원이 자기 맡은 부분을 완벽히 하고 신나서 코딩 설명을 해주는데 그 때 느꼈다.....정말 미쳐서 즐기면서 하는 사람을 이길 수 없구나 말이다. 그 팀원처럼 코딩에 대한 즐거움을 놓치지 않고 가야겠다는 생각이 들었다.</li>
<li>문제점을 인지하고 해결하려는 자세 - 스탠드업 미팅 시간을 짧게 했어야 했다. 1차 프로젝트 같은 경우, 나는 어제,오늘 할일을 적고, 그 다음에 “어떤 부분이 풀리지 않는다” 라고 하면, 팀원들이 다 같이 도와줬다. 어쩌보다니 2차프로젝트도 그렇게 했는데,  데일리 스탠드업 미팅하는 시간이 길어져서, 효율적이지 못하게 됐다. 팀원 한분이 조심스럽게 이 부분에 대해서 이야기 했다. 문제에 대해서 회피하지 않고, 똑바로 문제점을 이야기하기. 그리고 지적하기 보단 어떻게 보완할 수 있는지 이야기해주는 모습이 좋았다.</li>
<li>생각정리 시간이 필요하다. 모르는 부분이 있으면, 필기하면서 이해하기. 필기 내용을 토대로 내 생각 정리하기 (로그인때 절실히 느낌). 사실 너무 많은 양의 블로그나, 문서를 읽다보면 생각이 제대로 정리 되지 않을때가 있다. 사실 읽는 것만으로 정보가 습득되지 않는다. 완벽한 이해를 위해 내 생각을 정리할 시간이 필요하다.</li>
</ul>
</li>
</ul>
<p>처음 해본 소셜 로그인은 사실 쉽지 않았다. 정했던 스케쥴보다 지체되었고, 고생도 많이 했다.그렇지만 해내서 너무나 뿌듯하다!  프로젝트하면서 내 스스로에게 아쉬웠던 점을 보완하고, 팀원들에게 본받았던 점을 잊지 않고 내 것으로 만들어야겠다. 기업협업에서 꼭 실천하자! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[1차 프로젝트 회고록 ]]></title>
            <link>https://velog.io/@alicia-mkkim/vd9abn5p</link>
            <guid>https://velog.io/@alicia-mkkim/vd9abn5p</guid>
            <pubDate>Wed, 13 Apr 2022 01:10:46 GMT</pubDate>
            <description><![CDATA[<h1 id="1-team-kukukkakka">1. Team KuKuKkaKka</h1>
<blockquote>
<p>프로젝트 클로 사이트 소개:  꽃 배달 정기구독 사이트 
프로젝트 목표: 파운데이션 기간에 내운 내용들을 적용하여 사이트 구축하기 
진행기간: 3월 28일 - 4월 8일 
frontend: <a href="https://github.com/wecode-bootcamp-korea/justcode-4-1st-kukukkakka-front">https://github.com/wecode-bootcamp-korea/justcode-4-1st-kukukkakka-front</a>
backend : <a href="https://github.com/wecode-bootcamp-korea/justcode-4-1st-kukukkakka-back">https://github.com/wecode-bootcamp-korea/justcode-4-1st-kukukkakka-back</a>
API DOCUMENTATION : <a href="https://documenter.getpostman.com/view/15514335/Uyr4Jegx">https://documenter.getpostman.com/view/15514335/Uyr4Jegx</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/alicia-mkkim/post/b368ed2a-22b1-4c2a-b6a3-e4b74cff080e/image.gif" alt=""></p>
<p>우리팀은 꽃 정기구독 사이트를 클론코딩하기로 했다. 이유는 파운데이션때 배웠던 내용을 최대한 활용하고 복습할 수 있다고 판단했기 때문이다. 원래 5명이었지만, 한 팀원의 개인 사정으로 프로젝트를 그만 두게 되었고 4명이 함께 프로젝트를 하기로 했다. 다른 팀에 비해 인원이 적고, 2주라는 짧은 프로젝트를 기간을 고려해, 많은 기능을 만들기보다는, 할 수 있는 양을 먼저 정했다. 대신, 만약 시간이 된다면, 욕심을 내서 하고 싶은 기능 부분을 더 만들기로 했다. </p>
<p>구현 기능과 역할 </p>
<ul>
<li>Front<ul>
<li>Header - 꾸꾸까까 메인로고와 메뉴</li>
<li>Footer</li>
<li>List - 꽃 리스트/ 검색기능 및 추천순 정렬하기</li>
<li>Detail - 꽃 상세페이지 (계산식 기능)</li>
<li>장바구니</li>
<li>로그인/회원가입</li>
</ul>
</li>
<li>Backend<ul>
<li>상품리스트</li>
<li>로그인/회원가입</li>
<li>장바구니</li>
</ul>
</li>
</ul>
<h1 id="2-기술-스택">2. 기술 스택</h1>
<h3 id="프론트엔드--react">프론트엔드 : React</h3>
<h3 id="백엔드--nodejs-express-mysql-jwt--bcrypt">백엔드 : Node.js, Express, MySQL, JWT &amp; Bcrypt</h3>
<h1 id="3-공유하고-싶은-코드">3. 공유하고 싶은 코드</h1>
<p><strong>문제: 프론트에서는 count도 잘되고, 합계도 제대로 되고 있는데, 왜 백엔드에 제대로 반영되지 않을까?</strong> </p>
<ul>
<li>productId과 key값이 backend API에서 보내주는 것과 다르게 사용되고 있었다 (백엔드보고 문제해결)</li>
<li>count가 왜 하나씩 늦게 db에 적용될까? 그러니 합계금액도 맞지 않았다.</li>
</ul>
<p>나는 팀원이 fetch에서 post 같은 경우, 함수 안에 적어줘어야 돌아간다는 말을 얼핏 들었다. 사실 팀원이 처한 상황과 내 상황이 달랐다. 나느 그 부분을 고려하지 않는 상태로 “function 안에 fetch를 해야겠군” 이라는 판단을 내렸고 그게 몇시간동의 고난이 펼쳐질지 몰랐다.  count가 +1 된후, 백엔드에 보내줘야하는데, 자꾸 count 되기 전에 올라가, async,await도 걸어보고, 함수 위치도 바꿔보고 정말 말그대로 ....이짓저짓 다해봤다.  결국 멘토님과 리액트신 동기 덕분에 해결 할 수 있었다. 바로 useEffect를 사용하는 거였다. </p>
<p>사실 useEffect를 사용하려고 handleChangeCount안에 useEffect를  넣어보았다. 그러자, 너는 리액트 훅이 아닌데 왜 사용하려고 하니 라는 에러가 떴고, 렌더링이 되지 않는 상황이 발생했다. useEffect를 사용해서 하니 안됐다고 하니, useEffect 안에 fetch를 해야한다고 친절히 알려줬다. 휴...8시간만에 찾은 해답이었다. </p>
<p>나의 결론은 useEffect 개념 확실히 하기! 모르는게 있으면 제대로 찾아보고 사용하기! </p>
<pre><code class="language-jsx">
CartList.js  (잘못 작성한 코드 )

const handleChangeCount = async() =&gt; {

      await setCount(prev =&gt; prev+1);
    fetch(&#39;http://localhost:8000/carts&#39;, {
      method: &#39;PATCH&#39;,
      headers: {
        &#39;Content-Type&#39;: &#39;application/json&#39;,
        token: token,
      },
      body: JSON.stringify({
        productId: productId,
        quantity: count,
        totalPrice: totalPrice,
      }),
    })
      .then(response =&gt; response.json())
      .then(result =&gt; result) </code></pre>
<pre><code class="language-jsx">
CartList.js 

useEffect(() =&gt; {
    fetch(&#39;http://localhost:8000/carts&#39;, {
      method: &#39;PATCH&#39;,
      headers: {
        &#39;Content-Type&#39;: &#39;application/json&#39;,
        token: token,
      },
      body: JSON.stringify({
        productId: productId,
        quantity: count,
        totalPrice: totalPrice,
      }),
    })
      .then(response =&gt; response.json())
      .then(result =&gt; result);
  }, [count]);</code></pre>
<h1 id="4consolelog를-생활화">4.console.log를 생활화</h1>
<ul>
<li>데이터를 붙여주면서 느낀점은 콘솔로그가 얼마나 중요한지 깨닫게 됐다. 우리 팀은 3일만에 list API를 만들고, 데이터를 붙여주기로 했다. fetch함수도 제대로 적었는데 계속 fetch할 수 없다는 에러만 뜨고 있었다. 백엔드도 제대로 다 잘 적은거 같은데 무엇이 문제였을까 라는 생각이 들었다. 팀원들과 각자 시간을 가지고 5시까지 문제를 해결하자고 했다.</li>
<li>리스트에서 mockData를 잘 불러왔다. list API도 postman에서 잘 돌아가고 있었다. 이건 fetch를 잘못 썼던지, 라우터에 문제가 있을 거 같다고 생각했다. 그래서 그냥 생각없이 index.js에서 콘솔로그에 cors를 적었다. [Function: middlewareWrapper]하면서 잘 작동하고 있었다. 그리고 app.use(cors)를 콘솔로그에 찍었다. 근데 undefined이 뜨는거다. 그래서 cors 사용법을 구글링했다.MDN에서 <code>app.use(cors())</code> 를 사용하라는 글을 읽고 고쳐주니, fetch가 잘 작동되서 get으로 받아올수 있었다.</li>
<li>그날 깨달은 건 console를 잘 찍어보자</li>
</ul>
<p><img src="https://velog.velcdn.com/images/alicia-mkkim/post/20adb3ee-63d1-479b-bd33-8e4001867a70/image.png" alt=""></p>
<h1 id="5-1cm-성장">5. 1CM 성장</h1>
<ul>
<li>참고한 꾸까페이지 같은 경우, 검색기능과 추천순(가격 높음-낮음)정렬순은 없다. 대부분의 유저라면 가격에 대해 민감하게 반응하지 않을까라는 생각이 들었다. 먼저 저렴한 가격대에서 괜찮은 꽃을 찾아보지 않을까 라는 생각이 들었다. 본인이 원하는 꽃들을 검색해서 찾아보지 않을까 라는 생각이 들었다. 나는 그부분을 보완하고자 찾기 기능과 정렬하는 기능을 만들었다. 디자인적 요소는 마켓컬리를 참고했다. 추천순 같은 경우, 추천순&gt;가격높은&gt;가격 낮은으로 펼쳐 놓았다. 하지만 나중의 UI를 생각해서 추천순 버튼을 누르면 팝업창이 나와 원하는 대로 정렬할 수 있도록 만들었다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/alicia-mkkim/post/89d68f7e-912d-4de8-913e-35bbed17970c/image.png" alt="">
<img src="https://velog.velcdn.com/images/alicia-mkkim/post/6248e742-d3cb-4eea-8ada-1c1e273257f4/image.png" alt=""></p>
<h1 id="6-아쉬웠던점발전하고-싶은-부분">6. 아쉬웠던점/발전하고 싶은 부분</h1>
<ul>
<li>아쉬웠던 점은 이번 프로젝트는 파운데이션에서 배웠던 내용을 복습하다는 점에 의의해서 기능 개발을 많이 하지 못했다. 물론 멘토님들은 다른 사람들과 비교하지 말라고 하셨지만, 사람인지라 다른 사람과 비교를 안할 수 없었다. 너무 배운것을 복습하는 거에만 몰두 했던게 아닐까 라는 생각 들었다. 실력향상보다는 내가 할 수 있는 거에만 안주했던 게 아닐까라는 아쉬움이 있었다.  그래서 2차 프로젝트에서는 기능도 조금 더 많이 만들어보고 싶다는 생각이 들었다.</li>
<li>또 한가지, 문제가 발생하면, 내가 어떤 문제가 발생한지 조금 더 정확히 알아야겠다는 생각이 들었고, 그 내용을 잘 정리해서 구글링을 하거나, 다른 팀원들에게 물어봐야겠다는 생각이 들었다. 나조차 문제가 정리가 되지 않는데, 정리 안된 내용을 듣는 사람은 얼마나 괴로울까! 듣는 사람도 내 문제를 캐치 할 수 없고, 이런 나도 내가 .... ㅜㅜ힘들다. 다음번에는 문제가 발생하면 생각을  먼저 정리하고,  설명할 수 있도록 노력해야겠다.</li>
<li>만드는게 급급하느라, 클린코딩은 생각할 엄두가 나지 않았다.가끔 문제가 발생하면 도대체 어디서 부터 고쳐야할지 대략난감할때가 있었다. 휴... 만드는것도 중요하지만 훗날 리팩토링이랑, 다른 사람들이 읽기 편한 코딩을 적자! </li>
</ul>
<h1 id="7-회고">7. 회고</h1>
<p>프로젝트 협업하면서 배운점이 많다. 먼저 기록하는 습관, 서로 공유하기 그리고 커뮤니케이션과 같은 점이다.  매일 데일리 스탠드업 미팅을 통해서 어떻게 프로젝트가 각자 진행되는지 공유했다. 노션 페이지에 꼭 본인이 할일과 어제 한일에 대해서 적었다. 사실 프로젝트가 정신없이 진행되다 보면, 내가 어제 무엇을 하고 있었는지 , 내가 앞으로 무엇을 해야하는지 종종 까먹는 경우가 많다. 그럴때마다 기록해둔 팀 노션 공유 페이지를 보면서 방향성을 잃지 않았다. 또한 백엔드 모델링을 세세히 적어서, 코딩할 때 새삼 편하기도 했다.  </p>
<p>프로젝트 진행중 커뮤니케이션의 약간의 미스가 있었다. 백엔드와 프론트 네이밍이 달라 데이터를 불러오지 못하는 문제가 발생했다. 각자 branch에서 작업하다보니 발생한 일이었다. 프론트에서  분명 fetch는 잘 됐는데, 왜 특정데이터가 계속 불러지지 않았다. 알고보니 팀원이 작업한 백엔드key값과 내가 만든 front  키값이 달라서 였다. 하지만 팀원과 코드를 찬찬히 보다가 문제점을 알게 됐다.  다시 한번 느꼈다. 커뮤니케이션이  엄청 중요하구나! </p>
<p>나는 운좋게 좋은 팀원들 만났다. 나는 늘 생각하지만 인복이 타고난 사람이다. 어딜 가든 좋은 사람을 만난다. 종종 빌런도 있지만 대체적으로 좋은 사람들을 만났다. 이번 역시 우리 팀원들을 보면서 배운점도 많고 고마웠다.  </p>
<p>한 팀원은 문제가 발생하면, 끝까지 늘어져서 문제를 해결했다. 그런 점에 놀랐다. 사실 나는 문제가 발생하면, 동공지진부터 와서 우왕좌앙할 때가 많았다. 하지만 이번 프로젝트는 조금 달랐다. 앞서 말한 문제해결력이 높은 팀원들을 본받고자 했다.  “에라 모르겠다 안할래”보다는 무엇이 문제인지 보자, 어떻게 해결할지 생각해보자, 어떻게 구글링하지, 이렇게 풀었는데도 모르겠다.했을때  그때 멘토님과 실력자 동기들에게 물어 해결방법을 물었다. </p>
<p>한팀원은 정리요정이었다. 조근조근한 말투로 회의 내용을 잘 정리해줬다. 가끔 회의를 하다보면, 우리 지금 왜 이야기 한거죠? 회의 끝나고 무엇을 해야하나요? 라고 의문이 들 때면, 정리요정팀원이 촤라라락 오늘했던 미팅을 정리해 방향성을 놓지 않게 해줬다.  또 본인이 처한 문제를 남들이 알아듣기 쉽게 잘 설명했다. 그녀를 보면서 와...저건 배워야겠다 라는 생각이 들었다. 메모: 예쁜 말투로, 조근조근하게 조리있게 말하기!  </p>
<p>한 팀원은 현직 기획자인데, 모든 프로젝트가 어떻게 굴러가는지 숲을 보시는 분이었다. 사실 나는 내가 맡은 업무만 신경쓰느라, 다른 사람들 코드를 제대로 읽지 못했다. 한마디로 나무만 신경쓰느라, 숲이 어떻게 형성되는지 몰랐던 거다. 그분을 보면서 느낀점은 내가 맡은 부분도 잘 해나는 것도 중요하지만, 결국 프로젝트는 협업이다.  남의 코드를 보면서 흐름을 읽히고 숲을 보는게 중요하다는 점을 깨닫게 됐다.  팀이 어떻게 돌아가고 있는지 계속 체크하고, 큰 그림을 계속 보고 있어야 프로젝트의 방향성이 잃지 않고, 또 프로젝트를 잘 이해할 수 있다는 점을 말이다. </p>
<p>그래서 나는 무엇을 팀에게 해주었는가? 생각이 들었다. 나는 웹퍼블리셔의 짧은 경력 덕분에 HTML,CSS에 알려 줄 수 있었다. 팝업창 만드는 법, cors의 덕분에 콘솔로그를 잘 찍자는 경험을 하게 해주었다. 또 일명 주접을 잘 떨어줬다. 여기서 주접은 팀원들에게 내가 할 수 있는 한 칭찬을 많이 해줬다. 사실 나는 칭찬을 잘 하지도 못하고, 잘 받지도 못하는 사람이다. 그런 내가 왜 칭찬을 하게 됐냐면 말이다. 올해 들어서 느낀건데, 이 험난한 취업기에 많은 사람들이 자존감이 떨어져 있다. 또, 코로나 시국이라 긍정적인 거보다는 부정적인 일들이 가득한다. 이런 상황에 같이 꿈을 향해 달려가는 이들에게 칭찬해주고 싶었다. 그냥 칭찬해주고, 좋은 말들을 많이 해주고 싶었다.  </p>
<p>여튼 혼자 공부했다면, 몰랐을 내용을 프로젝트를 통해 많이 얻어갔다.  그래서 다음 2차 프로젝트도 너무 기대된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[PRISMA]]></title>
            <link>https://velog.io/@alicia-mkkim/PRISMA</link>
            <guid>https://velog.io/@alicia-mkkim/PRISMA</guid>
            <pubDate>Thu, 17 Mar 2022 13:34:23 GMT</pubDate>
            <description><![CDATA[<h1 id="orm">ORM</h1>
<p><strong>ORM(Object Relational Mapping)란?</strong> </p>
<ul>
<li>데이터 하나를 하나의 객체로 생각하겠다는 패러다임에서 출발한 개념</li>
<li>데이터베이스는 그대로 유지되고, 데이터베이스의 테이블 하나를 클래스 하나라고 생각하고, 하나씩 대응시켜 데이터를 코드로 관리할 수 있는 시스템이다.</li>
</ul>
<p><strong>활용</strong></p>
<ul>
<li>ORM 사용시, 데이터베이스 직접 쿼리를 날리지 않고, ORM이 javascript 혹 다른 언어로 작성된 코드를 MySQL 등의 쿼리문으로 번역하여 데이터베이스에 명령</li>
</ul>
<p> <strong>Migration 🎀</strong></p>
<ul>
<li>코드로 작성한 모델을 데이터베이스 적용하는 과정!</li>
</ul>
<h1 id="prisma">Prisma</h1>
<ul>
<li>원하는 위치에 directory를 생성하고, npm으로 패키지 설치</li>
</ul>
<pre><code class="language-jsx">npm install prisma --save-dev
npm install @prisma/client --save-dev</code></pre>
<ul>
<li>dotENV 패키지 설치</li>
</ul>
<blockquote>
<p>ENV란? 
웹,앱 개발을 하다보면,  민감한 정보(db관련정보, API_Key)를 오픈소스에 노출시키면 안된다.  해킹의 우려가 있기 때문이다. 그래서 dotenv 패키지를 사용하여 민감한 정보를 넣어 관리해야한다.</p>
</blockquote>
<pre><code class="language-jsx">npm install dotenv 
</code></pre>
<ul>
<li>prisma 시작 &amp; 데이터베이스 연결</li>
</ul>
<pre><code class="language-jsx">npx prisma  // 명령어 확인
npx prisma init // prisma 초기세팅</code></pre>
<pre><code class="language-jsx">
//prisma/schema.prisma 
datasource db {
  provider = &quot;mysql&quot;
  url      = env(&quot;DATABASE_URL&quot;)
}

// .env 
DATABASE_URL = &quot;mysql://USERNAME:PASSWORD@localhost:3306/DATABASE_NAME&quot;</code></pre>
<ul>
<li>Prisma 모델 생성</li>
</ul>
<pre><code class="language-jsx">model Artist{
    id Int @id @default(auto_increment())
    name String @unique 
    created_at Datetime? @default(now())
}</code></pre>
<ul>
<li>Migration</li>
</ul>
<pre><code class="language-jsx">npx prisma migrate dev --name init</code></pre>
<pre><code class="language-jsx">npx prisma migrate dev --폴더명

npx prisma migrate dev create_artist_table</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Database ]]></title>
            <link>https://velog.io/@alicia-mkkim/Database</link>
            <guid>https://velog.io/@alicia-mkkim/Database</guid>
            <pubDate>Mon, 14 Mar 2022 13:28:41 GMT</pubDate>
            <description><![CDATA[<h1 id="database">Database</h1>
<ul>
<li>데이터베이스(DB: Database)는 통합하여 관리되는 데이터의 집합체를 의미합니다.</li>
</ul>
<p><strong>왜 사용하는가?</strong> </p>
<ul>
<li>데이터를 오래기간 저장 및 보존하기 위해서</li>
<li>체계적으로 보존하고 관리하기 위해서</li>
</ul>
<h1 id="관계형-데이터베이스">관계형 데이터베이스</h1>
<p>관계형 데이터베이스는 모든 데이터는 2차원 테이블로 표현할 수 있습니다. </p>
<ul>
<li>Column 열  ( id, 책제목, 작가, 출판사, 가격)</li>
<li>Row 행  (위대한 개츠비, 향수, 오만과 편견 등등)</li>
</ul>
<table>
<thead>
<tr>
<th>id</th>
<th>책 제목</th>
<th>작가</th>
<th>출판사</th>
<th>가격</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>위대한 개츠비</td>
<td>F 스콧 피츠제럴드</td>
<td>믿음사</td>
<td>12,000</td>
</tr>
<tr>
<td>2</td>
<td>향수</td>
<td>파트리트 쥐스킨트</td>
<td>벼루</td>
<td>15,000</td>
</tr>
<tr>
<td>3</td>
<td>오만과 편견</td>
<td>제인 오스틴</td>
<td>앵무새</td>
<td>11,000</td>
</tr>
</tbody></table>
<h2 id="one-to-one">One to One</h2>
<p>관계형 데이터베이스란? </p>
<ul>
<li>DB를 구성하고 있는 데이블들이 서로 상호관련성을 가지고 연결 되어 있다는 의미</li>
<li>각 테이블이 완전히 독립적이지 않고, 테이블 A,B가 서로 연관된 사이</li>
</ul>
<h1 id="관계형-데이터베이스-종류">관계형 데이터베이스 종류</h1>
<ul>
<li>one to one</li>
<li>one to many</li>
<li>many to many</li>
</ul>
<h2 id="one-to-one-1">One to One</h2>
<p>user</p>
<table>
<thead>
<tr>
<th>id (pk)</th>
<th>name</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>송지은</td>
</tr>
<tr>
<td>2</td>
<td>김재범</td>
</tr>
<tr>
<td>3</td>
<td>박태연</td>
</tr>
<tr>
<td>4</td>
<td>강태리</td>
</tr>
</tbody></table>
<p>id_num</p>
<table>
<thead>
<tr>
<th>id (pk)</th>
<th>id_num</th>
<th>user_id (fk)</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>93101</td>
<td>3</td>
</tr>
<tr>
<td>2</td>
<td>870425-1XXXX</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>8901011-2xxx</td>
<td>1</td>
</tr>
<tr>
<td>4</td>
<td>901010-2xxxx</td>
<td>4</td>
</tr>
</tbody></table>
<p>| --- | --- | --- |</p>
<table>
<thead>
<tr>
<th>users</th>
</tr>
</thead>
<tbody><tr>
<td>id</td>
</tr>
<tr>
<td>name</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th>id_num</th>
</tr>
</thead>
<tbody><tr>
<td>id</td>
</tr>
<tr>
<td>id_num</td>
</tr>
<tr>
<td>user_id</td>
</tr>
</tbody></table>
<p>id_num의 user_id는 user의 id를 참조하고 있다.  </p>
<p>서로가 서로의 오로지 한 행(row)에만 연결 </p>
<h2 id="one-to-many">One to Many</h2>
<p>user</p>
<table>
<thead>
<tr>
<th>id (pk)</th>
<th>name</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>송지은</td>
</tr>
<tr>
<td>2</td>
<td>김재범</td>
</tr>
<tr>
<td>3</td>
<td>박태연</td>
</tr>
<tr>
<td>4</td>
<td>강태리</td>
</tr>
</tbody></table>
<p>Pets</p>
<table>
<thead>
<tr>
<th>id (pk)</th>
<th>pet_name</th>
<th>age</th>
<th>user_id (fk)</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>엘사</td>
<td>3</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>초코</td>
<td>2</td>
<td>1</td>
</tr>
<tr>
<td>3</td>
<td>코코</td>
<td>12</td>
<td>2</td>
</tr>
<tr>
<td>4</td>
<td>에릭</td>
<td>3</td>
<td>3</td>
</tr>
<tr>
<td>5</td>
<td>복실이</td>
<td>5</td>
<td>4</td>
</tr>
<tr>
<td>6</td>
<td>순자</td>
<td>10</td>
<td>4</td>
</tr>
</tbody></table>
<p>Pets 테이블의 user_id 칼럼은 user 테이블의 id (pk)를 참조한다. </p>
<p>테이블 user와 테이블 pets는 서로 일대다 관계이다. </p>
<p>로우 하나에 다른 테이블 행에 여러개가 연결 </p>
<h2 id="many-to-many">many to many</h2>
<p>Books </p>
<table>
<thead>
<tr>
<th>id (pk)</th>
<th>Author</th>
<th>Title</th>
<th>Price</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>김코딩, 개발장</td>
<td>개발 어렵지만 함께해요</td>
<td>13,000</td>
</tr>
<tr>
<td>2</td>
<td>김코딩, 송코드</td>
<td>자바스크립트 마스터가 되자</td>
<td>23,000</td>
</tr>
<tr>
<td>3</td>
<td>개발장, 송코드, 이개발</td>
<td>매일 기술 블로그를 씁시다!</td>
<td>16,000</td>
</tr>
</tbody></table>
<p>Author</p>
<table>
<thead>
<tr>
<th>id (pk)</th>
<th>name</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>김코딩</td>
</tr>
<tr>
<td>2</td>
<td>개발장</td>
</tr>
<tr>
<td>3</td>
<td>송코드</td>
</tr>
<tr>
<td>4</td>
<td>이개발</td>
</tr>
</tbody></table>
<p>Author_Books</p>
<table>
<thead>
<tr>
<th>id (pk)</th>
<th>author_id</th>
<th>book_id</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>1</td>
</tr>
<tr>
<td>3</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>4</td>
<td>3</td>
<td>2</td>
</tr>
<tr>
<td>5</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>6</td>
<td>3</td>
<td>3</td>
</tr>
<tr>
<td>7</td>
<td>4</td>
<td>3</td>
</tr>
</tbody></table>
<p>Books</p>
<table>
<thead>
<tr>
<th>id (pk)</th>
<th>Title</th>
<th>price</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>개발 어렵지만 함께해요</td>
<td>13,000</td>
</tr>
<tr>
<td>2</td>
<td>자바스크립트 마스터가 되자</td>
<td>23,000</td>
</tr>
<tr>
<td>3</td>
<td>매일 기술 블로그를 씁시다!</td>
<td>16,000</td>
</tr>
</tbody></table>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/45153a8b-0333-4132-b21d-2fe89fc0e8cc/Screen%20Shot%202022-03-14%20at%2010.36.02%20PM.png" alt=""></p>
<p>테이블 authors와 테이블 books는 서로 다대다 관계이다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Introduction to Backend ]]></title>
            <link>https://velog.io/@alicia-mkkim/Introduction-to-Backend</link>
            <guid>https://velog.io/@alicia-mkkim/Introduction-to-Backend</guid>
            <pubDate>Mon, 14 Mar 2022 13:24:24 GMT</pubDate>
            <description><![CDATA[<h1 id="ui">UI</h1>
<ul>
<li>UI(User Interface)는 유저가 소프트웨어와 만나는 경계면</li>
<li>웹 서비스에서 <code>UI를 만든다</code> 라는 표현은 사용자가 직접 사용하고 정보를 알아들을 수 있는<code>웹 페이지 화면을 만든다</code> 는 의미로 사용.</li>
</ul>
<h1 id="api">API</h1>
<ul>
<li>어플리케이션과 어플리케이션이 서로 의사소통을 하고 데이터를 교환할 수 있는 매개체가 되어주는 대상</li>
<li>서로 다른 프로그램 간에 소통할 수 있게 도와주는 통신 규약</li>
<li>서버에게 요청해서 데이터 가져오는 방법(함수)</li>
</ul>
<h1 id="http-vs-express">Http vs Express</h1>
<pre><code class="language-jsx">const http = require(&#39;http&#39;)
const { sendPosts } = require(&#39;./sendPosts&#39;)

const server = http.createServer((req, res) =&gt; {
  const { url, method } = req
  res.setHeader(&#39;Content-Type&#39;, &#39;application/json&#39;)

  if (url === &#39;/&#39;) return res.send({ message: &#39;/ endpoint&#39; })
  if (url === &#39;/signup&#39; &amp;&amp; method === &#39;POS&#39;) return res.end(JSON.stringify({ message: &#39;회원가입 완료!&#39; }))
  if (url === &#39;/login&#39; &amp;&amp; method === &#39;POST&#39;) return res.end(JSON.stringify({ message: &#39;로그인 완료!&#39; }))
  if (url === &#39;/products&#39; &amp;&amp; method === &#39;GET&#39;) return sendPosts(res)

  res.send(JSON.stringify({ message: &#39;this response answers to every request&#39; }))
})

server.listen(8080, () =&gt; { console.log(&#39;server is listening on PORT 8000&#39;)})</code></pre>
<pre><code class="language-jsx">Http 차이점 
- 서버 만드는 법 
- if 사용됨 
const server = http.createServer((req, res) =&gt; {
  const { url, method } = req
  res.setHeader(&#39;Content-Type&#39;, &#39;application/json&#39;)
  if (url === &#39;/signup&#39; &amp;&amp; method === &#39;POS&#39;) return res.end(JSON.stringify({ message: &#39;회원가입 완료!&#39; }))
})</code></pre>
<pre><code class="language-jsx">const http = require(&#39;http&#39;)
const express = require(&#39;express&#39;)
const { sendPosts } = require(&#39;./sendPosts&#39;)

const app = express()
app.use(express.json())

app.get(&#39;/&#39;, (req, res) =&gt; {
  res.json({ message: &#39;/ endpoint&#39; })
})

app.post(&#39;/signup&#39;, handleSignUp) // 첫번째 인자에는 endpoint url 을 기입하고,
app.post(&#39;/login&#39;, handleLogin) // 각각의 요청에 대해 핸들링 하는 함수를 두번째 인자로 넣는다.
app.get(&#39;/products&#39;, sendPosts)

const server = http.createServer(app)

server.listen(8000, () =&gt; {
  console.log(&#39;server is listening on PORT 8000&#39;)
})</code></pre>
<pre><code class="language-jsx">express을 사용했을 때 다른 점

- const express = require(&#39;express&#39;);
- const app = express();
- app.use(express.json());
- const server = http.createServer(app)</code></pre>
<h1 id="ressend-vs-resjson-vs-resend">res.send() vs res.json() vs res.end()</h1>
<ul>
<li><code>res.send()</code><ul>
<li>res.send([body])의 body에는 Buffer, String, Object, Array가 올 수 있다. 그리고 response Header에는 Body의 Content-Type이 자동으로 정의된다</li>
</ul>
</li>
<li><code>res.json()</code><ul>
<li>json이 아닌 것도 json 형식으로 바꾸어서 보내준다. 즉 content-type 헤더를 <strong>application/JSON</strong>으로 고정한다. 그런데 결국 res.json()도 마지막에 res.send()를 호출한다.</li>
</ul>
</li>
<li><code>res.end()</code><ul>
<li>보내줄 아무 데이터도 없는데 response를 끝내고 싶을 때 사용한다.ex) res.status(400).end();</li>
</ul>
</li>
</ul>
<h1 id="status-code">Status Code</h1>
<ul>
<li><code>Status Code</code>는 사용자가 웹 서버에 요청을 보냈을 때, 응답으로 보내주는 숫자 코</li>
</ul>
<h2 id="2xx-success">2XX Success</h2>
<ul>
<li><strong>200 OK</strong> - 대표적인 성공코드, 에러 없이 요청이 성공적으로 진행, 주로 Get 요청에 대한 응답으로 사용된다.</li>
<li><strong>201 Created</strong> - 요청이 성공적으로 처리되어, 서버가 새로운 리소르를 생성했을 때 사용하는 코드. POST,PUT 등의 요청에 대한 응다브올 주로 사용</li>
<li>204 No Content - 서버에 대한 요청이 성공적으로 처리, 제공해줄 응답 데이터 없을 때 204 사용</li>
</ul>
<h2 id="3xx-redirection">3XX Redirection</h2>
<ul>
<li>301 Moved Permanently - 요청한 리소스가 응답 헤더의 <code>Location</code>에 주어진 URL로 <strong>완전히</strong> 옮겨졌음을 의미.</li>
<li>302 Found - 일시적으로 이동한다</li>
</ul>
<h2 id="4xx-client-error">4XX Client Error</h2>
<ul>
<li>400 Bad Request</li>
<li>401 Unaurhtoized / 403 Forbidden</li>
<li>404 Not Found</li>
</ul>
<h2 id="5xx-server-error"><strong>5XX Server Error</strong></h2>
<p>-500 Internal server Error </p>
<p>-클라이언트의 요청을 처리하는 과정에서 DB에서 오류가 발생하는 등 요청이 잘못된 것이 아니라 서버측에서 문제가 생겼을 때 사용한다.</p>
<p>참고한 블로그: <a href="https://velog.io/@geeneve/%EC%9E%90%EC%A3%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-HTTP-%EC%83%81%ED%83%9C-%EC%BD%94%EB%93%9C">https://velog.io/@geeneve/자주-사용하는-HTTP-상태-코드</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - Monster React Exercise]]></title>
            <link>https://velog.io/@alicia-mkkim/TIL-Monster-React-Exercise</link>
            <guid>https://velog.io/@alicia-mkkim/TIL-Monster-React-Exercise</guid>
            <pubDate>Mon, 14 Mar 2022 13:23:12 GMT</pubDate>
            <description><![CDATA[<p>내가 했던 실수 </p>
<h1 id="monsterjs">Monster.js</h1>
<p>1) useEffect()를 사용해서 Data 붙여주기 </p>
<pre><code class="language-jsx">import React, { useState, useEffect } from &quot;react&quot;;

const API = &#39;[https://jsonplaceholder.typicode.com/users](https://jsonplaceholder.typicode.com/users)&#39;
useEffect(() =&gt; {
        fetch(API, {
     method: &quot;GET&quot;
     })
        .then(response =&gt; response.json())
        .then(result =&gt; console.log(&quot;result :&quot;, result));

},[])</code></pre>
<pre><code class="language-jsx">데이터가 잘 들어오는 지 확인 후, setState에 data를 넣어 주었다🔻

import React, { useState, useEffect } from &quot;react&quot;;
const [ monsters, setMonsters ] = useState([]);

const API = &#39;[https://jsonplaceholder.typicode.com/users](https://jsonplaceholder.typicode.com/users)&#39;
useEffect(() =&gt; {
        fetch(API)
        .then(response =&gt; response.json())
        .then(result =&gt; setMonsters(result));

},[])</code></pre>
<ul>
<li>먼저 useEffect를 선언해주었다.</li>
<li>const API를 선언하고, 주소를 할당해주었다</li>
<li>useEffect (() ⇒ {}, []) : 인수로 콜백 함수와 빈 배열을 전달한 경우, 처음 컴포넌트가 렌더링이 된 이후 무조건 한번 호출이 되고 이후에는 호출되지 않는다. (<a href="https://velog.io/@kim98111/useEffect">읽어보면 좋은 블로그</a>)</li>
</ul>
<p><strong>Monster.js를  하면서 알게 됐던 점</strong> </p>
<ul>
<li>method가 ‘GET’이면 설정을 생략할수 있다.</li>
</ul>
<pre><code class="language-jsx">useEffect(() =&gt; {
        fetch(API)
        .then(response =&gt; response.json())
        .then(result =&gt; console.log(&quot;result :&quot;, result));

},[])</code></pre>
<p><strong>Monster.js에서 했던 실수</strong></p>
<ul>
<li>Monster.js 에서는 데이터만 자식컴포넌트에 넘겨주면 되는데, 왜 map메서드를 돌렸다. 맵을 돌려야 자식컴포넌트에 값을 넘길 수 있다는 잘못된 생각을 했던 것 같다. CardList에서 card로 데이터를 넘기려고 했다. 당연히 오류가 떴다.</li>
<li>당연히 이미 맵을 돌린 상태니, cardList에서는 오브젝트{}로 들어온 상태이니 map이 안된다고 떴다.</li>
<li>에러 메시지에  “you may use Array” 라고 적혀있었다. 나는  값을 array로 받고 있는지 확인하니 object였다. 그래서 곰곰이 생각하다가, 아... 값만 넘겨주만 되니까, Monster.js에서는 map 돌릴 필요가 없다는 것을  깨달았다.</li>
</ul>
<blockquote>
<p><strong><code>map()</code></strong> 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.</p>
</blockquote>
<p>실수한 코드 🔻</p>
<pre><code class="language-jsx">return (
        &lt;div className=&quot;monsters&quot;&gt;
      &lt;h1&gt;컴포넌트 재사용 연습!&lt;/h1&gt;
      {monsters.map((monsters) =&gt; (
        &lt;CardList monsters={monsters} /&gt;
      ))}
    &lt;/div&gt;
  );</code></pre>
<p>다시 바꾼 코드 🔻</p>
<pre><code class="language-jsx">&lt;div className=&quot;monsters&quot;&gt;
      &lt;h1&gt;컴포넌트 재사용 연습!&lt;/h1&gt;
      &lt;CardList monsters={monsters} /&gt;
    &lt;/div&gt;</code></pre>
<h1 id="cardlistjs">CardList.js</h1>
<p>해결방안 </p>
<ul>
<li>Monster.js(부모 컴포넌트)에서 받아온 data가 잘 들어오는지 먼저 확인부터 했다.</li>
<li>console.log(props) ——&gt; 콘솔로그로 확인하니 잘 들어오고 있었다.</li>
<li>map함수를 돌렸고, 원하는 정보를 적어둠.  key, id, name, email</li>
</ul>
<pre><code class="language-jsx">function CardList({monsters}) {
  return &lt;div className=&quot;cardList&quot;&gt;
        {
          monsters.map(monster =&gt; 
             &lt;Card key={monster.id} id={monster.id} name={monster.name} email={monster.email}/&gt;)
        }
    &lt;/div&gt;;
}</code></pre>
<p><strong>CardList.js하면서 알게된 점</strong> </p>
<ul>
<li>부모 → 자식 컴포터는 props를 표현방식(?)이 다양한다.</li>
</ul>
<p>ex) </p>
<p>첫번째 방법:  props를 넘겨준다.  <a href="http://props.monsters.map">props.monsters.map</a>(monster → monster)</p>
<p>두번째 방법: props를 넘겨준다. const { monsters } = props로 사용한다.  <a href="http://monsters.map">monsters.map</a> </p>
<p>세번째 방법: function Cardlist({monsters}){} 로 받아온다. 이 방법이 코드를 간략하게 쓸 수 있어 유용하게 쓰일 것 같다!  </p>
<pre><code class="language-jsx">function CardList({monsters}) {
  return &lt;div className=&quot;cardList&quot;&gt;
        {
          monsters.map(monster =&gt; 
             &lt;Card key={monster.id} id={monster.id} name={monster.name} email={monster.email}/&gt;)
        }
    &lt;/div&gt;;
}</code></pre>
<h1 id="cardjs">Card.js</h1>
<pre><code class="language-jsx">function Card({ id, name, email}) {
  return (
  &lt;div className=&quot;cardContainer&quot;&gt;
     &lt;img src={`https://robohash.org/${id}?set=set2&amp;size=180x180`} alt=&quot;monster&quot; /&gt;
      &lt;h2&gt;{name}&lt;/h2&gt;
      &lt;p&gt;{email}&lt;/p&gt;
  &lt;/div&gt;
  )
}</code></pre>
<p><strong>Input에서 monster 이름을 찾기</strong></p>
<pre><code class="language-jsx">const [userInput, setUserInput] = useState(&quot;&quot;);

// SearchBox 에 props로 넘겨줄 handleChange 메소드 정의
  const handleChange = ( event) =&gt; {
       setUserInput(event.target.value);
  }

  const serachMonster = monsters.filter(monster =&gt; 
      monster.name.toLowerCase().includes(userInput.toLowerCase())
  )

return (
    &lt;div className=&quot;monsters&quot;&gt;
      &lt;h1&gt;컴포넌트 재사용 연습!&lt;/h1&gt;
      &lt;SearchBox handleChange={handleChange} /&gt;
      &lt;CardList monsters={serachMonster} /&gt;
    &lt;/div&gt;
  );</code></pre>
<p> <strong>내가 했던 실수</strong></p>
<ul>
<li><p>handleChange 함수 만들때 도대체 어떻게 해야할지 감도 안 잡혔다.</p>
<ul>
<li><p>먼저, input에 event,target.value 값을 받아야와겠다 라는 생각이 들었다.</p>
</li>
<li><p>setUserInput안에 받아온 값을 넣어주면 되겠다고 생각</p>
<pre><code class="language-jsx">const handleChange = (event) =&gt; {
       setUserInput(event.target.value)
}</code></pre>
</li>
</ul>
</li>
<li><p>그래...그렇다면 filter를 사용하라는 guideLine을 보고 정말 감이 잡히지 않아, 풀이 영상을 보았다.</p>
<ul>
<li>그렇구나. 그러고 저거를 어디에 선언해줘야 하는걸까? 고민을 했다.</li>
</ul>
</li>
</ul>
<pre><code class="language-jsx">const searchMonsters = monsters.filter(monster =&gt; 
     return monster.name.toLowerCase().includes(userInput.toLowerCase())
)</code></pre>
<p><strong>잘못한 실수</strong></p>
<ul>
<li>serachMonster과 Monsters를 동시게 넘겨줬다.</li>
<li>그렇게 생각했던 이유는 일단 monsters안에 있는 data를 넘겨줘야, searchMonster가 작동할거라고 생각했다.</li>
<li>풀이를 다시 보니, monsters={searchMonsters}로 바꿔준다.</li>
<li>왜일까 고민을 해보니, 사실 searchMonster에 이미 monster에서 넘겨준 함수가 포함된거다. 내가 Input에다가 무언가를 치지 않으면, 없는 상태의 모든 monster 데이터를  보여주는거고, input에 이름을 치면 조건에 맞는 데이터만 보여준다</li>
<li>개발자가 되어가는 과정이 어렵군요 ㅜㅜ</li>
</ul>
<p><strong>내가 실수한 코드</strong> </p>
<pre><code class="language-jsx">return (
    &lt;div className=&quot;monsters&quot;&gt;
      &lt;h1&gt;컴포넌트 재사용 연습!&lt;/h1&gt;
      &lt;SearchBox handleChange={handleChange} /&gt;
      &lt;CardList monsters={monsters} searchMonsters={searchMonsters}/&gt;
    &lt;/div&gt;
  )</code></pre>
<p>수정 코드 </p>
<pre><code class="language-jsx">return (
    &lt;div className=&quot;monsters&quot;&gt;
      &lt;h1&gt;컴포넌트 재사용 연습!&lt;/h1&gt;
      &lt;SearchBox handleChange={handleChange} /&gt;
      &lt;CardList monsters={searchMonsters}/&gt;
    &lt;/div&gt;
  )</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[동기, 비동기란 ]]></title>
            <link>https://velog.io/@alicia-mkkim/%EB%8F%99%EA%B8%B0-%EB%B9%84%EB%8F%99%EA%B8%B0%EB%9E%80</link>
            <guid>https://velog.io/@alicia-mkkim/%EB%8F%99%EA%B8%B0-%EB%B9%84%EB%8F%99%EA%B8%B0%EB%9E%80</guid>
            <pubDate>Mon, 14 Mar 2022 13:21:58 GMT</pubDate>
            <description><![CDATA[<h1 id="동기-vs-비동기란">동기 vs 비동기란</h1>
<blockquote>
<p><strong>동기</strong>는 순차적, 직력적으로 테스크를 수행한다.
<strong>비동기</strong>는 병렬적으로 테스크를 수행한다.</p>
</blockquote>
<h2 id="동기란">동기란?</h2>
<ul>
<li>동기는 요청을 보낸 후 응답 (결과물)을 받아야지만 다음 동장이 이루어지는 방식을 말한다.</li>
<li>모든 일은 순차적으로 실행되며 어떤 작업이 수행중이라면 다음 작업은 대기하게 된다.<ul>
<li>장점: 설계가 간단하고 직관적</li>
<li>단점: 결과를 볼대 까지 아무것도 못하고 대기해야한다</li>
</ul>
</li>
</ul>
<h2 id="비동기란">비동기란?</h2>
<ul>
<li>비동기는 동시에 일어나지 않는다 의미한다.  요청과 결과가 동시에 일어나지 않는 거라는 약속.</li>
<li>요청한 그 자리에서 결과가 주어지지 않음</li>
<li>노드 사이의 작업 처리 단위를 동시에 맞추지 않아도 된다.<ul>
<li>장점: 결과가 주어지는 데 시간이 걸리더라도 그동안 다른 작업이 가능해 자원의 효율적인 사용이 가능</li>
<li>단점 : 설계가 동기보다 복잡함</li>
</ul>
</li>
</ul>
<p>아래의 사진을 보면서 동기와 비동기를 이해해보자! </p>
<ul>
<li>동기<ul>
<li>첫번째 손님이 아메리카노를 시켰다. 첫번 째 손님의 커피가 나올때 까지 2번째 손님은 기다려야한다.</li>
<li>첫번째 손님이 요청한 아메리카노가 나온 뒤에 , 2번째 손님의 주문을 받을 수 있다.</li>
<li>즉, 앞의 손님의 요청과 결과가 다 나올때까지 뒤의 손님은 계속 기다려야한다.</li>
</ul>
</li>
<li>비동기<ul>
<li>카운터에서 일단 첫번째 손님의 커피주문을 받는다. 첫번째 손님은 진동벨을 가지고 커피를 기다린다.</li>
<li>(첫번째 손님의 커피는 나오지 않았지만) 카운터에서 두번째 손님의 주문을 받는다.</li>
<li>진동벨이 울리면, 첫번째 손님이 카운터로 와 커피를 받아간다.</li>
<li>비동기 같은 경우, 일단 손님들의 요청을 계속 받으면서,  요청한 결과를 처리하는 한다.</li>
</ul>
</li>
</ul>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/1248969f-02cf-4071-b44b-0a4bf84784d3/%E1%84%87%E1%85%B5%E1%84%83%E1%85%A9%E1%86%BC%E1%84%80%E1%85%B5:%E1%84%83%E1%85%A9%E1%86%BC%E1%84%80%E1%85%B5.png" alt=""></p>
<p>출처: <a href="https://simju9397.tistory.com/45">https://simju9397.tistory.com/45</a></p>
<h2 id="그렇다면-비동기는-왜-필요할까">그렇다면 비동기는 왜 필요할까?</h2>
<blockquote>
<p>만약 우리가 데이터를 서버에서 받아오는 앱을 만든다고 가정해보자.
먼저, 서버로부터 데이터를 받아오는 코드가 실행되어야 한다. 만약 비동기로 처리하지 않고, 동기적으로 구성을 하게 된다면, 데이터를 받아오기까지 기다린 다음에 앱이 실행될 것이다. 서버에 가져오는 데이터 양이 많을 수록 앱의 실행속도는 기하급수적으로 느려진다.                                                                              데이터를 불러오기까지 앱이 대기하는 상태가 발생된다. 이런 불편을 없애기 위해서 데이터를 수신하는 코드와 페이지를 표시하는 것은 비동기적으로 처리를 해야한다. 가장 대표적인 예가 setTimeOut과 AJax다.</p>
</blockquote>
<p>출저: <a href="https://velog.io/@lsj8367/Javascript-%EB%8F%99%EA%B8%B0%EC%99%80-%EB%B9%84%EB%8F%99%EA%B8%B0%EB%B0%A9%EC%8B%9D%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90">https://velog.io/@lsj8367/Javascript-동기와-비동기방식의-차이점</a> </p>
<pre><code class="language-jsx">동기 처리 

console.log(1);
console.log(2);
console.log(3);

//1
//2
//3 </code></pre>
<pre><code class="language-jsx">비동기 처리 

console.log(1);
setTimeout(() =&gt; {
    console.log(2)
},2000)
console.log(3);

//1
//3
//2</code></pre>
<h1 id="callback">Callback</h1>
<p> <strong>콜백함수란?</strong> </p>
<ul>
<li><p>이름 그대로 나중에 호출되는 함수를 말한다.</p>
</li>
<li><p>특정함수에 매개변수로 전달된 함수를 의미한다.</p>
</li>
<li><p>콜백 함수는 코드를 통해 명시적으로 호출하는 함수가 아니라, 개발자는 단지 함수를 등록 하기만 하고, 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수를 말한다.</p>
<p><strong>콜백은 좀 더 쉽게 이해해보기 🔻</strong></p>
</li>
</ul>
<blockquote>
<p>콜백 함수의 동작 방식은 일종의 식당 자리 예약과 같습니다. 일반적으로 맛집을 가면 사람이 많아 자리가 없습니다. 그래서 대기자 명단에 이름을 쓴 다음에 자리가 날 때까지 주변 식당을 돌아다니죠. 만약 식당에서 자리가 생기면 전화로 자리가 났다고 연락이 옵니다. 그 전화를 받는 시점이 여기서의 콜백 함수가 호출되는 시점과 같습니다. 손님 입장에서는 자리가 날 때까지 식당에서 기다리지 않고 근처 가게에서 잠깐 쇼핑을 할 수도 있고 아니면 다른 식당 자리를 알아볼 수도 있습니다.
자리가 났을 때만 연락이 오기 때문에 미리 가서 기다릴 필요도 없고, 직접 식당 안에 들어가서 자리가 비어 있는지 확인할 필요도 없습니다. 자리가 준비된 시점, 즉 데이터가 준비된 시점에서만 저희가 원하는 동작(자리에 앉는다, 특정 값을 출력한다 등)을 수행할 수 있습니다.
출저:  <a href="https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/#%EB%A7%88%EB%AC%B4%EB%A6%AC">캡팁판교 비동기/동기</a></p>
</blockquote>
<p>콜백 함수에는 동기,비동기가 있다. </p>
<ul>
<li>synchronous callback</li>
<li>asynchronous callback</li>
</ul>
<pre><code class="language-jsx">console.log(1);
setTimeout(() =&gt; {
    console.log(2)
},2000)
console.log(3);

// synchronous callback
function printImmediately(print){
    print()
}

printImmediately(() =&gt; console.log(&#39;hello&#39;))

//Asynchrouns callback
function printWithDelay(print, timeout){
    setTimeout(print, timeout)
}

printWithDelay(() =&gt; console.log(&#39;async callback), 2000)

//1
//3
//&#39;hello&#39;
//&#39;async callback&#39; </code></pre>
<ul>
<li><p>자바스크립트 execute 했을 때 컴퓨터가 인식한 모습 (hoisiting )</p>
<pre><code class="language-jsx">  //hoisting 된모습 

  // synchronous callback
  function printImmediately(print){
      print()
  }

  //Asynchrouns callback
  function printWithDelay(print, timeout){
      setTimeout(print, timeout)
  }

  console.log(1);  ----&gt; 동기
  setTimeout(() =&gt; {
      console.log(2)
  },2000)          -----&gt; 비동기 
  console.log(3);

  printImmediately(() =&gt; console.log(&#39;hello&#39;))  ----&gt; 동기 
  printWithDelay(() =&gt; console.log(&#39;async callback), 2000) ----&gt; 비동기 
</code></pre>
</li>
</ul>
<h2 id="callback-지옥">callBack 지옥</h2>
<pre><code class="language-jsx">function Callback(callback){
    console.log(&#39;콜백 함수&#39;);
    callback();
}
Callback(() =&gt; {
    console.log(&#39;콜백을 받는곳!&#39;)
})</code></pre>
<ul>
<li>가독성이 떨어짐</li>
<li>비즈니스 로직을 한 눈에 보기 어려움</li>
<li>에러가 발생했을때, 문제를 찾기 어려움</li>
<li>유지보수가 어렵다</li>
</ul>
<h1 id="promise">Promise</h1>
<ul>
<li>Promise is a JavaScript Object for asynchronous operation.</li>
<li>프로미스는 자바스크립트 비동기 처리에 사용되는 객체이다.  비동기 처리를 제어하는, 혹은 기존 비동기 처리 코드들을 동일한 (표준) API 형태로 사용할 수 있게 해주는 ES6에 추가된 기능이다.</li>
<li>when a new Promise is created, the executor runs automatically.</li>
</ul>
<h2 id="promise-객체-사용법">Promise 객체 사용법</h2>
<pre><code class="language-jsx">const getThreePromise = () =&gt; new Promise((resolve, reject) =&gt; {
    resolve(3);
});

getThreePromise().then(console.log);</code></pre>
<h2 id="producer-vs-consumer"><strong>Producer vs Consumer</strong></h2>
<pre><code class="language-jsx">
//producer 
const promise = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; {
    resolve(&quot;hello world!!!!&quot;);
    //  reject(new Error(&#39;no network&#39;))
  }, 2000);
});

//consumer : then, catch, finally  
promise
  .then((value) =&gt; {
    console.log(value);
  })
  .catch((error) =&gt; {
    console.log(error);
  })
  .finally(() =&gt; {
    console.log(&quot;finally&quot;);
  });</code></pre>
<h2 id="state">state</h2>
<ul>
<li><p>Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태</p>
</li>
<li><p>Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태</p>
</li>
<li><p>Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태</p>
<p><strong>Pending</strong> </p>
</li>
</ul>
<p>아래와 같이 new Promise() 메서드를 호출하면 대기 상태가 된다. </p>
<pre><code class="language-jsx">new Promise()</code></pre>
<p><strong>Fullfilled</strong> <strong>-이행</strong> </p>
<p>콜백 함수의 인자 resolve를 아래와 같이 실행하면 이행 상태가 된다. </p>
<pre><code class="language-jsx">function getData(){
        return new Promise((resolve, reject) =&gt; {
        let data = 100;
        resolve(data);
    })
}

getData().then(data =&gt; console.log(data));

//100</code></pre>
<p><strong>rejected - 실패</strong></p>
<pre><code class="language-jsx">function getData(){
   return new Promise((resolve,reject) =&gt; {
       reject(new Error(&#39;에러발생&#39;))
   })
}

getData().then().catch(console.log)
//[object Error] {....}</code></pre>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/11e24c58-358d-4e2f-bdae-d789b8c6417f/%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%86%E1%85%B5%E1%84%89%E1%85%B3%20%E1%84%92%E1%85%B3%E1%84%85%E1%85%B3%E1%86%B7%20%E1%84%8E%E1%85%A5%E1%84%85%E1%85%B5.svg" alt=""></p>
<p>출처 : <a href="https://joshua1988.github.io/web-development/javascript/promise-for-beginners/">프로미스 흐름 처리</a> </p>
<p><strong>여러 개의 프로미스 연결하기 (Promise Chaining)</strong></p>
<h2 id="promise-chaining">Promise Chaining</h2>
<pre><code class="language-jsx">const fetchNumber = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; resolve(1), 1000);
});

fetchNumber
  .then((num) =&gt; num * 2) //2
  .then((num) =&gt; num * 3) //6
  .then((num) =&gt; {
    return new Promise((resolve, reject) =&gt; {
      setTimeout(() =&gt; resolve(num - 1), 1000); //5 
    });
  })
  .then((num) =&gt; console.log(num)); //5

//5 </code></pre>
<h2 id="error-handling">Error Handling</h2>
<pre><code class="language-jsx">const getHen = () =&gt;
  new Promise((resolve, reject) =&gt; {
    setTimeout(() =&gt; resolve(&quot;🐓&quot;), 1000);
  });

const getEgg = (hen) =&gt;
  new Promise((resolve, reject) =&gt; {
    // setTimeout(() =&gt; resolve(`${hen} =&gt; 🥚`), 1000);
    setTimeout(() =&gt; reject(new Error(`${hen} =&gt; 🥚`) ), 1000);
  });

const cook = (egg) =&gt;
  new Promise((resolve, reject) =&gt; {
    setTimeout(() =&gt; resolve(`${egg} =&gt; 🍳`));
  });

getHen() //
  .then(getEgg)
  .catch(error =&gt; {
      return &#39;🥖&#39;
  })
  .then(cook)
  .then(console.log)
  .catch(console.log);//🥖 =&gt; 🍳</code></pre>
<h2 id="callback-→-promise">callback → promise</h2>
<p>callback 함수 </p>
<pre><code class="language-jsx">class UserStorage {
  loginUser(id, password) {
    return new Promise((resolve, reject) =&gt; {
      setTimeout(() =&gt; {
        if (
          (id === &quot;min&quot; &amp;&amp; password === &quot;dream&quot;) ||
          (id === &quot;coder&quot; &amp;&amp; password === &quot;wecode&quot;)
        ) {
          resolve(id);
        } else {
          reject(new Error(&quot;not found&quot;));
        }
      }, 2000);
    })
  }

  getRoles(user) {
    return new Promise((resolve, reject) =&gt; {
      setTimeout(() =&gt; {
        if (user === &quot;min&quot;) {
          resolve({ name: &quot;min&quot;, role: &quot;admin&quot; });
        } else {
          reject(new Error(&quot;no access&quot;));
        }
      }, 1000);
    });
  }
}

const userStorage = new UserStorage();
const id = prompt(&quot;enter your id&quot;);
const password = prompt(&quot;enter your password&quot;);

userStorage.loginUser(id, password)
.then(userStorage.getRoles)
.then( user =&gt;  alert(`Hello ${user.name}, you have a ${user.role} role`))
.catch(console.log)</code></pre>
<p>promise 함수 바꾼 것 </p>
<pre><code class="language-jsx">class UserStorage {
  loginUser(id, password) {
    return new Promise((resolve, reject) =&gt; {
      setTimeout(() =&gt; {
        if (
          (id === &quot;min&quot; &amp;&amp; password === &quot;dream&quot;) ||
          (id === &quot;coder&quot; &amp;&amp; password === &quot;wecode&quot;)
        ) {
          resolve(id);
        } else {
          reject(new Error(&quot;not found&quot;));
        }
      }, 2000);
    })
  }

  getRoles(user) {
    return new Promise((resolve, reject) =&gt; {
      setTimeout(() =&gt; {
        if (user === &quot;min&quot;) {
          resolve({ name: &quot;min&quot;, role: &quot;admin&quot; });
        } else {
          reject(new Error(&quot;no access&quot;));
        }
      }, 1000);
    });
  }
}

const userStorage = new UserStorage();
const id = prompt(&quot;enter your id&quot;);
const password = prompt(&quot;enter your password&quot;);

userStorage.loginUser(id, password)
.then(userStorage.getRoles)
.then( user =&gt;  alert(`Hello ${user.name}, you have a ${user.role} role`))
.catch(console.log)</code></pre>
<h1 id="async--await">async &amp; await</h1>
<p> async와 await는 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법이다. 기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 도와준다. </p>
<ul>
<li><p>Syntactic Sugar란?</p>
<p>  문법적인 기능은 그대로 유지하되, 코드를 작성하는 사람 입장에서 혹은 그 코드를 다시 읽는 사람의 입장에서 편의성이 높은 프로그래밍 문법을 의미합니다.</p>
</li>
</ul>
<h2 id="await-사용법">await 사용법</h2>
<pre><code class="language-jsx">async function 함수명() {
  await 비동기_처리_메서드_명();
}

function fetchItems() {
  return new Promise(function(resolve, reject) {
    var items = [1,2,3];
    resolve(items)
  });
}

async function logItems() {
  var resultItems = await fetchItems();
  console.log(resultItems); 
}

logItems();</code></pre>
<h2 id="예시">예시</h2>
<pre><code class="language-jsx">
function delay(ms){
    return new Promise((resolve) =&gt; setTimeout(resolve =&gt; ms))
}

// promise를 사용할때 
function getApple(){
    return delay(300)
    .then(() =&gt; console.log(&#39;🍎&#39;))
}

// async 를 사용하면 아래와 같이 바꿀수 있다. 

async function getApple(){
   await delay(3000)
     return &#39;🍎&#39;
}

getApple().then(console.log) // &quot;🍎&quot;</code></pre>
<pre><code class="language-jsx">function delay(ms){
    return new Promise(resolve =&gt; setTimeout(resolve, ms));
}

async function getApple(){
    await delay(3000);
    return &#39;🍎&#39;
}

async function getBanana(){
    await delay(3000);
    return &#39;🍌&#39;
}

function pickFruits(){
    return getApple()
    .then(apple =&gt; {
        return getBanana().then(banana =&gt; `${apple} + ${banana}`)
    })
}

pickFruits().then(console.log)

// &#39;🍎+🍌&#39;

그렇지만 promise 많이 쓰면 콜백지옥 같은 일이 발생한다. 

async function pickFruits(){
     const apple = await getApple();
     const banana = await getBanana();

        return `${apple} + ${banana}`
}

pickFruits().then(console.log)

// 바나나와 사과를 순차적으로 받아올 필요가 없다. 
// Promise가 생성되자마자, 실행된다는 점을 이용해보자  
async function pickFruits(){
    const applePromise = getApple();
    const bananaPromise = getBanana()
    const apple = await applePromise;
    const banana = await bananaPromise;

    return `${apple} + ${banana}`

}
pickFruits().then(console.log)</code></pre>
<h2 id="error-handling--try-catch">error handling  (try catch)</h2>
<pre><code class="language-jsx">function delay(ms){
    return new Promise(resolve =&gt; setTimeout(resolve, ms));
}

async function getApple(){
    await delay(1000);
//     throw &#39;error가 발생함&#39;; 
    return &#39;🍎&#39;;
}

async function getBanana(){
    await delay(1000);
    return &#39;🍌&#39;
}

async function pickFruits(){
    try{
        const apple = await getApple();
        const banana = await getBanana();

       return `${apple} + ${banana}`

    }catch(err){
        console.log(err)
    }
}

pickFruits().then(console.log)</code></pre>
<h2 id="유용한-promise-api">유용한 Promise API</h2>
<p><strong>Promise.all([ ])</strong></p>
<pre><code class="language-jsx">function pickAllFruits() {
    return Promise.all([getApple(),getBanana()])
    .then(fruits =&gt; fruits.join(&#39; + &#39;))
}

pickAllFruits().then(console.log); //&quot;🍎 + 🍌&quot;</code></pre>
<p><strong>Promise.race([])</strong></p>
<pre><code class="language-jsx">function delay(ms){
    return new Promise(resolve =&gt; setTimeout(resolve, ms));
}

async function getApple(){
    await delay(2000);
    return &#39;🍎&#39;
}

async function getBanana(){
    await delay(1000);
    return &#39;🍌&#39;
}

function pickOnlyOne(){
    return Promise.race([getApple(),getBanana()])
}

pickOnlyOne().then(console.log) // 🍌 ---바나나만 뜸 </code></pre>
<h1 id="자바스크립트의-동작원리-엔진-런타임-호출-스택">자바스크립트의 동작원리: 엔진: 런타임, 호출 스택</h1>
<p>참고 블로그 :<a href="https://resilient-923.tistory.com/308">https://resilient-923.tistory.com/308</a>  </p>
<ul>
<li>자바스크립트의 큰 특징 중 하나는 &#39;단일 스레드&#39; 기반의 언어이다. 동시에 하나의 작업만 처리 할 수 있다.</li>
<li>but, 자바스크립트가 사용되는 환경을 생각해보면 많은 작업이 동시에 처리되고 있는 걸 볼 수 있다.</li>
</ul>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/43677110-6c12-4be9-9fda-f0c9540b34f8/eventloop.png" alt=""></p>
<p>출처 : <a href="https://resilient-923.tistory.com/308">https://resilient-923.tistory.com/308</a></p>
<h1 id="호출-스택-call-stack">호출 스택 (call stack)</h1>
<p>엔진의 주요 두 구성요소는</p>
<ul>
<li><strong>Memory Heap</strong> : 메모리 할당이 일어나는 곳</li>
<li><strong>Call Stack</strong> : 코드 실행에 따라 호출 스택이 쌓이는 곳</li>
</ul>
<p>자바스크립트 엔진은 Memory Heap과 Call Stack으로 구성되어 있다.</p>
<p>자바스크립트는 <strong>단일 스레드(싱글 스레드) 프로그래밍 언어</strong>인데, 이 말은 <strong>Call Stack</strong>이 하나 라는 의미이다.</p>
<p><strong>MemoryHeap</strong>은 우리가 프로그래밍을 할 때 선언된 변수, 함수 등이 담겨지는, 메모리 할당이 일어나는 곳이다.</p>
<p><strong>Call Stack</strong>은 코드가 실행될 때 쌓이는 곳이고, <strong>Stack형태</strong>로 쌓이게 된다.</p>
<p>Stack은 LIFO(Last In First Out) 선입후출 즉, 가장 마지막에 들어온 게 먼저 나가는 구조이다.</p>
<h1 id="web-api">Web API</h1>
<hr>
<ul>
<li>****Web API는 JS엔진이 아닌, 브라우저에서 제공하는 API이다. (대표적 setTimeout, AJax)</li>
<li>Call Stack에서 실행된 비동기 함수는 Web API를 호출하고, Web API는 콜백함수를 Callback Queue에 넣어준다.</li>
</ul>
<h1 id="callback-queue--task-queue"><strong>Callback Queue / Task Queue</strong></h1>
<ul>
<li>비동기로 실행된 콜백 함수가 보관되는 영역이다.</li>
<li>Queue 자료구조는 FIFO(First In First Out) 구조로 섭입 선출, 먼저 들어간 게 먼저 나오는 구조이다.</li>
</ul>
<h1 id="event-loop란"><strong>Event Loop란?</strong></h1>
<ul>
<li>Event Loop는 Call Stack과 Callback Queue의 상태를 체크하여,Call Stack이 빈 상태가 되면, Callback Queue의 첫번째 콜백을 Call Stack으로 밀어 넣는다</li>
<li>이러한 반복적인 행동을 틱(tick) 이라 부른다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[components vs JSX]]></title>
            <link>https://velog.io/@alicia-mkkim/components-vs-JSX</link>
            <guid>https://velog.io/@alicia-mkkim/components-vs-JSX</guid>
            <pubDate>Mon, 28 Feb 2022 15:02:08 GMT</pubDate>
            <description><![CDATA[<h1 id="components--jsx">components &amp; JSX</h1>
<p><strong>components</strong></p>
<ul>
<li>component: 재활용 가능한 UI 구성단위</li>
</ul>
<p><strong>components 특징</strong></p>
<ul>
<li>재활용 가능</li>
<li>코드 유지보수에 좋음</li>
<li>페이지 구성을 쉽게 파악</li>
<li>컴포넌트는 또 다른 컴포넌트를 포함 할 수 있음</li>
</ul>
<p><strong>Components 종류</strong> </p>
<ul>
<li>class 형</li>
<li>function형</li>
</ul>
<p><strong>1) Class Component</strong></p>
<ul>
<li>클래스형 컴포넌트 - render 필수!</li>
</ul>
<pre><code class="language-jsx">import React from &#39;react&#39;

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

export default Component</code></pre>
<p><strong>2) Functional Component</strong></p>
<ul>
<li>React 16.8 버전에서 Hook 기능이 추가되면서 state 사용 가능해짐</li>
</ul>
<pre><code class="language-jsx">import React from &#39;react&#39;

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

export default Component</code></pre>
<h1 id="jsx-javascript-syntax-extension">JSX (Javascript Syntax Extension)</h1>
<ul>
<li>리액트에서 사용하는 자바스크립트 확장 문법</li>
<li>바벨을 통해 일반 자바스크립트 형태로 변환</li>
</ul>
<p><strong>특징</strong></p>
<ul>
<li>&lt;&gt;&lt;/&gt; : 모든 요소를 감싸는 최상위 요소!</li>
<li>self closing Tag <div ></li>
<li>class vs className</li>
<li>inline styling &lt;div style={{color : ‘red’}}&gt;안녕하세요!</div></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React Intro]]></title>
            <link>https://velog.io/@alicia-mkkim/React-Intro</link>
            <guid>https://velog.io/@alicia-mkkim/React-Intro</guid>
            <pubDate>Mon, 28 Feb 2022 15:01:22 GMT</pubDate>
            <description><![CDATA[<h1 id="1-why-react">1. Why React?</h1>
<h2 id="1-1-web-application의-발전">1-1. Web Application의 발전</h2>
<ul>
<li>애플리케이션 규모가 커지고 다양한 UI,UX를 구현하기 위해서 이전의 방법(DOM,JQuery)으로는 어플리케이션 개발하고 코드를 유지보수 하는 것이 어려워짐</li>
<li><strong>규모가 커지고 복잡한 애플리케이션을 개발하며 생산성을 향상시키고 많은 양의 데이터 관리와 코드 유지 보수를 더욱 편리하게 하기 위해 다양한 Frontend Framework(Library)가 등장</strong></li>
</ul>
<h2 id="1-2-frontend-framework-종류">1-2 Frontend FrameWork 종류</h2>
<ul>
<li>Angular</li>
<li>Vue</li>
<li>React</li>
</ul>
<p>Library vs FrameWork : <a href="https://webclub.tistory.com/458">참고 블로그</a></p>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/35127500-39a9-4b4c-b885-4fc26e5fe357/Screen%20Shot%202022-03-01%20at%2012.01.04%20AM.png" alt=""></p>
<h1 id="2-what-is-react">2. What is React?</h1>
<h3 id="2-1-react-정의">2-1. React 정의</h3>
<ul>
<li>React는 페이스북에서 개발하고 관리하는 <strong>사용자 인터페이스(UI)를 만들기 위한 JavaScript 라이브러리</strong>다.</li>
<li>리액트는 <strong><code>가상 돔(Virtual Dom)</code></strong> 을 통해 UI를 빠르게 업데이트한다. 가상 돔은 <strong>이전 UI 상태를 메모리에 유지해서, 변경될 UI의 최소 집합을 계산하는 기술</strong>이다.</li>
</ul>
<h1 id="3-작업-환경-설정">3. 작업 환경 설정</h1>
<p><strong>Node.js</strong></p>
<ul>
<li>Node.js 는 자바스크립트가 브라우저 밖(ex. 서버)에서도 동작하게 하는 환경</li>
</ul>
<pre><code class="language-jsx">node -v </code></pre>
<p><strong>npm</strong></p>
<ul>
<li>Node 기반의 패키지를 사용하려면 <strong>npm(node package manager)</strong>이라는 패키지 도구가 필요하다.</li>
</ul>
<pre><code class="language-jsx">npm -v</code></pre>
<p><strong>CRA (create-react-app)</strong></p>
<ul>
<li><strong>리액트 프로젝트를 시작하는데 필요한 개발 환경을 세팅 해주는 도구(toolchain)</strong><ul>
<li>package manager - 예시) yarn, npm. 제 3 패키지 install, 업데이트를 쉽게 해줌</li>
<li>bundler - 예시) parcel, webpack. 복잡한 자바스크립트 모듈 호환.</li>
<li>complier - 예시) Babel.  옛날 브라우저에서도 모던 자바스크립트를 사용할 수 있도록 해줌</li>
</ul>
</li>
</ul>
<h1 id="cra---settings">CRA - Settings</h1>
<pre><code class="language-jsx">// 1. Desktop - 원하는 파일 
cd Desktop/react_practice

//2. 리액트 프로젝트 설치
npx create-react-app react_practice

//3. 프로젝트 진입
cd react_practice

//4.로컬 서버 띄우기
npm start</code></pre>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/9cc1468f-10e3-430f-acb6-011fa1ec15ac/Screen%20Shot%202022-03-01%20at%2012.00.20%20AM.png" alt=""></p>
<ul>
<li><code>npm start</code> 입력 시 <code>http://localhost:3000</code> 주소를 확인할 수 있습니다.</li>
<li>같은 와이파이를 쓰는 사람이라면, on Your Network : (주소)를 주면, 배포 전이라도 현재 작업물을 알 수 있다.</li>
</ul>
<p>1) node.modules</p>
<ul>
<li>CRA를 구성하는 모든 패키지 소스 코드가 존재하는 폴더</li>
</ul>
<p>2) package.json</p>
<ul>
<li>기본 패키지 외 추가로 설치된 라이브러리/패키지 정보가 기록되는 파일</li>
<li>모든 프로젝트마다 package.json 하나씩 존재</li>
</ul>
<p>3) .gitIgnore</p>
<ul>
<li>github에 올리고 싶지 않는 폴더와 파일을 작성할 수 있다</li>
<li>push를 해도 .gitignore 파일에 작성된 폴더와 파일은 올라가지 않음</li>
</ul>
<p>4) public -index.html/ images폴더 </p>
<p>5) src - index.js (작업하는 폴더와 파일들!)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[git , github]]></title>
            <link>https://velog.io/@alicia-mkkim/git-github</link>
            <guid>https://velog.io/@alicia-mkkim/git-github</guid>
            <pubDate>Wed, 23 Feb 2022 14:04:18 GMT</pubDate>
            <description><![CDATA[<h1 id="git">Git</h1>
<h2 id="1-install-git">1. install git</h2>
<aside>
💡 Git 다운로드 링크: [https://git-scm.com/downloads](https://git-scm.com/downloads)

</aside>

<ul>
<li><strong>git이 제대로 설치 되었는 지 확인하는 법</strong></li>
</ul>
<pre><code class="language-jsx">git --version</code></pre>
<ul>
<li><strong>이름&amp;이메일설정</strong></li>
</ul>
<pre><code class="language-jsx">git config --global user.name &quot;이름&quot;
git config --global user.email &quot;이메일&quot;</code></pre>
<h2 id="2git-init">2.git init</h2>
<ul>
<li>터미널에서 Git으로 프로젝트를 관리 시작하려면, 원하는 폴더에 들어간다 ex) cd desktop/git_practice</li>
<li>다음 명령어를 입력해준다</li>
</ul>
<pre><code class="language-jsx">git init .</code></pre>
<ul>
<li>.git 폴더가 잘 설치되어있는지 확인해주기 위해 다음 명령어를 입력한다. 숨겨진 .git 폴더를 찾아볼 수 있다.</li>
</ul>
<pre><code class="language-jsx">ls -al </code></pre>
<h2 id="3-staging-and-committing-code">3. staging and committing code</h2>
<p><strong>git status</strong> : 어떤 파일이 변경되었는지, 어떤 파일이 추가 되었는지 전부 보여준다.</p>
<pre><code class="language-jsx">git status</code></pre>
<p><strong>git add:</strong> 원하는 파일들을 stagin area로 추가</p>
<pre><code class="language-jsx">git add</code></pre>
<pre><code class="language-jsx">git add file1.js
git add file1.js file2.js file3.js
git add . (변경된 파일 모두 올려주기)</code></pre>
<p><strong>git commit -m “</strong>”: 커밋은 특정 시간의 코드 스냇샵의 형태로 해당 respository의 커밋 기록에 남게됩니다. git add 명령어를 사용하여 모든 파일을 staging area를 추가했으면 커밋을 해줘야한다. </p>
<pre><code class="language-jsx">git commit -m “메세지”</code></pre>
<p><strong>git log :</strong> 모든 커밋 내역을 보여준다.</p>
<pre><code class="language-jsx">git log</code></pre>
<h1 id="github">github</h1>
<h2 id="git-vs-github">Git vs GitHub</h2>
<ul>
<li><strong>Git</strong>은 버전 관리 시스템으로, 시간이 지남에 따라 파일의 변경 사항을 추적하는 도구</li>
<li><strong>GitHub</strong>은 Git을 사용하는 프로젝트를 위한 호스팅 서비스</li>
</ul>
<h2 id="using-github">Using GitHub</h2>
<p><strong>Common Workflow: 내 로컬 Repository를 GitHub 에 push 하기</strong></p>
<ol>
<li>로컬에서 add / commit 한다.</li>
<li>Github 으로 이동 후 새 repository를 생성한다.</li>
<li>나의 로컬 repository 를 GitHub repository 와 연결한다. (remote 추가)</li>
<li>새 remote 를 이용하여 코드를 Push 한다.</li>
</ol>
<p><strong>github repo 생성</strong></p>
<ul>
<li><p>github 사이트에서 new respository 생성
<img src="https://images.velog.io/images/alicia-mkkim/post/21b9ae1c-728f-4eec-b9b0-bda6e7d7d4c2/Screen%20Shot%202022-02-23%20at%2010.56.01%20PM.png" alt=""></p>
</li>
<li><p>git remote add origin respository주소</p>
</li>
<li><p>git push: git push origin main</p>
</li>
</ul>
<p>** git add, git commit, git push 한세트!!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - Linux  & Terminal ]]></title>
            <link>https://velog.io/@alicia-mkkim/TIL-Linux-Terminal</link>
            <guid>https://velog.io/@alicia-mkkim/TIL-Linux-Terminal</guid>
            <pubDate>Wed, 23 Feb 2022 00:49:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[가위바위보 문제]]></title>
            <link>https://velog.io/@alicia-mkkim/%EA%B0%80%EC%9C%84%EB%B0%94%EC%9C%84%EB%B3%B4-%EB%AC%B8%EC%A0%9C</link>
            <guid>https://velog.io/@alicia-mkkim/%EA%B0%80%EC%9C%84%EB%B0%94%EC%9C%84%EB%B3%B4-%EB%AC%B8%EC%A0%9C</guid>
            <pubDate>Sun, 20 Feb 2022 06:10:08 GMT</pubDate>
            <description><![CDATA[<p>js replit 문제를 풀다가 난관(?)에 부딪쳤다.
무의식적으로 문제가 어렵다고 생각한건지, 아니면 난독증이 오신건지
문제를 읽다가, 문제를 이해하지 못해서 혼자 멘붕이 와버렸다. 
프리코스 자바스크립트 시험 쳤을때도, 문제 그대로 보긴 보단, 간단한 문제를 자꾸 어렵게 생각하는 경향이 있었다. 
오답노트 정리하다가 반성의 시간! </p>
<p>이전에 같이 일하셨던 분이 내 코딩 짜는 모습을 보고 했던 말이 생각했다. </p>
<p>&quot;한번에 너무 많은 경우의 수를 생각하니, 문제를 접근 못하시는 것 같아요.(ㅜㅜ코딩 한줄 쓰지 못해서...좌절중이엇음)
 먼저, 간단하게 생각하기. 그리고 조건에 맞는 코딩을 단계별로 적어주면 좋을듯해요!&quot;</p>
<blockquote>
<p>Assignment
index.js에 있는 가위 바위 보 게임 함수를 아래 조건에 맞게 구현해주세요.
rockPaperScissors 함수를 구현해서 가위 바위 보 게임을 구현해주세요.
가능하면 || 와 &amp;&amp; 연산자 둘다 사용해주세요.
player1과 player2 중 이긴 사람이 누군지 리턴해주세요.
예를 들어, player1이 이겼으면 &quot;player1&quot; 이 리턴 되고 그 반대의 경우라면 &quot;player2&quot;가 리턴이 되어야 합니다.
만일 비기는 경우에는 무조건 &quot;player1&quot;이 리턴 되어야 합니다.
player1 과 player2 의 값은 다음 셋 중 하나 입니다.
&quot;가위&quot;
&quot;바위&quot;
&quot;보&quot;
예를 들어, player1은 &quot;가위&quot; 이고 player2는 &quot;보&quot; 이면 &quot;player1&quot; 이 리턴 되어야 합니다.</p>
</blockquote>
<pre><code>
Assignment - 다음 함수 안에 코드를 구현하세요
function rockPaperScissors(player1, player2) {
//  예시:
  // if ( (player1 === &quot;가위&quot; &amp;&amp; player2 === &quot;보&quot; ) || (player1 === &quot;가위&quot; &amp;&amp; player2 === &quot;가위&quot;) ) {
  //     result = &quot;player1&quot;;

}
module.exports = {rockPaperScissors};력하세요</code></pre><p>문제를 읽고, 아래의 예시를 읽는데, 순간 예시가 이해가 안 가서 당황했다.
지금 생각해보면, 나는 true/false에 꽂혀있었고... 말도 안되게 문제를 이해하게 되는 상황이 되었다.
player1 === 가위이면 true, player2 === &#39;보&#39;... 그러다가 만약 player2가 &quot;보&quot;가 아니면 false로 찍히는건가? 그럼 뭘 비교하는거지??</p>
<p>근데 오늘 평온한 마음 장착시키고 연산자 설명을 다시 읽었다. 그제서야 문제가 제대로 보이기 시작. 바로 해결됨 ... 와.... </p>
<pre><code>// Assignment - 다음 함수 안에 코드를 구현하세요
function rockPaperScissors(player1, player2) {
  let result;
  if(
    (player1 === &quot;가위&quot; &amp;&amp; player2 === &#39;보&#39;) || 
    (player1 === &#39;가위&#39; &amp;&amp; player2 === &#39;가위&#39;) || 
    (player1 === &#39;바위&#39; &amp;&amp; player2 === &quot;가위&quot;) || 
    (player1 === &quot;바위&quot; &amp;&amp; player2 === &quot;바위&quot;) ||
    (player1 === &quot;보&quot; &amp;&amp; player2 === &quot;바위&quot;) ||
    (player1 === &quot;보&quot; &amp;&amp; player2 === &quot;보&quot;)
    ){
    result = &#39;player1&#39;;
  } 

  if(
    (player1 === &quot;보&quot; &amp;&amp; player2 === &#39;가위&#39;) || 
    (player1 === &quot;가위&quot; &amp;&amp; player2 === &#39;바위&#39;) || 
    (player1 === &quot;바위&quot; &amp;&amp; player2 === &#39;보&#39;)
  ){
    result = &#39;player2&#39;
  }

  return result;
}

rockPaperScissors(&#39;가위&#39;,&#39;바위&#39;)

// 아래의 코드는 절대로 수정하거나 삭제하지 마세요.
module.exports = {rockPaperScissors};</code></pre><p>클린 코드인지는 모르겠지만 일단 테스트 돌렸을때 다 초록불 뜸! 
내가 생각한 방법은 일단 result 변수를 선언하고 대신 값은 할당하지 않았다. 그 이유는 승패여부에 따라 player가 달라지기 때문!
먼저 if 조건식을 사용했다. Player1이 이길 수 있는 경우의 수를 다 적었다. 조건에 비길경우는 player1를 반환하라고 했기 때문에, 같은 경우도 함께 넣어줬다. 그리고 result = &quot;player1&quot;을 할당했다. 마찬가지로 player2도 이길 수 있는 조건식을 넣어주고, 변수result에 player2를 할당. </p>
<p>그래도 혼자 잘 풀어내서 행벅! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[(TIL) precourse JS 오답정리]]></title>
            <link>https://velog.io/@alicia-mkkim/precourse-JS-%EC%98%A4%EB%8B%B5%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@alicia-mkkim/precourse-JS-%EC%98%A4%EB%8B%B5%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 18 Feb 2022 04:43:19 GMT</pubDate>
            <description><![CDATA[<h1 id="02-isbiggerthanfive">02. isBiggerThanFive</h1>
<p>Q. 하나의 숫자를 인자로 받아 5보다 크면 true 아니면 false를 반환하는 함수를 구현해주세요.</p>
<p>내 답안</p>
<pre><code class="language-jsx">function isBiggerThanFive(num) {
if( num &gt; 5){
      return true 
    }else{
      return false
    }
}

isBiggerThanFive();</code></pre>
<p>개선후 ) </p>
<p>나는 if문을 사용해서 함수를 작성했다. 물론 위의 방법은 틀린 것은 아니다. 하지만 true,false를 반환하는 경우라면 아래와 같이 한 줄로 작성할 수 있다. 와우!! </p>
<p>**return에 조건식을 적으면 boolean으로 반환한다.  이후 모든 문제를 ...한줄로 작성할 수 있었다는 매직!</p>
<pre><code class="language-jsx">function isBiggerThanFive(num) {
    return num &gt;5; 
}

isBiggerThanFive(8)</code></pre>
<h1 id="05getsecondelement">05.getSecondElement</h1>
<p>Q. 인자로 반드시 길이가 2 이상인 배열이 들어옵니다.배열의 두번째 요소를 반환하는 함수를 구현해주세요.</p>
<p>내 답안</p>
<pre><code class="language-jsx">function getSecondElement(numbers) {
   let result = numbers
    if(result.length &gt; 2){
       return result[1];
    }
}

let number = [1,6,7,4];
console.log(getSecondElement(number))</code></pre>
<p>개선후 ) </p>
<p>전반적으로 이번 시험에서 내가 문제를 다소 어렵게 생각했다. “2이상인 배열이 들어온다” 라는 문구를 보고 아 조건식이구나! 라고 생각했다. 그래서 위와 같은 코드를 작성했다. 먼저, 배열의 길이를 보고 2이상인지 확인 작업을 하고 그 후에 배열의 2번째 요소를 작성한다 라고 적었다.... 그렇지만 정작 문제는 걍 배열의 두번째 요소를 보여달라는 말이었다ㅠㅠ </p>
<pre><code class="language-jsx">function getSecondElement(numbers) {
     return numbers[1];
}

let number = [1,6,7,4];
console.log(getSecondElement(number))</code></pre>
<h1 id="07-getsumofarray">07 getSumOfArray</h1>
<p>Q.아래 조건을 만족하는 함수를 구현해주세요.</p>
<p>배열은 길이가 1이상이며 모든 요소가 숫자로 되어있습니다.</p>
<p> 배열 모든 요소의 합을 반환하는 함수를 구현해주세요.</p>
<p>내답안</p>
<ul>
<li>조건이 아닌데 조건식이라고 착각했다. 그래서 배열 안에 들어가는 요소들이 먼저 숫자인지 확인하는 작업을 넣어줬다.  check 변수명을 보면, 일단 배열안에 있는 요소가 숫자인지 확인!</li>
<li>그러고 난 뒤, sum 변수명에 배열안에 수를 더하는 식을 표현을 넣어줌</li>
<li>조건식을 시작<ul>
<li>먼저, 배열의 길이가 1 미만이거나, 숫자가 아닌 거를 체크해줌.  조건이 맞으면 바로 false를 반환해줌</li>
<li>마지막으로 return sum을 반환</li>
</ul>
</li>
</ul>
<pre><code class="language-jsx">function getSumOfArray(numbers) {

  let arr = numbers;
  let check = arr.forEach(arr =&gt; arr === number);
   const sum = arr.reduce((a,b) =&gt; a +b);
   if(arr.length &lt; 1 &amp;&amp; !check ){
       return false
   }else{
      return sum 
   }
}
getSumOfArray()</code></pre>
<p>개선후</p>
<ul>
<li>문제를 잘못 파악한 1인.  배열 길이 1개 이상 및 숫자가 조건식이 아닌, default로 들어오는 상황임! 그래서 그것을 체크해줄 필요가 없었다고 한다.</li>
<li>멘토님께서 2가지 방법을 쓰셨는데, 1번답안은 숫자랑 배열길이 조건 빼면 나와 거의 비슷!</li>
<li>대신 다른점은 나는 reduce()라는 메서드를 사용하였고, 멘토님은 +=이라는 연산방법 사용! 내가 봤을때 이게 훨씬 직관적이고 편한거 같다</li>
<li>두번째 방법은 ... 한줄로 끝나는 매직. forEach!</li>
</ul>
<pre><code class="language-jsx">function getSumOfArray(numbers) {

   let amount = 0;
   for( let i = 0; i &lt; numbers.length ; i++){
     amount += numbers[i];
   }
   return amount; 

}

getSumOfArray()</code></pre>
<pre><code class="language-jsx">function getSumOfArray(numbers) {

   numbers.forEach((num) =&gt; {return amount += num});

   return amount; 

}
getSumOfArray()</code></pre>
<h1 id="08-findadultname">08. findAdultName</h1>
<p>Q. 배열에서 성인을 찾아 그 이름을 반환하는 함수를 만들어주세요.</p>
<p>함수는 인자로 객체가 요소인 배열을 받습니다.</p>
<p>배열의 요소는 각 사람에 대한 객체이며 아래는 배열의 예시입니다.</p>
<p>배열 예시 : [</p>
<p>{ name: &#39;tom&#39;, age: 10, gender: &#39;male&#39; },</p>
<p>{ name: &#39;sera&#39;, age: 30, gender: &#39;female&#39; },</p>
<p>]</p>
<p>함수의 반환값 : &#39;sera&#39;</p>
<p>배열에는 성인이 없거나 오직 한 명만 있습니다.</p>
<p>배열에 성인이 없다면 false를 반환해주세요.</p>
<p>19세까지는 미성년자, 20세부터는 성인으로 가정합니다.</p>
<p>내 답안</p>
<ul>
<li>어제 적은 TIL(<a href="https://velog.io/write?id=62b6e5d2-d24d-4d6e-80cf-0c46991bbe70">Javascript 시험 8</a>)에 있다. 마지막 조건식인 성인이 없을 경우, return false를 해라! 하는 부분이 이해가 잘 되지 않았다. 오늘 자바스립트 풀이 보면서, return에 대한 개념을 잡을 수 있었다. 나랑 비슷한 생각을 하셨던 분이 질문을 하셔서 반가움 (ㅜㅜ나만 이런생각을 한게 아니군!)</li>
<li>for문을 다 돌고, 성인이 없으면 그 밖에 return false를 해야한다.<ul>
<li>만약 성인이 있다면, for문 안에 if 조건식에서 return 되기 때문에 함수 끝! 이제 정확히 이해됨!!!! &gt;_&lt;</li>
</ul>
</li>
</ul>
<pre><code class="language-jsx">function findAdultName(people) {
  for(let i = 0; i &lt; people.length; i++){
      if(people[i].age &gt;= 20) return people[i].name
  }

  return false;

}

let obj = [
    { name: &#39;tony&#39;, age: 10, gender: &#39;male&#39; }, 
    { name: &#39;sera&#39;, age: 30, gender: &#39;female&#39; }, 
  ]
findAdultName(obj);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[(TIL)JS- findAdultName ]]></title>
            <link>https://velog.io/@alicia-mkkim/JS-findAdultName</link>
            <guid>https://velog.io/@alicia-mkkim/JS-findAdultName</guid>
            <pubDate>Thu, 17 Feb 2022 15:09:13 GMT</pubDate>
            <description><![CDATA[<p>잘 풀리지 않았던 8번문제</p>
<pre><code class="language-jsx">
잘 풀리지 않았던 8번문제

```jsx

  08. findAdultName
  배열에서 성인을 찾아 그 이름을 반환하는 함수를 만들어주세요.

  함수는 인자로 객체가 요소인 배열을 받습니다. 
  배열의 요소는 각 사람에 대한 객체이며 아래는 배열의 예시입니다.
  배열 예시 : [
    { name: &#39;tom&#39;, age: 10, gender: &#39;male&#39; }, 
    { name: &#39;sera&#39;, age: 30, gender: &#39;female&#39; }, 
  ]
  함수의 반환값 : &#39;sera&#39;
  배열에는 성인이 없거나 오직 한 명만 있습니다.
  배열에 성인이 없다면 false를 반환해주세요.
  19세까지는 미성년자, 20세부터는 성인으로 가정합니다.

  * @param {*[]} people - array of people</code></pre>
<p>내가 풀었던 방법</p>
<pre><code class="language-jsx">let obj = [
    { name: &#39;tom&#39;, age: 10, gender: &#39;male&#39; }, 
    { name: &#39;sera&#39;, age: 30, gender: &#39;female&#39; }, 
  ]

function findAdultName(people){
    for(let i = 0; i &lt; people.length ; i++ ){
                if( people.age &gt; 20 )return people.name[i]
                else return false; 
}

findAdultName(obj);</code></pre>
<p>계속 오류가 떴다. </p>
<pre><code class="language-jsx">사실 처음에는 else return false를 적어주지 않았다.
그때는 sera가 잘 나왔다. 그렇지만  
질문에 &#39;만약 성인이 한명이라도 없으면&#39;return false라는 말이 있어서 넣어줬다.
그러자...sera는 나오지 않고 바로 false가 나오는 사태가 나왔다.</code></pre>
<p>결국 팀원들에게 물어봤고 </p>
<p>return false의 위치가 잘못 되었다고  한다. 슬랙으로 열심히 설명해줬지만 이해가 되지 않았다.</p>
<p>고마운 팀원들이 설명해주셨다. (프로필사진과 이름은 지움! 개인정보는 중요하니까!)
<img src="https://images.velog.io/images/alicia-mkkim/post/706c86b2-f4c2-4bdc-9d3a-827b4b2491fe/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-18%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2012.08.59.png" alt=""></p>
<p>마지막 답변을 보고 이해가 됐다. 루프를 돌려서 전체를 검사를 해야하지만 나같은 경우 for문안에 조건문 if/else때문에 에러가 난거다. 루프가 다 돌게 하고 그 안에서 성인인 경우 성인의 이름을 넣어주세요 라는 식만 필요한 거다. 루프를 다 돌고 나서도 성인으 없다면,  루프  밖에다가 return false를 해야 한다는 거다. </p>
<p>글이 잘 정리가 되지 않지만! 일단 루프를 다 돌고 그에 맞는 조건식을 찾아야한다는 점!!!!!! </p>
<p>문제 파악)</p>
<ol>
<li>뭔가 if를 넣으면 꼭 else를 넣어야한다는 생각이 있어서 오류를 범한거 같다! </li>
<li>아직 for문, 루프가 돈다는 개념이 익숙하지 않다. 그래서 일단 돌리고 그다음은??? 어떻게 해야하지? 라는 고민이 많이 든다. </li>
<li>가끔 다른 문제 풀때 return을 넣어줘야하나? 말아야하나? 고민할때 있다.  자바스크립트랑 논리적인 사고가 정확히 잡히지 않아서 스스로도 코드를 짜면서 “이렇게 코드 짜는게 맞나” 의심이 들어서 인거 같다 .</li>
</ol>
<p>개선할 점!) </p>
<ul>
<li>반복문 for 에 익숙해지자</li>
<li>인터넷에 찾아보는 건 좋은데, 먼저 스스로 생각해 볼 것</li>
<li>return 개념</li>
<li>문제 보고 당황하지 말자! 제대로 읽자!!!!!! 문제에 답이 있따다닫다다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[(TIL) 문자열 - 숫자, 숫자 - 문자열 ]]></title>
            <link>https://velog.io/@alicia-mkkim/%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%88%AB%EC%9E%90-%EC%88%AB%EC%9E%90-%EB%AC%B8%EC%9E%90%EC%97%B4</link>
            <guid>https://velog.io/@alicia-mkkim/%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%88%AB%EC%9E%90-%EC%88%AB%EC%9E%90-%EB%AC%B8%EC%9E%90%EC%97%B4</guid>
            <pubDate>Wed, 16 Feb 2022 15:10:47 GMT</pubDate>
            <description><![CDATA[<h2 id="질문--number--string--string--number---string--number">질문:  Number + String = String ? Number - String = Number?</h2>
<pre><code class="language-jsx">let age = &quot;20&quot;;
let currentYear = 2022;

currentYear - age;
//expected answer : undefined or Error 발생이겠지?  
*그렇게 생각한 이유: 
1) age는 string 이고 currentYear는 number이다.
서로 다른 데이터 타입이기 때문에 연산이 되지 않을거라고 생각했다. 

콘솔창에 확인차 해보니 결과는...2002. 계산이 되서 나오네요. ㅇ_ㅇ;;?
</code></pre>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/754aec17-989d-4bc8-bf65-87d6fbfd2a89/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2011.42.58.png" alt=""></p>
<p>콘솔로그에  확인차 다른 값들도 넣어보다가 이상한 결과를 발견했습니다.</p>
<ul>
<li><p>concation: string과 number를 더하면</p>
<ul>
<li>console.log(”2” + 2) 를 할때는 값은 22입니다. type은 문자열입니다.</li>
<li>사전스터디 소헌님 강의에서도 문자열과 숫자를 더한 값의 데이터는 문자열이 된다고 하셨거든요.</li>
</ul>
</li>
<li><p>substract: string과 number를 서로 빼면</p>
<ul>
<li>console.log(”2022”- 2)하면 결과 값은 2022 입니다. 우리가 생각하는 연산이 되네요.</li>
<li>typeof를 사용하여  확인하니 데이터의 타입은 숫자입니다.  ...문자열이 아니네요.</li>
</ul>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/63ddc285-a685-496d-aa41-c4b6b94565f6/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2011.48.22.png" alt="">
<img src="https://images.velog.io/images/alicia-mkkim/post/9f4f0549-e520-44bd-bcda-9af0bc24e730/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2011.17.15.png" alt=""></p>
</li>
</ul>
<h2 id="질문">**질문</h2>
<p> 문자열과 숫자를 합치거나(+), 숫자와 문자열을 뺄때(-)로 왜 데이터 종류가 달라지나요????????</p>
<h2 id="나와-비슷한-질문을-한-사람의-답변"><a href="https://stackoverflow.com/questions/8116261/adding-and-subtracting-strings-and-numbers-in-javascript-auto-type-conversion">나와 비슷한 질문을 한 사람의 답변</a></h2>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/63f8a13c-686c-4740-9bec-400264aa2b38/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2011.55.49.png" alt=""></p>
<ul>
<li><ul>
<li>같은 경우, 디폴트가 string이라고  합니다</li>
</ul>
</li>
<li><ul>
<li>일 경우, 스트링에 사용하지 않고, 숫자로 변환해서 사용한다고 하네요.</li>
</ul>
</li>
</ul>
<h2 id="그렇다면-어떻게-방지해야할까">그렇다면 어떻게 방지해야할까?</h2>
<ul>
<li>물론 아래와 같이 문자열안에 숫자 “30”를 넣지않고 말그래로 문자를 넣으면 위와 같은 고민을 할 필요는 없다.<ul>
<li>“abcd” + 123456 = abcd123456</li>
<li>“abcds” - 12346 = NaN</li>
<li>not a number가 뜨니 계산이 되지 않는다
<img src="https://images.velog.io/images/alicia-mkkim/post/681c0715-83ae-4289-b400-2cd27792b068/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2012.05.01.png" alt=""></li>
</ul>
</li>
</ul>
<p>하지만 예를 들어서 실수로 문자열을 받아오게 된다면?? 숫자 계산을 하고 싶어진다면???  </p>
<h2 id="내가-찾은-방법">내가 찾은 방법</h2>
<p>String → Number로 바꿔주는 작업해주기 (<a href="https://dev.to/sanchithasr/7-ways-to-convert-a-string-to-number-in-javascript-4l">참고사이트</a>)</p>
<p>대표적으로 쓰이는 방법 (참고사이트 7가지 방법이 있지만 대표적인 것만 추려봄)</p>
<ul>
<li>parseInt()</li>
<li>Number()</li>
<li>Math.floor()</li>
</ul>
<p>근데..실무에서 이런 일이 있을까...요? ..... 궁금해지네요.</p>
<p>멘토님한테 물어보니, 
자바스크립트는 타입이 약한 타입이라서, 가끔 저런 현상이 일어난다고 한다.
그래서 가급적이면,  문자열에서 숫자를 뺴거나 숫자에서 문자열을 빼는 행위는 지양한다고 한다.  </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - 웹 서비스의 역사와 발전]]></title>
            <link>https://velog.io/@alicia-mkkim/TIL-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4%EC%9D%98-%EC%97%AD%EC%82%AC%EC%99%80-%EB%B0%9C%EC%A0%84</link>
            <guid>https://velog.io/@alicia-mkkim/TIL-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4%EC%9D%98-%EC%97%AD%EC%82%AC%EC%99%80-%EB%B0%9C%EC%A0%84</guid>
            <pubDate>Wed, 16 Feb 2022 01:16:26 GMT</pubDate>
            <description><![CDATA[<h1 id="assignment">Assignment</h1>
<hr>
<ul>
<li>1세대, 2세대, 3세대 웹 서비스의 특징을 조사해 주세요.</li>
<li>3세대 웹에서 존재하는 포지션들을 조사하고 각 포지션의 역할을 요약해 주세요.</li>
<li>google classroom에 제출해주세요.</li>
</ul>
<h1 id="세대별-특징">세대별 특징</h1>
<ol>
<li>1세대 웹 -  전통적인 web system architecture — 정적  웹 </li>
<li>2세대 - UI(User Interaction) 증가 — 동적 웹 </li>
<li>3세대 - SPA(Single Page Application) — FE/BE 개발자 구분 </li>
<li>Modern Web - 규모가 커지면서  Web system 발전</li>
</ol>
<h1 id="3세대-존재하는-포지션">3세대 존재하는 포지션</h1>
<ul>
<li>Designer</li>
<li>Front-End Developer / Web publisher</li>
<li>Backend Developer<ul>
<li>API을 담당하는 개발자</li>
<li>데이터 수집, 분석, 관리 등을 데이터 관련 시스템을 개발하는 개발자</li>
<li>DevOps: 개발자가 system infrastructure 관리까지 당담</li>
</ul>
</li>
<li>System Operations<ul>
<li>System infra를 담당하는 직군. Data center 등에 서버 설치 및 관리가 주 임무 중 하나</li>
</ul>
</li>
<li>Data Scientist<ul>
<li>머신러닝, AI 등의 데이터 분석 알고리즘 과 데이터 분석 모델링을 구현하는 직군</li>
</ul>
</li>
<li>Data Enginner<ul>
<li>Data Scientist들이 코딩을 잘 하지 못하기 때문에, 데이터 사이언티스들을 도와 데이터 모델링 구현을 도와주는 개발자</li>
</ul>
</li>
<li>Tester<ul>
<li>QA (Quantity Assurance)</li>
<li>Software Engineer in Test/Automation</li>
</ul>
</li>
<li>Fullstack Developer (FE+BE)</li>
<li>PM</li>
<li>Scrum</li>
<li>SoftWare Architecture</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Position, inline, inline-block, block]]></title>
            <link>https://velog.io/@alicia-mkkim/Position-inline-inline-block-block</link>
            <guid>https://velog.io/@alicia-mkkim/Position-inline-inline-block-block</guid>
            <pubDate>Tue, 15 Feb 2022 14:51:37 GMT</pubDate>
            <description><![CDATA[<h1 id="position">Position</h1>
<p><strong>Position</strong>이란? element를 배치하는 방법을 지정하는 속성입니다. </p>
<ol>
<li>Static</li>
<li>Relative </li>
<li>Absolute</li>
<li>fixed</li>
</ol>
<h1 id="1-static기본값">1. Static(기본값)</h1>
<ul>
<li>element에 position를 주지 않아도, 기본값으로 static으로 되어있음</li>
<li>z-index 적용되지 않는다</li>
<li>top, bottom, left, right 적용 안됨</li>
</ul>
<h1 id="2-relative">2. Relative</h1>
<ul>
<li>static과 달리, top, bottom, left, right가 적용이 된다.</li>
</ul>
<pre><code class="language-jsx">&lt;div style=&quot;position: relative; top: 100px&quot;&gt;안녕!&lt;/div&gt;
&lt;h1&gt;헬로우&lt;/h1&gt;</code></pre>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/f86f50a9-e2f7-491b-b96a-4d69bd7797c8/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.07.52.png" alt=""></p>
<ul>
<li>위의 사진을 보면, h1에는 Position를 주지 않았으니, top: 100px 영향을 받지 않았다.</li>
<li>다만, 다른 레이아웃에 있는 태그들과 겹쳐 보일 수 있으니, 사용시 주의바람!</li>
</ul>
<h1 id="3-absolute">3. Absolute</h1>
<p>absolute는 element가 문서의 일반적인 흐름을 따르지 않습니다. 대신 <em>가장 가까운 위치에 있는 조상 element(static 이 아닌)에 상대적 위치로 배치됩니다 .</em>조상 element가 없으면 문서 본문(body)을 기준으로 삼고 페이지 스크롤에 따라 움직입니다.</p>
<pre><code class="language-jsx">&lt;style&gt;

.outer{
position: absolute;
 right: 0;
 top: 0;
 width: 100px;
 height: 100px; 
background: aqua

}
section {
position: relative; 
width: 300px;
height: 500px; 
margin: 0 auto;
border: 1px solid red
}

.box{
position: absolute;
right: 0;
top: 0; 
width: 100px;
height: 100px;
 background: salmon
}

.box:last-child{
background-color: beige
}
&lt;/style&gt;

&lt;div class=&quot;outer&quot;&gt;박스!&lt;/div&gt;

&lt;section&gt;
     &lt;div class=&quot;box&quot;&gt;박스!&lt;/div&gt;
    &lt;div class=&quot;box&quot;&gt;박스!&lt;/div&gt;
 &lt;/section&gt;</code></pre>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/ae2f1163-c7c3-4ece-9b73-7ad5f6032e6e/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.26.19.png" alt=""></p>
<p>현재 class outer에 대한 부모는 body이다.그러니 right:0을 하니 상단 우측에 “안녕하세요”가 붙어 있는 결과가 보인다</p>
<ul>
<li>반면, section에 position :relative 가 있다. Class의 box에 부모다. box들은 그 안에서 위치를 자리잡는 것을 볼 수 있다.</li>
</ul>
<h1 id="4-fixed">4. Fixed</h1>
<p>fixed 역시 absolute와 마찬가지로 element가 문서의 일반적인 흐름에서 제거됩니다. 대신, 스크린의 뷰포트(viewport)를 기준으로 한 위치에 배치됩니다. 즉, 스크롤되어도 움직이지 않는 고정된 자리를 갖게 됩니다.</p>
<pre><code class="language-jsx">
  &lt;style&gt;
    *{
      margin: 0;
      padding:0;
    }

    section{
      height: 200vh;
      background-color: blue;
    }
    nav{
      width: 100%;
      height: 30px;
      background-color: red;
      color: #fff;
      position: fixed;
      top: 0; 
      left:0;
      right:0;
    }

  &lt;/style&gt;

&lt;body&gt;
&lt;section&gt;
  &lt;nav&gt;메뉴 fixed&lt;/nav&gt;
&lt;/section&gt;
&lt;/body&gt;</code></pre>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/def304e5-d183-4e02-99d2-dd26c93cb0b7/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.26.19.png" alt=""></p>
<ul>
<li>스크롤을 계속 했는데도, nav가 위에 붙어있는 것을 볼 수 있다.</li>
</ul>
<h1 id="display-inline-inline-block-block">display: inline, inline-block, block</h1>
<h1 id="1-inline">1. inline</h1>
<pre><code class="language-jsx">&lt;a&gt;, &lt;i&gt;, &lt;span&gt;, &lt;abbr&gt;, &lt;img&gt;, &lt;strong&gt;, &lt;b&gt;, &lt;input&gt;, &lt;sub&gt;, &lt;br&gt;, &lt;code&gt;, &lt;em&gt;, &lt;small&gt;, &lt;tt&gt;, &lt;map&gt;, &lt;textarea&gt;, &lt;label&gt;, &lt;sup&gt;, &lt;q&gt;, &lt;button&gt;, &lt;cite&gt;</code></pre>
<ul>
<li>span 태그가 대표적</li>
<li>content,text 크기만큼 점유하고 동일 라인에 붙는 성질</li>
<li>width/height 적용불가</li>
<li>marin/padding-top/padding-bottom,float 적용 불가</li>
</ul>
<h1 id="2-block">2. block</h1>
<pre><code class="language-jsx">&lt;p&gt;, &lt;h1&gt;, &lt;h2&gt;, &lt;h3&gt;, &lt;h4&gt;, &lt;h5&gt;, &lt;h6&gt;, &lt;ul&gt;, &lt;ol&gt;, &lt;dl&gt;, &lt;pre&gt;, &lt;hr /&gt;, &lt;blockquote&gt;, an&lt;address&gt;</code></pre>
<ul>
<li>한줄을 점유</li>
</ul>
<h1 id="3-inline-block">3. inline-block</h1>
<ul>
<li><p>inline-block은 크기를 지정할수 있다.</p>
</li>
<li><p>가로 나열이고, 요소 사이에 여백이 있다.</p>
<ul>
<li><p>여백 해결방법은 margin-right: -4px</p>
</li>
<li><p>font-size: 0으로 해결</p>
<pre><code class="language-jsx">  &lt;style&gt;
      nav{
        font-size: 0;
      }
      nav a {

        width: 50px;
        height: 50px;
        border: 1px solid red;
        display:inline-block;
        font-size: 16px;
      }
      }
  &lt;/style&gt;

  &lt;nav&gt;
    &lt;a href=&quot;#&quot;&gt;One&lt;/a&gt;
    &lt;a href=&quot;#&quot;&gt;Two&lt;/a&gt;
    &lt;a href=&quot;#&quot;&gt;Three&lt;/a&gt;
  &lt;/nav&gt;</code></pre>
</li>
<li><p>flex 사용하자</p>
</li>
</ul>
</li>
</ul>
<h1 id="float">float</h1>
<ul>
<li>float 속성은 요소를 어떻게 띄울 것인지를 나타내는 것입니다. float 속성을 사용하면, 다른 요소들이 해당 요소 근처에 떠다니게 됩니다. float 속성을 사용해 이미지를 좌, 우로 정렬할 수도 있으며, 이를 활용해 웹페이지 레이아웃도 구성할 수 있습니다.</li>
<li>float: left, right, none, inherit 속성이 있다.</li>
</ul>
<pre><code class="language-jsx">div{
      width: 150px;
      height: 150px;
    }    

    .box-left{
      background-color: green;
       width: 150px;
      height: 150px;
      float: left;
    }

     .box-right{
      background-color: blue;
       float: right;
    }

&lt;div class=&quot;box-left&quot;&gt;박스1&lt;/div&gt;
  &lt;p&gt;
    &lt;span&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis eligendi libero sequi veniam eius, eveniet recusandae saepe porro earum consequuntur. Ullam nesciunt, commodi fugiat sed voluptatem, consequuntur unde rerum atque.&lt;/span&gt;
    &lt;span&gt;Laborum maiores, rerum. Officiis a doloribus quasi quam. Culpa fugiat itaque dolor impedit nostrum velit aliquam ducimus quidem dolorem odit numquam non architecto dicta quos quasi, suscipit ea, explicabo perferendis.&lt;/span&gt;
    &lt;span&gt;Beatae sed optio explicabo ducimus, consequatur id delectus temporibus quas quis excepturi nesciunt veniam ipsa amet iste quam inventore at accusantium minima recusandae doloribus odio placeat, numquam facere? Molestias, modi!&lt;/span&gt;
    &lt;span&gt;Quam dolor ex quibusdam, quis incidunt excepturi voluptatem fugiat unde sapiente facere veniam accusamus doloribus non dicta numquam dolores impedit error, molestias omnis! Non sint, perspiciatis nesciunt eveniet illo a.&lt;/span&gt;
  &lt;/p&gt;
  &lt;div class=&quot;box-right&quot;&gt;박스2&lt;/div&gt;</code></pre>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/85b3726b-852f-4999-a0b6-f66cafeccc2c/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2012.00.36.png" alt=""></p>
<ul>
<li>float을 주면, 높이가 사라지면서 원하는 layout이 안 생기는 경우가 있다.</li>
</ul>
<h1 id="clear로-해결">clear로 해결</h1>
<pre><code class="language-jsx">// ...위의 코드와 동일
//p에 clear를 주면 된다. 
p{
      clear:both;
    }
</code></pre>
<p><img src="https://images.velog.io/images/alicia-mkkim/post/28bc0902-e9c8-4071-8576-01d3d0f179f8/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-16%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2012.06.09.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[# TIL - semantic web과 semantic tag]]></title>
            <link>https://velog.io/@alicia-mkkim/TIL-semantic-web%EA%B3%BC-semantic-tag</link>
            <guid>https://velog.io/@alicia-mkkim/TIL-semantic-web%EA%B3%BC-semantic-tag</guid>
            <pubDate>Tue, 15 Feb 2022 14:50:25 GMT</pubDate>
            <description><![CDATA[<h1 id="assignment">Assignment</h1>
<blockquote>
<p>&quot;사이트에 이미지를 넣는 방법은 두 가지가 있습니다. <img> 태그를 사용하는 것과 <div> 태그에 background-image 속성을 추가하는 것. 두 가지 방법의 차이점과 각각 어떠한 경우에 사용하면 좋은지 설명해보세요.&quot;</p>
</blockquote>
<h1 id="1semantic-web">1.Semantic Web</h1>
<h2 id="11-semantic-web-이란">1.1 semantic web 이란?</h2>
<p>Semantic Web은 ‘의미론적 웹’이란 뜻으로, 기계가 이해할 수 있는 형태로 제작된 웹을 의미한다. 웹에 존재하는 수많은 웹들의 메타데이터를 부여하여, “의미”와 “관련성”을 가진 거대한 데이터베이스를 구축하고자 하는 발상이다.</p>
<ul>
<li>before semantic web</li>
</ul>
<pre><code class="language-jsx">&lt;div id=&quot;header&quot;&gt;&lt;/div&gt;</code></pre>
<ul>
<li>after semantic web</li>
</ul>
<pre><code class="language-jsx">&lt;header&gt;&lt;/header&gt;</code></pre>
<h1 id="2semantic-tag">2.Semantic tag</h1>
<h2 id="21-semantic-tag란">2.1 semantic tag란?</h2>
<p>시멘틴 태그는 의미가 있는 태그란 뜻이다. HTML 태그를 통해 웹 문서를 작성할 때 좀 더 의미 있는 태그를 사용함으로써 정확하게 정보를 전달하고 웹 문서의 구조를 쉽게 파악할 수 있도록 합니다. 또한, 검색 엔진은 웹 사이트의 HTML 태그들을 분석하여 사용자가 원하는 정보를 노출시키기 때문에 시맨틱 마크업은 중요합니다.
<img src="https://images.velog.io/images/alicia-mkkim/post/7ca40353-e55b-4cad-9494-fbfe8c943e46/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.48.22.png" alt="">
<a href="https://www.w3schools.com/html/html5_semantic_elements.asp">www3schools</a></p>
<h1 id="3-img-vs-background-img">3. img vs background-img</h1>
<ul>
<li>img tag는 의미가 있는 semantic tag로써 컴퓨터가 이해하고, alt(alternative) 속성으로 에러 발생시, 이미지가 깨져도, 어떤 이미지인지 알 수 있도록 해준다. 반면 background-image는 의미있는 semantic tag가 아니며, 에러 발생시 어떠한 정보도 받아볼 수 없다.</li>
<li>img tag를 사용할 경우, 검색엔진에 의해 웹이 잘 노출된다. 반면 웹 디자인 같은 이미지를 보여주기 위해서는 background-image를 사용하는게 좋다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL #5 변수,호이스팅,TDZ]]></title>
            <link>https://velog.io/@alicia-mkkim/TIL-5-%EB%B3%80%EC%88%98%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85TDZ</link>
            <guid>https://velog.io/@alicia-mkkim/TIL-5-%EB%B3%80%EC%88%98%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85TDZ</guid>
            <pubDate>Wed, 26 Jan 2022 13:56:08 GMT</pubDate>
            <description><![CDATA[<p><strong>keyword</strong> </p>
<ul>
<li>variables</li>
<li>hoisting</li>
<li>TDZ</li>
</ul>
<p><strong>lecture</strong></p>
<ul>
<li>youtube - 코딩앙마</li>
</ul>
<p>var는 한번 선언된 변수를 다시 선언할 수 있다.  반면 let는 한번 선언된 변수는 다시 선언할 수 없다. </p>
<pre><code class="language-jsx">var name = &quot;Mike&quot;;
console.log(name);
var name = &#39;Jane&#39;</code></pre>
<pre><code class="language-jsx">let name = &quot;Mike&quot;;
console.log(name); // Mike
let name = &#39;Jane&#39; // error</code></pre>
<p>var는 선언하기 전에 사용할 수 있다.  선언만 Hoisting 되고, 할당은 hoisting 되지 않는다. </p>
<p>호이스팅: 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것 처럼 행동! </p>
<pre><code class="language-jsx">console.log(name) //undefined
var name; 
name = &#39;Mike&#39;</code></pre>
<p>let 같은 경우 , error가 나온다. 그렇다면 let은 hositing이 되지 않는 걸까? </p>
<pre><code class="language-jsx">
console.log(name);// ReferenceError: Cannot access &#39;name&#39; before initialization
let name = &#39;Mike&#39;</code></pre>
<p>왜냐하면, let과 const는 TDZ (Temporal Dead Zone)의 영향을 받기 때문이다. </p>
<p>코드를 좀 더 예측가능하게 하고, 오류를 줄일 수 있다. </p>
<pre><code class="language-jsx">console.log(name); // 사용 불가 
const name = &#39;Mike&#39; // 함수 선언 및 할당
console.log(name) //사용 가능 </code></pre>
<pre><code class="language-jsx">let age = 30; 
function isAdult(){
  console.log(age); //erorr 발생 TDZ 이기 때문 
  let age = 20; 
}
isAdult();</code></pre>
<p><strong>변수 생성과정</strong> </p>
<p>var </p>
<ol>
<li>선언 및 초기화 단계 (함께 일어남)<ul>
<li>let name; //값을 할당 안해도 초기값이 undefined 설정되어있다.</li>
</ul>
</li>
<li>할당 단계 </li>
</ol>
<p>let </p>
<ol>
<li>선언 단계 </li>
<li>초기화 단계 (선언과 초기화 단계가 따로 일어남. 실제 코드에 도달 했을 때 발생)</li>
<li>할당 단계</li>
</ol>
<p>const</p>
<ol>
<li>선언 + 초기화  + 할당 </li>
</ol>
<p>스코프</p>
<p>var </p>
<p>: 함수 스코프 (function scoped)</p>
<p>let,const</p>
<p>: 블록 스코프  (block-scoped)</p>
<p>함수, if문,  for문, while 문, try/catch 문 </p>
<pre><code class="language-jsx">function add(){
    //block-level scope
}
if(){
    //block-level scope
}
for(let i = 0 ; i &lt; 10 ; i++){
    //block-level scope
}</code></pre>
<pre><code class="language-jsx">const age = 30; 
if(age&gt; 19){
  var txt = &#39;성인입니다.&#39;
}

console.log(txt); //&#39;성인입니다&#39;

//if문 안에 있는 var는 밖에서 부를 수 있다. let과 const는 안된다. </code></pre>
<pre><code class="language-jsx">function add(num1,num2){
  var result = num1 + num2;

}

add(2,3);

console.log(result) // error

//다만 함수안에서 var는 예외다. 함수 밖에서 부를 수 없다. </code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL - #5 배열, 반복문]]></title>
            <link>https://velog.io/@alicia-mkkim/%EB%B0%B0%EC%97%B4-%EB%B0%98%EB%B3%B5%EB%AC%B8</link>
            <guid>https://velog.io/@alicia-mkkim/%EB%B0%B0%EC%97%B4-%EB%B0%98%EB%B3%B5%EB%AC%B8</guid>
            <pubDate>Mon, 24 Jan 2022 14:13:19 GMT</pubDate>
            <description><![CDATA[<h1 id="array">Array</h1>
<p><strong>배열이란?</strong> 관련 있는 데이터를 하나의 변수에 할당 여 관리하기 위해 사용되는 데이터 타입</p>
<h1 id="array가-필요한-이유">Array가 필요한 이유</h1>
<p>배열이 필요한 </p>
<ul>
<li>단일 데이터(Single data)가 아닌 다수의 데이터(Multiple data) 저장</li>
<li>연관있는 데이터를 함께 변수에 저장하므로 데이터를 찾는데 용이</li>
</ul>
<h1 id="array-선언">Array 선언</h1>
<pre><code class="language-jsx">let name = [&#39;Jane&#39;,&#39;Mike&#39;,&#39;David&#39;,&#39;Alice&#39;];

//[]안에 들어간 데이터는 element라고 부른다.</code></pre>
<h1 id="array의-값을-추가삭제하는-방법">Array의 값을 추가,삭제하는 방법</h1>
<ul>
<li>push()</li>
<li>unshift()</li>
<li>pop()</li>
<li>shift()</li>
</ul>
<h2 id="push">push()</h2>
<ul>
<li><strong>push()</strong>: add items to the end of an array</li>
</ul>
<pre><code class="language-jsx">let students = [&#39;June&#39;,&#39;Willy&#39;,&#39;Anne&#39;];
console.log(students); // [&quot;June&quot;, &quot;Willy&quot;, &quot;Anne&quot;]
students.push(&#39;George&#39;);
console.log(students); //[&quot;June&quot;, &quot;Willy&quot;, &quot;Anne&quot;, &quot;George&quot;]</code></pre>
<h2 id="unshift">unshift()</h2>
<ul>
<li><strong>unshift()</strong>: Add items to the beginning of an array</li>
</ul>
<pre><code class="language-jsx">let students = [&#39;June&#39;,&#39;Willy&#39;,&#39;Anne&#39;];
console.log(students); //[&quot;June&quot;, &quot;Willy&quot;, &quot;Anne&quot;]
students.unshift(&#39;George&#39;);
console.log(students);[&quot;George&quot;, &quot;June&quot;, &quot;Willy&quot;, &quot;Anne&quot;]</code></pre>
<h2 id="pop">pop()</h2>
<ul>
<li><strong>pop()</strong>: Remove an item from the end of an array</li>
</ul>
<pre><code class="language-jsx">let students = [&#39;June&#39;,&#39;Willy&#39;,&#39;Anne&#39;];
console.log(students); //[&#39;June&#39;,&#39;Willy&#39;,&#39;Anne&#39;]
students.pop();
console.log(students); [&#39;June&#39;,&#39;Willy&#39;]</code></pre>
<h2 id="shift">shift()</h2>
<ul>
<li><strong>shift() :</strong> Add items to the beginning of an array</li>
</ul>
<pre><code class="language-jsx">let students = [&#39;June&#39;,&#39;Willy&#39;,&#39;Anne&#39;];
console.log(students); //[&quot;June&quot;, &quot;Willy&quot;, &quot;Anne&quot;]
students.shift();
console.log(students); //[&quot;Willy&quot;, &quot;Anne&quot;]</code></pre>
<h1 id="반복문이-필요한-이유와-사용하는-방법">반복문이 필요한 이유와 사용하는 방법</h1>
<ul>
<li>반복되는 작업을 수행하기 위해 필요</li>
</ul>
<h2 id="for">for</h2>
<pre><code class="language-jsx">for(초기문; 조건문; 증감식){

//반복할 코드 작성하는 부분 

}</code></pre>
<pre><code class="language-jsx">let result = 0;

for(let i = 0; i &lt; 10 ; i++){
        result += i;

}

console.log(result);</code></pre>
<blockquote>
<p>초기화문</p>
</blockquote>
<ul>
<li>초기화문 작성 시 변수 선언자를 써주어야 합니다.</li>
<li>변수명은 보통 index를 의미하는 i로 선언합니다.</li>
<li>index가 증가할 경우 숫자는 보통 0부터 시작합니다.</li>
</ul>
<blockquote>
<p>조건문</p>
</blockquote>
<ul>
<li>index의 범위를 설정합니다.</li>
<li>index가 증가할 경우 특정한 숫자 미만 혹은 이하로 설정합니다.</li>
<li>index가 감소할 경우 0 이상으로 설정합니다.</li>
<li>조건문이 true일 경우 반복문을 계속 실행합니다.</li>
<li>조건문이 false일 경우 반복문이 종료됩니다.</li>
</ul>
<blockquote>
<p>증감식</p>
</blockquote>
<ul>
<li>index가 1씩 증가할 경우 ++을 써줍니다.(index의 숫자가 하나씩 증가)</li>
<li>index가 1씩 감소할 경우 --를 써줍니다.(index의 숫자가 하나씩 감소)</li>
<li>i++은 i = i+1 을 줄여서 쓴 것입니다. i += 1 로 표현할 수도 있습니다.</li>
<li>i++는 ++1로 표현할 수 있습니다.</li>
</ul>
<h1 id="배열과-반복문을-함께-자주-사용하는-이유">배열과 반복문을 함께 자주 사용하는 이유</h1>
<p>반복문은 동일한 명령을 정해진 횟수만큼 반복하여 수행하도록 제어하는 명령문으로 구문(syntax)에는 주로 변수 증감을 위한 명령을 많이 사용하는데, 배열의 index가 해당 역할을 수행하기에 적합하기 때문에 배열과 반복문은 자주 함께 쓰인다.</p>
<h1 id="배열의-메서드-5가지와-사용-방법">배열의 메서드 5가지와 사용 방법</h1>
<p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array">Array - JavaScript | MDN</a></p>
<p><strong><code>concat()</code></strong> 메서드는 인자로 주어진 배열이나 값들을 기존 배열에 합쳐서 새 배열을 반환합니다.</p>
<pre><code class="language-jsx">const array1 = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];
const array2 = [&#39;d&#39;, &#39;e&#39;, &#39;f&#39;];
const array3 = array1.concat(array2);

console.log(array3);
// expected output: Array [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;, &quot;e&quot;, &quot;f&quot;]</code></pre>
<p><strong><code>slice()</code></strong> 메서드는 어떤 배열의 <code>begin</code>부터 <code>end</code>까지(<code>end</code> 미포함)에 대한 얕은 복사본을 새로운 배열 객체로 반환합니다. 원본 배열은 바뀌지 않습니다</p>
<ul>
<li>slice 메서드는 배열 내의 특정한 요소의 index 범위에 따라 새로운 배열을 리턴합니다.</li>
<li>splice 메서드와는 다르게 slice 메서드는 원본 배열을 변형시키지 않습니다.</li>
<li>그렇기 때문에 이 메서드를 사용할 때는 slice 메서드를 적용한 새로운 변수를 선언해주어야 합니다.</li>
</ul>
<pre><code class="language-jsx">const findFruits = () =&gt; {
  let foodBox = [&#39;🍕&#39;, &#39;🍤&#39;,&#39;🍇&#39; ,&#39;🥝&#39;,&#39;🍒&#39;,&#39;🍉&#39;,&#39;🍗&#39;, &#39;🍟&#39; ];

  let new_foodBox = foodBox.slice(2,6);
  console.log(new_foodBox);

  return new_foodBox

}

findFruits();</code></pre>
<p><strong><code>filter()</code></strong> 메서드는 array 관련 메서드로 조건에 맞는 요소들만 모아서 새로운 배열을 반환합니다.</p>
<pre><code class="language-jsx">let numbers = [10, 4, 32, 17, 5, 2]

let result = numbers.filter((value) =&gt; value &gt; 10);
console.log(result); // [32,17]</code></pre>
]]></description>
        </item>
    </channel>
</rss>