<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>juyh_yung5.log</title>
        <link>https://velog.io/</link>
        <description>곧 개발자</description>
        <lastBuildDate>Fri, 14 Apr 2023 04:08:54 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>juyh_yung5.log</title>
            <url>https://images.velog.io/images/juyh_yung5/profile/f5311a31-9a5e-460c-ba81-8a88256a2b14/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. juyh_yung5.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/juyh_yung5" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[disney-plus 클론 오류 해결]]></title>
            <link>https://velog.io/@juyh_yung5/disney-plus-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0</link>
            <guid>https://velog.io/@juyh_yung5/disney-plus-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0</guid>
            <pubDate>Fri, 14 Apr 2023 04:08:54 GMT</pubDate>
            <description><![CDATA[<p>강의를 두 번이나 듣는 고생스러움을 하며 디즈니 플러스 웹사이트를 완성했다.
첫 번째 시도에서는 레파지토리에 업로드가 안되는 오류를 만났었는데,
이번에는 어렵지 않게 해냈다. 물론 오류가 없던 것은 아니다.</p>
<p>강의의 오류라고 할 수 있는데, 네브 바에서 인풋 창에 영화 검색을 하면  search 페이지로 넘어가는데 (한 글자를 치면 바로 넘어간다.)</p>
<p>문제 1. 인풋 창 포커스가 사라진다.
문제 2. 처음 쳤던 글자가 인풋 창에 뜨지 않고 url에는 남으나, 다시 인풋 창을 클릭한 후 뒤이어 다른 글자를 치면 url에도 남지 않게 된다.</p>
<p>문제점을 살펴보면,
문제 2. 네브 바의 인풋 창에 입력한 데이터가 (이 때 페이지는 메인 페이지)
search 페이지로 전달되지 못하는 것이다.
문제 1. 페이지가 넘어가면서 페이지가 다시 랜더 되며 인풋 창에 포커스가 되지 않는 것이다. 이것도 이전 페이지에서 데이터와 함께 인풋 창이 포커스 되어 있음이 전달되지 않은 것이다.</p>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/ff0a20b1-5787-47d9-997e-4ddc4c980a35/image.png" alt=""></p>
<p>우선 인풋 창에 onChange에 들어갈 함수로 handleChange가 있는데, navigate(<code>const navigate = useNavigate();</code>) 의 두 번째 인자로 props, 함수, state 등 데이터를 전달할 수 있음을 알게 되었다. state를 통해 value를 전달할 수 있게 코드를 짰다.</p>
<p>그리고 useLocation을 사용하여 <strong>state를 담는</strong> 변수를 하나 만들고</p>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/5c550856-73d6-4666-8ad2-49e00ea4a470/image.png" alt=""></p>
<p>인풋 창에 영화를 검색한 후 console에 location을 찍어보면,
<img src="https://velog.velcdn.com/images/juyh_yung5/post/33967765-9888-4555-8c14-b531cfb20551/image.png" alt=""></p>
<p>이렇게 value가 담아져 있는 것을 볼 수 있다.</p>
<p>이제 메인 페이지의 네브 바에서 search 페이지로 입력한 글자를 넘겨주기 위해
만들어 둔 <code>searchValue</code>에 담아서 넘겨주고, ==&gt; 문제 2
useRef 함수와 focus() 메서드를 사용하여 인풋 창이 계속 포커스 되게 하면 문제가 해결 된다. ==&gt; 문제 1</p>
<p>useRef 함수는 current 속성을 가지고 있는 객체를 반환하는데 current를 사용하기 위해 inputRef라는 변수에 useRef 함수를 넣어주고 focus() 메서드를 사용하면 페이지가 다시 렌더 되어도 인풋 창은 계속 포커스가 되어 있다. =&gt; 문제 1 해결</p>
<p>인풋 창에 입력한 value가 담아있는 location은 useEffect를 사용해 만약 location이 truthy 값이면 searchValue state에 담아주기 위해 다음과 같이 코드를 작성해 준다.</p>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/818ca6e2-01d3-45a7-b648-38edb28498a1/image.png" alt=""></p>
<p>useEffect의 디펜던시로 location(<code>const location = useLocation().state;</code>)을 넣어 location이 변할 때 마다(인풋 창에 입력이 될 때마다) 렌더가 다시 되게 해 주었다. (search 페이지에서 useDebounce라는 훅을 만들어 한 글자 마다 리렌더가 되지 않게 해주었다.) =&gt; 문제 2 해결</p>
<blockquote>
<p>참고로 useEffect 대신 <code>useLayoutEffect</code>를 사용할 수도 있긴 하다.
둘을 비교하자면,
useEffect는 컴포넌트 들이 render와 paint 된 후에 비동기적으로 실행되고,
useLayoutEffect는 컴포넌트들이 render 된 후 실행되며, 그 이후에 paint가 동기적으로 실행된다. 
즉, useLayoutEffect는 동기적으로 실행되고 내부의 코드가 모두 실행된 후 painting 작업을 거친다. 따라서 로직이 복잡할 경우 사용자가 레이아웃을 보는데까지 시간이 오래걸린다는 단점이 있어, 기본적으로는 항상 useEffect 만을 사용하는 것을 권장한다고 한다.
만약 리렌더가 되며 화면이 깜빡거리는 이슈 발생 시 useLayoutEffect를 사용 할 수 있다.
(참고: <a href="https://medium.com/@jnso5072/react-useeffect-%EC%99%80-uselayouteffect-%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C-e1a13adf1cd5">https://medium.com/@jnso5072/react-useeffect-%EC%99%80-uselayouteffect-%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C-e1a13adf1cd5</a>)</p>
<blockquote>
<p>Render: DOM Tree 를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정
Paint: 실제 스크린에 Layout을 표시하고 업데이트하는 과정</p>
</blockquote>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[소인수분해]]></title>
            <link>https://velog.io/@juyh_yung5/%EC%86%8C%EC%9D%B8%EC%88%98%EB%B6%84%ED%95%B4</link>
            <guid>https://velog.io/@juyh_yung5/%EC%86%8C%EC%9D%B8%EC%88%98%EB%B6%84%ED%95%B4</guid>
            <pubDate>Mon, 06 Mar 2023 18:47:46 GMT</pubDate>
            <description><![CDATA[<p>소인수분해</p>
<pre><code class="language-js">function solution(n) {
    const arr = [];
    let idx = 2;

    while(n !== 1) {
        if(n % idx === 0) {
            arr.push(idx);
            n /= idx;
        } else {
            idx += 1;
        }
    }
    return arr 
    // return Array.from(new Set(arr)) 중복 제거
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[+ 단항 연산자]]></title>
            <link>https://velog.io/@juyh_yung5/%EB%8B%A8%ED%95%AD-%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@juyh_yung5/%EB%8B%A8%ED%95%AD-%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Tue, 14 Feb 2023 17:54:01 GMT</pubDate>
            <description><![CDATA[<p>숫자 타입이 아닌 피연산자에 + 단항 연산자를 사용하면 피연산자를 숫자 타입으로 변환하여 반환한다.</p>
<pre><code class="language-js">x = true;
console.log(+x); // 1

y = false;
console.log(+y); // 0</code></pre>
<ul>
<li>딥다이브 77쪽 참고</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[shift, unshift, pop, splice, slice, Array.from]]></title>
            <link>https://velog.io/@juyh_yung5/shift-unshift-pop-splice-slice-%EB%A9%94%EC%84%9C%EB%93%9C</link>
            <guid>https://velog.io/@juyh_yung5/shift-unshift-pop-splice-slice-%EB%A9%94%EC%84%9C%EB%93%9C</guid>
            <pubDate>Mon, 13 Feb 2023 09:54:40 GMT</pubDate>
            <description><![CDATA[<ul>
<li>shift</li>
<li>unshift</li>
<li>pop</li>
<li>splice</li>
<li>slice</li>
<li>Array.from</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[ 주어진 값의 소수부분을 제거하고 숫자의 정수부분을 반환하는 메서드]]></title>
            <link>https://velog.io/@juyh_yung5/%EC%A3%BC%EC%96%B4%EC%A7%84-%EA%B0%92%EC%9D%98-%EC%86%8C%EC%88%98%EB%B6%80%EB%B6%84%EC%9D%84-%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B3%A0-%EC%88%AB%EC%9E%90%EC%9D%98-%EC%A0%95%EC%88%98%EB%B6%80%EB%B6%84%EC%9D%84-%EB%B0%98%ED%99%98%ED%95%98%EB%8A%94-%EB%A9%94%EC%84%9C%EB%93%9C</link>
            <guid>https://velog.io/@juyh_yung5/%EC%A3%BC%EC%96%B4%EC%A7%84-%EA%B0%92%EC%9D%98-%EC%86%8C%EC%88%98%EB%B6%80%EB%B6%84%EC%9D%84-%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B3%A0-%EC%88%AB%EC%9E%90%EC%9D%98-%EC%A0%95%EC%88%98%EB%B6%80%EB%B6%84%EC%9D%84-%EB%B0%98%ED%99%98%ED%95%98%EB%8A%94-%EB%A9%94%EC%84%9C%EB%93%9C</guid>
            <pubDate>Wed, 08 Feb 2023 10:52:42 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/7bd4ec27-c66c-42b1-a56d-33a5c3b22e6e/image.png" alt=""></p>
<ul>
<li>위와 같은 문제(프로그래머스 - 두 수의 나눗셈)에서 <code>Math.floor()</code> 를 사용하여 답을 아래와 같이 작성하였다.<pre><code class="language-js">const solution = (num1, num2) =&gt; Math.floor(num1 / num2 * 1000)</code></pre>
</li>
</ul>
<hr>
<ul>
<li><code>Math.floor()</code> 대신 <code>Math.trunc()</code> 메서드를 사용하여 다음과 같이 답을 작성할 수도 있다.</li>
</ul>
<pre><code class="language-js">const solution = (num1, num2) =&gt; Math.trunc(num1 / num2 * 1000)</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[instanceof와 constructor]]></title>
            <link>https://velog.io/@juyh_yung5/instanceof%EC%99%80-contructor</link>
            <guid>https://velog.io/@juyh_yung5/instanceof%EC%99%80-contructor</guid>
            <pubDate>Sat, 28 Jan 2023 11:08:52 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-js">class A {
  constructor() {}
}

class B extends A {
  constructor() {
    super()
  }
}

class C extends B {
  constructor() {
    super()
  }
}

const a = new A()
const b = new B()
const c = new C()

console.log(a instanceof A); // true
console.log(a instanceof B); // false
console.log(a instanceof C); // false


console.log(b instanceof A); // true
console.log(b instanceof B); // true
console.log(b instanceof C); // false


console.log(c instanceof A); // true
console.log(c instanceof B); // true
console.log(c instanceof C); // true

// c라는 인스턴스가 어느 부분에서 만들어진 것인지 확인 하기 위해
// construct라는 속성을 일치 연산자를 통해서 비교하면 된다
console.log(c.constructor === A); // false
console.log(c.constructor === B); // false
console.log(c.constructor === C); // true


const fruits = [&#39;Apple&#39;, &#39;Banana&#39;];
console.log(fruits.constructor === Array); // true
console.log(fruits instanceof Array); // true
// fruits라는 데이터는 Array 클래스의 하나의 인스턴스가 된다는 뜻
// 아래도 같은 코드

const fruits = new Array(&#39;Apple&#39;, &#39;Banana&#39;);
console.log(fruits.constructor === Array); // true
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[정적 메서드 Static methods]]></title>
            <link>https://velog.io/@juyh_yung5/%EC%A0%95%EC%A0%81-%EB%A9%94%EC%84%9C%EB%93%9C-Static-methods</link>
            <guid>https://velog.io/@juyh_yung5/%EC%A0%95%EC%A0%81-%EB%A9%94%EC%84%9C%EB%93%9C-Static-methods</guid>
            <pubDate>Sat, 28 Jan 2023 10:34:20 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-js">class User {
  constructor(first, last) {
    this.firstName = first
    this.lastName = last
  }
  getFullName() {
    return `${this.firstName} ${this.lastName}`
  }
  static isUser() {
    return true
  }
}

const lisa = new User(&#39;Lisa&#39;, &#39;Oh&#39;);
const ju = new User(&#39;Ju&#39;, &#39;Oh&#39;);

console.log(lisa.getFullName()); // Lisa Oh
console.log(lisa.getFullName()); // Ju Oh
console.log(User.isUser()); // true
console.log(lisa.isUser()); // Uncaught TypeError</code></pre>
<ul>
<li>일반 메서드, 프로토타입 메서드는 기본적으로 인스턴스에서 사용하는 메서드</li>
<li>static 키워드가 붙어있는 정적 메서드는  인스턴스에서는 사용할 수 없고, class 자체에서 사용해야한다</li>
</ul>
<hr>
<ul>
<li>정적 메서드 사용 예시<pre><code class="language-js">class User {
constructor(first, last) {
  this.firstName = first
  this.lastName = last
}
getFullName() {
  return `${this.firstName} ${this.lastName}`
}
static isUser(user) {
  if (user.firstName &amp;&amp; user.lastName) {
    return true
}
  return false
}
</code></pre>
</li>
</ul>
<p>const lisa = new User(&#39;Lisa&#39;, &#39;Oh&#39;);
const ju = new User(&#39;Ju&#39;, &#39;Oh&#39;);
const kevin = {
  name: &#39;Kevin Kim&#39;,
  age: 56
}</p>
<p>console.log(User.isUser(lisa)); // true
console.log(User.isUser(ju)); // true
console.log(User.isUser(kevin)); // false
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Class 문법]]></title>
            <link>https://velog.io/@juyh_yung5/Class-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@juyh_yung5/Class-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Sat, 28 Jan 2023 05:27:02 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-js">// function User(first, last) {
//   this.firstName = first
//   this.lastName = last
// }

// User.prototype.getFullName = function () {
//   return `${this.firstName} ${this.lastName}`
// }

// 위의 prototype 방식을 ES6의 클래스 방식으로 옮겨 작성하기
class User {
  constructor(first, last) {
    this.firstName = first
    this.lastName = last 
  }
  getFullName() {
    return `${this.firstName} ${this.lastName}`
  }
}

// new라는 키워드와 함께 마치 함수처럼 호출을 해서 
// 인스턴스 결과를 통해(ju, lisa) 데이터를 활용할 수 있다
const ju = new User(&#39;Ju&#39;, &#39;Oh&#39;);
const lisa = new User(&#39;Lisa&#39;, &#39;Oh&#39;);


console.log(ju.getFullName()); // Ju Oh
console.log(lisa.getFullName()); // Lisa Oh</code></pre>
<ul>
<li>예시<pre><code class="language-js">class User {
constructor(first, last) {
  this.firstName = first
  this.lastName = last
  this.fullName = `${first} ${last}`
}
}
</code></pre>
</li>
</ul>
<p>const lisa = new User(&#39;Lisa&#39;, &#39;Oh&#39;);</p>
<p>console.log(lisa); // ‣ User {firstName: &#39;Lisa&#39;, lastName:&#39;Oh&#39;, fullName:&#39;Lisa Oh&#39;}</p>
<p>lisa.firstName = &#39;Ju&#39;;</p>
<p>console.log(lisa); // ‣ User {firstName: &#39;Ju&#39;, lastName:&#39;Oh&#39;, fullName:&#39;Lisa Oh&#39;}</p>
<p>// constructor에 fullName은 firstName과 lastName의 조합으로 만들어져야 하는데,
// new 라는 키워드를 통해 생성자 함수로 class를 호출할 때 최초로만 만들어지고
// 그 이후에 firstName과 lastName이 바뀌더라도 변화가 없는 상태가 되어져버린다
// 이것을 해결하기 위해 아래와 같이 하나의 매서드로 만들어서 코드 변경</p>
<p>class User {
  constructor(first, last) {
    this.firstName = first
    this.lastName = last
  }
  getFullName() {
    return <code>${this.firstName} ${this.lastName}</code>
  }
}</p>
<p>const lisa = new User(&#39;Lisa&#39;, &#39;Oh&#39;);</p>
<p>console.log(lisa.getFullName()); // Lisa Oh</p>
<p>lisa.firstName = &#39;Ju&#39;;</p>
<p>console.log(lisa.getFullName()); // Ju Oh</p>
<p>// 위 방식의 문제는 getFullName을 계속 호출해 주어야 한다는 것
// 그래서 Getter(값을 얻어내는 용도의 매서드) 사용</p>
<pre><code>
* getter와 setter 사용
```js
class User {
  constructor(first, last) {
    this.firstName = first
    this.lastName = last
  }
  get fullName() { // get, 메서드에 붙여서 사용 fullName이 getter
    return `${this.firstName} ${this.lastName}`
  }
  set fullName(value) { // fullName이라는 setter는 fullName이라는 속성에 값을 지정할 때 동작하는 메서드
    console.log(value);
    [this.firstName, this.lastName] = value.split(&#39; &#39;);
  }
}

const lisa = new User(&#39;Lisa&#39;, &#39;Oh&#39;);

console.log(lisa.fullName); // Lisa Oh

lisa.firstName = &#39;Ju&#39;;

console.log(lisa.fullName); // Ju Oh

lisa.fullName = &#39;Ju Park&#39; // 데이터를 할당하게 되면 setter의 메서드 실행
console.log(lisa); // ‣ User {firstName: &#39;Ju&#39;, lastName: &#39;Park&#39;}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[prototype]]></title>
            <link>https://velog.io/@juyh_yung5/prototype</link>
            <guid>https://velog.io/@juyh_yung5/prototype</guid>
            <pubDate>Sat, 28 Jan 2023 05:18:13 GMT</pubDate>
            <description><![CDATA[<ul>
<li>자바스크립트의 클래스 문법(ES6)은 prototype을 기반으로 구현 되어있다.</li>
</ul>
<pre><code class="language-js">function User(first, last) {
  this.firstName = first
  this.lastName = last
}

User.prototype.getFullName = function () {
  return `${this.firstName} ${this.lastName}`
}

const ju = new User(&#39;Ju&#39;, &#39;Oh&#39;);
const lisa = new User(&#39;Lisa&#39;, &#39;Oh&#39;);

console.log(ju); // ‣ User {firstName: &#39;Ju&#39;, lastName: &#39;Oh&#39;}
console.log(lisa); // ‣ User {firstName: &#39;Lisa&#39;, lastName: &#39;Oh&#39;}

// console에서 prototype 열어보면 getFullName이라는 함수가 들어가 있다.
// 이 함수는 User라는 함수의 prototype으로 등록이 된 메소드이고, (내부에 내장이 됨)
// User라는 생성자 함수에서 반환 된 인스턴스 객체(ju, lisa)에서는
//  언제든지 prototype에 등록이 되어 있는 메소드를 쓸 수 있다.

console.log(ju.getFullName()); // Ju Oh
console.log(lisa.getFullName()); // Lisa Oh</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[this]]></title>
            <link>https://velog.io/@juyh_yung5/this</link>
            <guid>https://velog.io/@juyh_yung5/this</guid>
            <pubDate>Fri, 27 Jan 2023 17:23:13 GMT</pubDate>
            <description><![CDATA[<ul>
<li>일반 함수의 this는 호출 위치에서 정의</li>
<li>화살표 함수의 this는 자신이 선언된 함수(렉시컬: 함수가 동작할 수 있는 유효한 범위) 범위에서 정의</li>
</ul>
<hr>
<ul>
<li><p>일반 함수 예제1</p>
<pre><code class="language-js">function user() {
this.firstName = &#39;Lisa&#39;
this.lastName = &#39;Oh&#39;

return {
  firstName: &#39;Ju&#39;,
  lastName: &#39;Oh&#39;,
  age: 93,
  getFullName: function () {
    return `${this.firstName} ${this.lastName}`
  }
}
}
</code></pre>
</li>
</ul>
<p>const u = user();</p>
<p>console.log(u.getFullName()); // Ju Oh</p>
<pre><code>* 일반 함수 예제2
```js
function user() {
  this.firstName = &#39;Lisa&#39;
  this.lastName = &#39;Oh&#39;

  return {
    firstName: &#39;Ju&#39;,
    lastName: &#39;Oh&#39;,
    age: 93,
    getFullName () { // 축약형으로 쓸 수 있다
      return `${this.firstName} ${this.lastName}`
    }
  }
}

const kevin = {
  fistName: &#39;Kevin&#39;,
  lastName: &#39;Kim&#39;
}

const u = user();

console.log(u.getFullName); // Ju Oh
console.log(u.getFullName.call(kevin)); // Kevin Kim</code></pre><ul>
<li><p>일반 함수 예제3</p>
<pre><code class="language-js">const timer = {
title: &#39;TIMER!&#39;,
timeout() { // 축약형으로 작성
  console.log(this.title); // TIMER!
  setTimeout(function () {
    console.log(this.title) // undefined
  }, 1000)
}
}
timer.timeout();</code></pre>
</li>
<li><p>화살표 함수 예제1</p>
<pre><code class="language-js">function user() {
this.firstName = &#39;Lisa&#39;
this.lastName = &#39;Oh&#39;

return {
  firstName: &#39;Ju&#39;,
  lastName: &#39;Oh&#39;,
  age: 93,
  getFullName: () =&gt; {
    return `${this.firstName} ${this.lastName}`
  }
}
}
</code></pre>
</li>
</ul>
<p>const u = user();</p>
<p>console.log(u.getFullName()); // Lisa Oh</p>
<pre><code>
* 화살표 함수 예제2
```js
const timer = {
  title: &#39;TIMER!&#39;,
  timeout() { // 축약형으로 작성
    console.log(this.title); // TIMER!
    setTimeout(() =&gt; { // 화살표 함수 적합. timeout 함수에서 this 찾음
      console.log(this.title); // (1초 뒤에) TIMER!
    }, 1000);
  }
}
timer.timeout();</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[재귀 함수]]></title>
            <link>https://velog.io/@juyh_yung5/%EC%9E%AC%EA%B7%80-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@juyh_yung5/%EC%9E%AC%EA%B7%80-%ED%95%A8%EC%88%98</guid>
            <pubDate>Fri, 27 Jan 2023 17:10:41 GMT</pubDate>
            <description><![CDATA[<p>Recursive</p>
<pre><code class="language-js">const userA = { name: &#39;A&#39;, parent: null }
const userB = { name: &#39;B&#39;, parent: userA }
const userC = { name: &#39;C&#39;, parent: userB }
const userD = { name: &#39;D&#39;, parent: userC }

const getRootUser = user =&gt; {
  if (user.parent) {
    return getRootUser(user.parent)
  }
  return user
}

console.log(getRootUser(userD)); // {name: &#39;A&#39;, parent: null}
console.log(getRootUser(userC)); // {name: &#39;A&#39;, parent: null}
console.log(getRootUser(userB)); // {name: &#39;A&#39;, parent: null}
console.log(getRootUser(userA)); // {name: &#39;A&#39;, parent: null}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Callback]]></title>
            <link>https://velog.io/@juyh_yung5/Callback</link>
            <guid>https://velog.io/@juyh_yung5/Callback</guid>
            <pubDate>Fri, 27 Jan 2023 16:58:06 GMT</pubDate>
            <description><![CDATA[<ul>
<li>예제 1<pre><code class="language-js">const a = callback =&gt; {
callback();
console.log(&#39;A&#39;);
}
const b = () =&gt; {
console.log(&#39;B&#39;);
}
</code></pre>
</li>
</ul>
<p>a(b);
// a 함수가 호출될 때 b 라는 함수 데이터가 인수로 들어가게 되고, 이 때 b를 콜백함수라고 부른다.</p>
<p>// console에는 B 그리고 A가 찍힌다.</p>
<pre><code>
* 예제 2
```js
const sum = (a, b, c) =&gt; {
  setTimeout(() =&gt; {
    c(a + b)
  }, 1000)
}

sum (1, 2, value =&gt; {
  console.log(value); // 3
})

sum (3, 7, value =&gt; {
  console.log(value); // 10
})</code></pre><ul>
<li>예제 3
이미지 로딩 되는 시간</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[IIFE]]></title>
            <link>https://velog.io/@juyh_yung5/IIFE</link>
            <guid>https://velog.io/@juyh_yung5/IIFE</guid>
            <pubDate>Fri, 27 Jan 2023 16:42:46 GMT</pubDate>
            <description><![CDATA[<p>즉시실행함수 Immediately-Invoked Function Expression</p>
<pre><code class="language-js">((a,b) =&gt; {
  console.log(a.innerWidth);
  console.log(b.body);
})(window, document); // 333 body</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[While, Do while 반복문]]></title>
            <link>https://velog.io/@juyh_yung5/While-Do-while-%EB%B0%98%EB%B3%B5%EB%AC%B8</link>
            <guid>https://velog.io/@juyh_yung5/While-Do-while-%EB%B0%98%EB%B3%B5%EB%AC%B8</guid>
            <pubDate>Wed, 25 Jan 2023 10:53:49 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p>while 문 작성 시 언제 조건이 거짓이 될 수 있는지가 명확해야 한다.</p>
</li>
<li><p>while 문은 계속 반복이 되고(무한 반복), 조건이 거짓일 경우에 멈출 수 있다.</p>
</li>
<li><p>do while 반복문</p>
</li>
</ul>
<pre><code class="language-js">let n = 0;

while (n) {
  console.log(n); //
}
// 조건이 거짓이므로(n = 0) 아무 것도 실행하지 않는다.

do {
  console.log(n); // 0
} while (n)
// do 중괄호 부분의 코드를 먼저 실행한다.
// 이후에 while 안의 조건으로 갔을 때 0(falsy)이므로 do 부분의 중괄호를 다시 실행하지 않는다.
// 조건이 거짓이어도 최초 한 번은 실행한다.

do {
  console.log(n); // 0 1 2 3
  n++
} while (n &lt; 4)
</code></pre>
<ul>
<li><p>일반적인 반복은 while 문을 사용하면 되고, 조건에 상관 없이 최초 한 번 코드 실행이 필요하면 do while 문을 사용하면 된다. </p>
</li>
<li><p>for 반복문은 배열 혹은 객체 데이터를 다루는데 특화 되어 있고, 그 외의 경우에는 취향에 따라 사용하면 된다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[for문 & continue, for of 문,  for in 문]]></title>
            <link>https://velog.io/@juyh_yung5/for%EB%AC%B8-continue-for-of-%EB%AC%B8-for-in-%EB%AC%B8</link>
            <guid>https://velog.io/@juyh_yung5/for%EB%AC%B8-continue-for-of-%EB%AC%B8-for-in-%EB%AC%B8</guid>
            <pubDate>Wed, 25 Jan 2023 08:18:19 GMT</pubDate>
            <description><![CDATA[<h2 id="for-문--continue">for 문 &amp; continue</h2>
<pre><code class="language-js">for (let i = 9; i &gt; -1; i--) {
  if (i % 2 === 0) {
    continue // 현재 반복을 종료하고 다음 반복으로 넘어간다.
  }
  console.log(i); // 9 7 5 3 1
}</code></pre>
<h2 id="for-of-반복문">for of 반복문</h2>
<pre><code class="language-js">for (const 변수 of 반복하고자 하는 &quot;배열&quot; 데이터) {
  // 실행될 코드
} </code></pre>
<ul>
<li>예제<pre><code class="language-js">const fruits = [&#39;Apple&#39;, &#39;Banana&#39;, &#39;Cherry&#39;]
</code></pre>
</li>
</ul>
<p>for (const fruit of fruits) {
  console.log(fruit) // Apple Banana Cherry
} </p>
<pre><code>
* 예제2
```js
const users = [
  {
    name: &#39;Ju&#39;,
    age: 22
  },
  {
    name: &#39;Neo&#39;,
    age: 45
  },
  {
    name: &#39;Lisa&#39;,
    age: 56
  }
]

for (let i = 0; i &lt;users.length; i++) {
  console.log(users[i]); // {name: &#39;Ju&#39;, age: 22} {name: &#39;Neo&#39;, age: 45} {name: &#39;Lisa&#39;, age: 56}
  console.log(users[i].name); // Ju Neo Lisa
}

for (const user of users) {
  console.log(user); // {name: &#39;Ju&#39;, age: 22} {name: &#39;Neo&#39;, age: 45} {name: &#39;Lisa&#39;, age: 56}
  console.log(user.name); // Ju Neo Lisa
}</code></pre><h2 id="for-in-문">for in 문</h2>
<pre><code class="language-js">for (const key in &quot;객체&quot; 데이터) {
  // 실행 될 코드
}

const user = {
  name: &#39;Lisa&#39;,
  age: 56,
  inValid: true,
  email: &#39;juuh.yung5@gmail.com&#39;
}


for (const key in user) {
  console.log(key); // name age isValid email
  console.log(user[key]); // Lisa 56 true juuh.yung5@gmail.com
}

console.log(user.name); // Lisa
console.log(user.age); //56
console.log(user[&#39;name&#39;]); // Lisa
// 대괄호 표기법의 장점은 대괄호 사이에 문자 데이터로 속성이 들어갈 수 있다.

// 객체 데이터는 속성이 순서를 갖지 않는다. 객체 데이터가 가지고 있는 속성 만큼 갯수만 반복이 된다.
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[switch 조건문]]></title>
            <link>https://velog.io/@juyh_yung5/switch-%EC%A1%B0%EA%B1%B4%EB%AC%B8</link>
            <guid>https://velog.io/@juyh_yung5/switch-%EC%A1%B0%EA%B1%B4%EB%AC%B8</guid>
            <pubDate>Wed, 25 Jan 2023 07:17:51 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-js">switch (조건) {
  case 값1:
    // 조건이 &#39;값1&#39;일 때 실행
    break
  case 값2:
    // 조건이 &#39;값2&#39;일 때 실행
    break
  default:
    // 조건이 &#39;값1&#39;도 &#39;값2&#39;도 아닐 때 실행
}</code></pre>
<ul>
<li><p>예제</p>
<pre><code class="language-js">function price(fruit) {
let p
switch (fruit) {
  case &#39;Apple&#39;:
    p = 1000
    break
  case &#39;Banana&#39;:
    p = 1500
    break
  case &#39;Cherry&#39;:
    p = 2000
    break
  default:
    p = 0
}

return p
}
</code></pre>
</li>
</ul>
<p>console.log(price(&#39;Apple&#39;)); // 1000
console.log(price(&#39;Banana&#39;)); // 1500
console.log(price(&#39;Cherry&#39;)); // 2000
console.log(price(&#39;Hello&#39;)); // 0</p>
<pre><code>

* 예제2 - break 삭제
```js
function price(fruit) {
  switch (fruit) {
    case &#39;Apple&#39;:
      return 1000
    case &#39;Banana&#39;:
      return 1500
    case &#39;Cherry&#39;:
      return 2000
    default:
      return 0
  }
}

console.log(price(&#39;Apple&#39;)); // 1000
console.log(price(&#39;Banana&#39;)); // 1500
console.log(price(&#39;Cherry&#39;)); // 2000
console.log(price(&#39;Hello&#39;)); // 0
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[JUST WE AIR - 위코드 2차 프로젝트]]></title>
            <link>https://velog.io/@juyh_yung5/JUST-WE-AIR-%EC%9C%84%EC%BD%94%EB%93%9C-2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@juyh_yung5/JUST-WE-AIR-%EC%9C%84%EC%BD%94%EB%93%9C-2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Sun, 18 Dec 2022 08:29:26 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>제주항공을 모티브로 비행 티켓 예약 가능이 가능한 항공사 사이트를 구현 해보았다.</p>
</blockquote>
<h2 id="1-프로젝트-개요">1. 프로젝트 개요</h2>
<h3 id="1-1-개발-인원-및-기간">1-1. 개발 인원 및 기간</h3>
<ul>
<li><p>개발 인원: 프론트엔드 3명, 백엔드 2명 </p>
<ul>
<li><p>프론트엔드</p>
<ul>
<li>오주형: 예약 페이지(시간 및 가격 선택), 예약 정보 기입 페이지 및 예약 확인 페이지 </li>
<li>남연우: 카카오톡 간편로그인, 회원가입, spinner 및 토스를 이용한 간편결제</li>
<li>천정환: 메인 페이지 (목적지 및 날짜선택), Nav, Footer</li>
</ul>
</li>
<li><p>백엔드</p>
<ul>
<li>이영서: DB 모델링, 소셜 로그인 및 회원가입API, 주문 내역 저장 및 조회 API, 결제정보 저장 API (토스), 티켓 정보 email 발송</li>
<li>지송현: DB 모델링, DB생성, 항공권 조회 API (필터 및 분류), 결제정보 저장 API (토스)</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>개발 기간: 2022.11.28 ~ 2022.12.09</li>
</ul>
<h3 id="1-2-제공하는-서비스">1-2. 제공하는 서비스</h3>
<ul>
<li>카카오톡 이용한 소셜 회원가입 및 로그인</li>
<li>날짜, 목적지 및 시간(가격) 선택하여 항공권 구매</li>
<li>토스 이용한 간편 결제</li>
</ul>
<h3 id="1-3-사용하는-기술-스택">1-3. 사용하는 기술 스택</h3>
<p><img src="https://velog.velcdn.com/images/sujeong_dev/post/d46cd72c-b2e6-421b-822d-5dd1bb88b45c/image.png" alt=""></p>
<hr>
<h2 id="2-팀원들과-협업">2. 팀원들과 협업</h2>
<h3 id="2-1-협업-방법">2-1. 협업 방법</h3>
<ul>
<li>Notion과 Trello를 사용하여 scrum, sprint 진행</li>
<li>GitBook과 Postman을 활용하여 API 및 mockdata형식 공유</li>
</ul>
<hr>
<h2 id="3-구현-사항">3. 구현 사항</h2>
<h3 id="3-1-소셜-회원가입-및-로그인">3-1. 소셜 회원가입 및 로그인</h3>
<p><img src="https://user-images.githubusercontent.com/98579539/208579825-034ecee7-8920-41cd-b363-089b7b16726c.gif" alt="회원가입 및 로그인"></p>
<ul>
<li>카카오API 사용하여 카카오 간편 로그인 구현.</li>
<li>회원가입 시 입력한 유저 정보는 access token에 저장 (뒤에 예약 확인 페이지에서 불러오게 된다.)</li>
</ul>
<hr>
<h3 id="3-2-메인-페이지">3-2. 메인 페이지</h3>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/1c9395da-c17b-4284-9cfd-c5285209e1df/image.jpeg" alt=""></p>
<ul>
<li>slick-carousel 라이브러리 사용하여 슬라이드 구현</li>
</ul>
<hr>
<h3 id="3-3-예약-도시-및-날짜-선택">3-3. 예약 도시 및 날짜 선택</h3>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/660cfa9a-c214-46b4-90e5-70614de21605/image.gif" alt=""></p>
<ul>
<li>datePicker 라이브러리 이용하여 항공권 예약할 날짜 선택 모달 창 구현</li>
</ul>
<hr>
<h3 id="span-stylebackgroundcolorpink-fontsize36px3-4-비행편-선택span"><span style="backgroundColor:pink; fontSize:36px;">3-4. 비행편 선택</span></h3>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/4ff5bcf4-c2e4-4e5b-a1a4-cea928dd1c25/image.gif" alt=""></p>
<ul>
<li>이전 페이지인 메인페이지에서 선택한 도시와 날짜 정보가 넘어와서 예약 페이지 상단의 날짜들과 날짜에 따라 달라지는 비행편들이 보여진다.</li>
<li>fetch를 두 번 사용하는데, 첫 번째 fetch는 출발 날짜, 출발지 id 값, 도착지 id 값을 <code>useSearchParams()</code>를 통해 받아온다. 이 때 method(fetch의 두 번째 매개변수) 두 번째 fetch는 이 페이지(예약 페이지)에서 선택한 정보들을 다음 페이지인 booking-details 즉, 예약 확인 페이지로 정보를 넘기기 위해 사용한다. 두 번째 fetch에는 데이터를 담아 다음 페이지로 넘겨주어야 하기 때문에 <code>useNavigate</code>를 변수 navigate에 담고, navigate의 두 번째 매개변수로 데이터(여기서는 state들)를 담아준다. (물론 첫 번째 매개변수에는 이동할 페이지의 path를 적어준다.) 그래서 다음과 같은 코드가 완성된다.
<code>navigate(&#39;/booking-details&#39;, { state: { arrivalSeat, departureSeat } })</code></li>
</ul>
<hr>
<h2 id="span-stylebackgroundcolorpink-fontsize36px3-5-예약자-정보-기입span"><span style="backgroundColor:pink; fontSize:36px;">3-5. 예약자 정보 기입</span></h2>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/56eaf27b-d464-4ed7-8824-bd8335c1417b/image.gif" alt=""></p>
<ul>
<li><p>이 페이지를 만들면서 정규표현식에 대해 조금 더 자세히 알게 되었다. 우선 fetch를 통해 accessToken에 저장되어 있는 user info(회원가입 시 저장 됨)를 받고, 받은 user info 중 핸드폰 번호와 생년월일을 <code>replace()</code> 메서드와 정규표현식을 사용하여 하이픈을 넣을 수 있게 코드를 짜보았다. 다음과 같은 코드가 만들어진다. (useEffect 안에 함수를 넣어야 하나, getUserInfo 함수가 길어졌기에 아래와 같이 useEffect 안에 함수를 넣어준다.)</p>
<pre><code class="language-js">const getUserInfo = () =&gt; {
  fetch(&#39;http://10.58.52.240:3000/booking-details&#39;, {
    method: &#39;GET&#39;,
    headers: {
      &#39;Content-Type&#39;: &#39;application/json;charset=utf-8&#39;,
      authorization: localStorage.getItem(&#39;accessToken&#39;),
    },
  })
    .then(response =&gt; response.json())
    .then(data =&gt;
      setUserInfo({
        ...data,
        phoneNumber: data.phoneNumber
          .replace(/\D/g, &#39;&#39;)
          .replace(
            /(^02.{0}|^01.{1}|[0-9]{3})([0-9]+)([0-9]{4})/,
            &#39;$1-$2-$3&#39;
          ),
        birth: data.birth.replace(/(\d{4})(\d{2})(\d{2})/, &#39;$1-$2-$3&#39;),
      })
    );
};

useEffect(() =&gt; {
  getUserInfo();
}, []);</code></pre>
</li>
<li><p>다음 페이지인 예약 확인 페이지로 가기 위해서 역시 <code>useNavigate()</code>를 사용하였고, 두 번째 매개 변수로 아래와 같은 state를 담아 onClick 이벤트를 발생시켜서 다음 페이지로 넘겨주었다.</p>
<pre><code class="language-js">&lt;NextBtn
 onClick={() =&gt;
   navigate(&#39;/Booking-confirm&#39;, {
     state: { ...location.state, userInfo },
   })
 }
&gt;
 다음
&lt;/NextBtn&gt;</code></pre>
</li>
<li><p>객체 디스트럭처링 할당도 사용하였다. userInfo라는 state를 만들고, 초기값은 모두 <code>&quot;&quot;</code> 빈값으로 설정한다. userInfo 중 gender만 제외하고 userInfo에 디스트럭처링 할당을 해 주고, </p>
</li>
</ul>
<hr>
<h3 id="span-stylebackgroundcolorpink-fontsize36px3-6-예약-확인span"><span style="backgroundColor:pink; fontSize:36px;">3-6. 예약 확인</span></h3>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/82fde310-ef1b-4e93-b950-20eb4c621f10/image.gif" alt="">
*</p>
<hr>
<h3 id="3-7-항공권-토스-간편-결제">3-7. 항공권 토스 간편 결제</h3>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/f4c19d34-23a4-4734-9028-114cdcef808e/image.gif" alt=""></p>
<ul>
<li>토스 API 이용하여 간편 결제 구현</li>
</ul>
<hr>
<h3 id="3-8-항공권-메일-발송">3-8. 항공권 메일 발송</h3>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/84fc7678-96fd-4cf2-ab38-26fcacc1ce00/image.gif" alt=""></p>
<ul>
<li>백엔드 단에서 추가적으로 만든 페이지</li>
</ul>
<hr>
<h2 id="4-프로젝트-회고">4. 프로젝트 회고</h2>
<ul>
<li>지난 프로젝트에서 아쉬웠던 부분이었던 백엔드 단과의 소통이 이번 프로젝트에서는 원활하게 이루어졌다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[WCF - 위코드 1차 프로젝트 회고]]></title>
            <link>https://velog.io/@juyh_yung5/WCF-%EC%9C%84%EC%BD%94%EB%93%9C-1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@juyh_yung5/WCF-%EC%9C%84%EC%BD%94%EB%93%9C-1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Sun, 27 Nov 2022 12:05:18 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>삼성물산 패션부문의 통합 온라인몰 SSF샵을 모티브로 의류 소개 사이트를 구현 해보았다.</p>
</blockquote>
<h2 id="1-프로젝트-개요">1. 프로젝트 개요</h2>
<h3 id="1-1-개발-인원-및-기간">1-1. 개발 인원 및 기간</h3>
<ul>
<li><p>개발 인원: 프론트엔드 4명, 백엔드 2명 </p>
<ul>
<li><p>프론트엔드</p>
<ul>
<li>오주형: 회원가입, 로그인 및 장바구니 페이지</li>
<li>구수정: 상품 리스트 페이지</li>
<li>박문영: 상품 상세 페이지</li>
<li>정효원: navbar, footer 및 메인 페이지</li>
</ul>
</li>
<li><p>백엔드</p>
<ul>
<li>이영서: DB 모델링, 로그인•회원가입•상품 리스트 조회•상품 조회 API</li>
<li>박상욱: DB 모델링, 장바구니 API</li>
</ul>
</li>
</ul>
</li>
</ul>
<ul>
<li>개발 기간: 2022.11.14 ~ 2022.11.25<h3 id="1-2-제공하는-서비스">1-2. 제공하는 서비스</h3>
</li>
<li>회원가입 및 로그인</li>
<li>위코드 멘토님들 및 동기분들의 의류소개</li>
<li>카테고리 별 브랜드 검색 및 필터링</li>
<li>장바구니 <h3 id="1-3-사용하는-기술-스택">1-3. 사용하는 기술 스택</h3>
<img src="https://velog.velcdn.com/images/sujeong_dev/post/d46cd72c-b2e6-421b-822d-5dd1bb88b45c/image.png" alt=""></li>
</ul>
<hr>
<h2 id="2-팀원들과-협업">2. 팀원들과 협업</h2>
<h3 id="2-1-협업-방법">2-1. 협업 방법</h3>
<ul>
<li>Notion과 Trello를 사용하여 scrum, sprint 진행</li>
<li>GitBook과 Postman을 활용하여 API 및 mockdata형식 공유</li>
</ul>
<h3 id="2-2-협업-tools-및-개발-규칙">2-2. 협업 tools 및 개발 규칙</h3>
<ul>
<li><a href="https://github.com/wecode-bootcamp-korea/39-1st-WCF-frontend/wiki">위키</a> 참조</li>
</ul>
<hr>
<h2 id="3-구현-사항">3. 구현 사항</h2>
<h3 id="3-1-회원가입-및-로그인">3-1. 회원가입 및 로그인</h3>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/4ce625f3-c75a-4d33-9783-3c80991fa12a/image.gif" alt=""></p>
<ul>
<li>회원가입 시 아이디와 비밀번호, 그리고 비밀번호 확인에 조건을 걸어 놓았다. 조건에 충족 시 조건이 쓰여있는 글자들 색이 변한다.</li>
<li>회원가입 약관에 동의할 때 체크박스가 필요했다. 한번에 모두 체크가 될 수 있는 전체 체크도 가능해야하며, 개별 체크도 가능해야 했고, 또 개별 체크로 약관에 모두 동의하면 전체 체크도 체크 되어야했다. 체크 되어야할 항목들인 checkList state는 객체이기 때문에 (key가 아닌) value들만 배열로 만들어주기 위해 <code>onCheckedAll</code> 함수에 <code>valueArr</code> 변수를 만들어<code>Object.values(checkList)</code>를 사용하였다. 그리고 배열로 만들어진 체크 리스트들에 <code>Array.prototype.every()</code> 메서드를 사용하였다. <code>every()</code> 메서드는 배열 안의 모든 요소가 주어진 판별 함수를 통과하는지 테스트하며 Boolean 값을 반환한다. 결론적으로 아래와 같은 코드가 완성되었다.
<code>const valueArr = Object.values(checkList).every(el =&gt; el === true);</code></li>
<li>로그인 시 fetch 메서드를 사용하여 데이터를 전달하고 localStorage에 토큰을 저장했다.</li>
</ul>
<h3 id="3-2-장바구니">3-2. 장바구니</h3>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/b4c22757-6d83-4a4b-abc7-cc596f8d87b2/image.gif" alt=""></p>
<ul>
<li>백엔드와 통신 전, 활용할 목데이터를 만들어 장바구니 페이지를 구현해보았다.</li>
<li>Cart 컴포넌트에 CartFilled 컴포넌트와 CartEmpty 컴포넌트를 삼항연산자로 넣어 장바구니 페이지를 구현했다.</li>
<li>체크박스에 체크 된 리스트에 대해서 filter 메서드와 reduce 메서드를 사용하여 상품 총 가격을 만들어낼 수 있었다.</li>
<li>장바구니에 들어온 상품 리스트들에 대해 개별 삭제는 가능하나 체크박스에 체크된 리스트들에 대한 선택 삭제는 구현하지 못했다.</li>
</ul>
<hr>
<h2 id="4-프로젝트-회고">4. 프로젝트 회고</h2>
<ul>
<li><p>개발자로 첫 프로젝트를 진행해보았다. 동료들에게 배울 점이 매우 많았다. 특히 Trello, Notion 등의 툴을 가지고 2번의 planning meeting, 2주간 매일 진행했던 Daily Standup Meeting, 2번의 Retrospective Meeting을 하면서 계획 세우는 것을 두려워?했던 내가 점점 변하는 것을 느꼈다. 계획의 중요성을 알게 되며 방향을 잡고 나가는 것이 얼마나 중요한 것인지를 알 수 있게 되었다. 팀원 중 두 명이 특히 우리 팀을 이끌어주었는데, 그들이 없을 2차 프로젝트에서는 내가 배웠던 것 만큼 툴 사용과 계획적인 미팅들로 원만한 프로젝트가 진행 될 수 있도록 노력해야겠다고 생각했다.</p>
</li>
<li><p>아쉬웠던 것은 내가 맡은 페이지를 담당했던 백엔드분과의 소통이 잘 이루어지지 않았다는 점이다. 그분이 피치 못할 사정으로 재택근무를 하시게 되어서 더 그런 문제가 발생한 것 같은데, 개발자에게 재택 근무란 익숙하고 유연하게 대처해야할 일이라고 생각한다. 백엔드 쪽에서의 일이 어떻게 돌아가는지 대략적으로 알 수 있었으며, 내가 요구해야할 것은 제대로 분명하게 요구해야함에 대해 배울 수 있었다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[react -useEffect, CleanUp fn]]></title>
            <link>https://velog.io/@juyh_yung5/react-useEffect</link>
            <guid>https://velog.io/@juyh_yung5/react-useEffect</guid>
            <pubDate>Sun, 13 Nov 2022 14:01:54 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/68ee88b8-2699-49dd-b62f-6c5fa5332311/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/4323e998-a514-4918-8ed8-821a574804ca/image.png" alt=""></p>
<p>component가 없어질 때도 콘솔에 찍히게 하는 코드! useEffect에 return을 해준다. 이것을 CleanUp function이라 부른다. 그냥 function인데, component가 destroy될 때 뭔가 할 수 있도록 해준다. return 값으로 component가 언제 create 되었는지, 언제 destroy 되었는지 알 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/10cee865-51bb-4167-bc20-8577257b63d4/image.png" alt=""></p>
<p>두 개의 function을 만들고 hiFn에서 byeFn을 return 해준다.
useEffect는 function을 받고, 이 function은 dependency가 변화할 때 호출 된다. 이 경우 dependency가 비어있으니까 component가 처음 생성될 때 function이 호출된 후에 다시는 호출되지 않게 된다. 
component가 파괴될 때도 function을 실행하고 싶으면 hiFn이 byeFn을 return 해야한다.</p>
<p>useEffect는 우리가 코드를 언제 실행할지에 대한 선택권을 준다!
우리는 시작할 때만 code를 실행하게 할 수 있고,
무언가 변화할 때 code가 실행되도록 할 수 있으며,
component가 파괴될 때 code를 실행할 수 있게 할 수 있다. (-&gt; 별로 필요 없다.)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[grid]]></title>
            <link>https://velog.io/@juyh_yung5/grid</link>
            <guid>https://velog.io/@juyh_yung5/grid</guid>
            <pubDate>Sun, 13 Nov 2022 07:18:45 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-css">display: grid;
grid-template-columns: 40% 60%;
grid-template-columns: 4fr 6fr;
grid-template-columns: 1fr 1fr 1fr 1fr
grid-template-columns: repeat(4, 1fr)
/*200px 고정값이 된다. 1fr만 늘어난다.*/
grid-template-columns: 200px 1fr;
/*콘텐츠 높이와 상관 없이 row가 같아진다.*/
grid-auto-row: 200px;
/*200px로 설정했을 때 콘텐츠 때문에 박스가 작을 경우 minmax 이용. 최소한 200px씩 확보하고, 더 넘치는게 있다면 맞춰서 늘어나진다.*/
grid-auto-row: minmax(200px, auto);
grid-auto-row: minmax(10em, auto);
grid-gap: 1rem;
/*정렬하기. justify는 가로, align은 세로로 왔다 갔다 움직인다.*/
justify-items: start; / center; / end;
align-items: start; / center; / end;
/*개별적으로 움직일 때*/
justify-self: start; / center; / end;
align-self: start; / center; / end;</code></pre>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/4a696906-136a-4deb-b09f-183f99639d46/image.png" alt=""></p>
<p>1번을 3번까지 늘리게 하려면? ⬇️</p>
<pre><code class="language-css">/*1부터 4까지*/
.item:nth-child(1) {
    grid-column: 1/4</code></pre>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/58263275-7a78-49bf-a324-889912de71e5/image.png" alt=""></p>
<p>4를 7까지 늘리려면? ⬇️</p>
<pre><code class="language-css">.item:nth-child(4) {
    grid-row: 2/4;</code></pre>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/d25f999b-9d3d-4d3e-a09f-417e61e47a6b/image.png" alt=""></p>
<p>왼쪽으로 배치되었다. 오른쪽으로 가게 하려면? 4의 column 위치를 조정하면 된다.</p>
<pre><code class="language-css">.item:nth-child(4) {
    grid-column: 3;
    grid-row: 2/4;</code></pre>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/57e9f704-e94c-48cf-94a2-9e25aaa12679/image.png" alt=""></p>
<p>4번은 그대로 있고 9번을 위로 올린다면?</p>
<pre><code class="language-css">.item:nth-child(9) {
    grid-colum: 3; 
    grid-row: 3/5;</code></pre>
<p><img src="https://velog.velcdn.com/images/juyh_yung5/post/4a619569-d491-4162-9085-4fb7c596eb63/image.png" alt=""></p>
<p>(투명한 노란색과 붉은색이 합쳐져서 주황색이 됨!)</p>
]]></description>
        </item>
    </channel>
</rss>