<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>뒤박죽박 김동현</title>
        <link>https://velog.io/</link>
        <description>아자자자</description>
        <lastBuildDate>Tue, 19 Dec 2023 07:09:35 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>뒤박죽박 김동현</title>
            <url>https://velog.velcdn.com/images/_imhyunnn/profile/435249d7-7235-4083-8f2c-fd61bc8a4cea/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 뒤박죽박 김동현. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/_imhyunnn" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Type Script - 6]]></title>
            <link>https://velog.io/@_imhyunnn/Type-Script-6</link>
            <guid>https://velog.io/@_imhyunnn/Type-Script-6</guid>
            <pubDate>Tue, 19 Dec 2023 07:09:35 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>넓은 타입에서 좁은 타입으로 타입을 좁히는 과정에 대해 알아보자</p>
</blockquote>
<h2 id="타입-좁히기">타입 좁히기</h2>
<pre><code class="language-ts">function func1 (value: string | number) {
  value.toFixed();
  value.toUpperCase();
}</code></pre>
<p>위와 같은 함수가 있고 value의 타입은 <code>string</code>, <code>number</code> 로 되어있기에 해당 타입에 대한 메서드를 실행을 하면 오류를 발생한다.</p>
<ul>
<li>value는 <code>string</code>, <code>number</code>가 합쳐진 타입을 기대하는 반면 해당 메서드는 각각의 타입에서만 독립적으로 쓸 수 있는 메서드이기 때문이다
그렇기에 다음과 같이 조건문을 통해 타입을 좁혀서 사용을 할 수 있다.</li>
</ul>
<pre><code class="language-ts">function func1 (value: string | number) {
    if(typeof value == &quot;string&quot;) {
        value.toUpperCase();
    } else if (typeof value == &quot;number&quot;) {
        value.toFixed
    }
}</code></pre>
<ul>
<li>위와 같이 조건문을 이용해 조건문 내부에서 변수가 특정 타입임을 보장해주기에 이를 통해 타입이 좁혀질 수 있다.</li>
</ul>
<h3 id="instanceof">instanceof</h3>
<blockquote>
<p><code>instanceof</code>를 통해 내장 클래스 타입에 대한 타입 좁히기가 가능하다.</p>
</blockquote>
<pre><code class="language-ts">function func2(value: Date | null) {
    if(typeof value == &quot;object&quot;) {
        value.getTime();
    }
}</code></pre>
<p>위 코드는 오류를 발생을 한다 왜일까? 전 처럼 타입을 조건문을 통해 좁혔는데,,
value값을 보게 되면 <code>null</code>일 수 있기때문이다 그럼 이러한 내장 클래스에 대해선 어떻게 타입을 좁힐 수 있을까?</p>
<pre><code class="language-ts">function func2(value: Date | null) {
    if (value instanceof Date) {
        value.getTime();
  }
}</code></pre>
<ul>
<li><code>instanceof</code> 를 사용하면 내장 클래스의 타입을 보장할 수 있게 된다.</li>
<li><code>instanceof</code> 를 우리가 직접 만든 클래스에는 사용할 수 없다.</li>
</ul>
<h3 id="in-type-guard">in type guard</h3>
<blockquote>
<p>우리가 직접 만든 클래스에 타입을 보장 하려면 <code>in</code>을 사용하여 좁힐 수 있다.</p>
</blockquote>
<pre><code class="language-ts">type Glass = {
    name: string;
      color: string;
}

function func3(value: Glass | null) {
    if (value &amp;&amp; &quot;color&quot; in value) {
        console.log(value.name)
    }
}</code></pre>
<ul>
<li>위와 같이 value의 타입을 우리가 만든 타입에 대해 적용을 하고 싶다면 
value값이 존재하고 &amp;&amp; value값이 우리가 만든 타입안의 값이 있는지에 대한 여부를 검사한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Type Script - 5]]></title>
            <link>https://velog.io/@_imhyunnn/Type-Script-5</link>
            <guid>https://velog.io/@_imhyunnn/Type-Script-5</guid>
            <pubDate>Sun, 17 Dec 2023 12:50:12 GMT</pubDate>
            <description><![CDATA[<p>타입 단언에 대해서 알아보자</p>
<h2 id="타입-단언">타입 단언?</h2>
<blockquote>
<p>빈 객체에 어떠한 타입이라고 단언해주기</p>
</blockquote>
<p>어떠한 타입이 정의되어 있는 객체에서 그 객체를 초기화 한 상태는 빈 객체로 저장하고 싶을때 타입 스크립트는 다음과 같은 코드를 보고 오류를 발생시킨다.</p>
<pre><code class="language-ts">type Korea = {
    name: string;
      city: string;
}

let korea:Korea = {};

korea.name = &quot;대한민국&quot;;
korea.city = &quot;서울&quot;;</code></pre>
<ul>
<li>빈 객체로 타입이 추론 되기에 <code>name</code>, <code>city</code>에 접근을 할 수 없다. 그럼 어떻게 해야할까?</li>
<li><code>타입 단언</code> 을 통해 오류를 개선해보자</li>
</ul>
<pre><code class="language-ts">type Korea = {
    name: string;
      city: string;
}

let korea:Korea = {} as Korea;

korea.name = &quot;대한민국&quot;;
korea.city = &quot;서울&quot;;</code></pre>
<p>위와 같이 <code>값 as 타입</code> 을 통해 원하는 타입으로 단언을 할 수 있게 된다.</p>
<h3 id="타입-단언시-조건">타입 단언시 조건</h3>
<p><code>A as B</code>로 타입을 단언 했을 때 다음 조건을 만족해야한다.</p>
<ul>
<li>A가 B의 슈퍼타입</li>
<li>A가 B의 서브타입</li>
</ul>
<p>말이 뭔가 어려운데 그냥 이러한 타입일 것이다 라고 말하는 것이고, 즉 서로 관계가 없는 타입에 대한 단언만 하지 않게 되면 문제는 발생하지 않을 것이다.</p>
<h3 id="const-단언">const 단언</h3>
<blockquote>
<p>특정 값을 <code>const</code> 타입으로 단언하게 되면 변수를 const로 선언한 것과 빅슷하게 타입이 변경된다.</p>
</blockquote>
<pre><code class="language-ts">let apt = {
    name: &quot;자이&quot;,
      place: &quot;방배동&quot;,
} as const;
// 모든 프로퍼티가 readonly를 갖게 되며 그렇기에 값을 수정, 할당하는 행위는 불가하다.</code></pre>
<h3 id="non-null-단언">Non Null 단언</h3>
<blockquote>
<p>어떠한 값이 있을수도 있고 없을수도 있는 상황에서 이 값은 <code>undefined</code>, <code>null</code>이 아닐것이라고 단언할 수 있다.</p>
</blockquote>
<pre><code class="language-ts">type Person = {
    name: string,
      gf?: string,
};

let person: Person = {
    name: &quot;현&quot;,
      gf: &quot;있을수도있고 없을수도있고&quot;,
};

const len: number = person.gf?.length; // 오류를 발생시킨다.

const len: number = person.gf!.length;</code></pre>
<ul>
<li><code>!</code>를 통해 이 값이 <code>undefined</code>, <code>null</code> 아니라고 단언하기</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Type Script - 4]]></title>
            <link>https://velog.io/@_imhyunnn/Type-Script-4</link>
            <guid>https://velog.io/@_imhyunnn/Type-Script-4</guid>
            <pubDate>Sat, 16 Dec 2023 14:40:14 GMT</pubDate>
            <description><![CDATA[<h2 id="객체-타입간의-호환성">객체 타입간의 호환성</h2>
<blockquote>
<p>어떤 객체타입을 다른 객체타입으로 취급해도 괜찮은가에 대해</p>
</blockquote>
<pre><code class="language-ts">type Korea = {
    이름: string;
      코드: number;
}

type Dokdo = {
    이름: string;
      코드: number;
      소속: string;
}

let korea: Korea = {
    이름: &quot;대한민국&quot;,
      코드: 82,
}

let dokdo: Dokdo = {
    이름: &quot;독도&quot;,
      코드: 82,
      소속: &quot;대한민국&quot;,
}</code></pre>
<p>위와 같이 <code>korea</code>와 <code>dokdo</code>라는 객체가 존재한다 
이떄 객체간의 호환성을 알아보자</p>
<p><code>dokdo</code> = <code>korea</code></p>
<ul>
<li>위의 코드는 오류를 발생한다 왜 일까?</li>
</ul>
<p>나는 처음에 이것을 보고 프로퍼티가 더 있기에 이것이 더 큰 포함이라 생각을 했었지만, <code>dokdo</code>객체는 <code>korea</code>객체가 가지는 프로퍼티를 포함하고 추가적인 프로퍼티가 있기에 <code>korea</code>객체가 더 큰 집합이라고 볼 수 있다 
따라서 <code>korea</code> = <code>dokdo</code> 가 맞는 코드인 것이다.</p>
<blockquote>
<p>프로퍼티가 적은(조건이 더 적은) 타입이 슈퍼타입인 것이다.</p>
</blockquote>
<h2 id="대수-타입">대수 타입</h2>
<blockquote>
</blockquote>
<p>여러개의 타입을 합성해서 새롭게 만들어낸 타입
이 타입에는 합집합, 교집합이 존재한다.</p>
<h3 id="합집합union-타입">합집합(Union) 타입</h3>
<blockquote>
<p><code>|</code> 를 이용하여 유니온 타입을 정의할 수 있다.</p>
</blockquote>
<pre><code class="language-ts">let union :string | number | boolean;
let number: number = 10;

union = &quot;이렇게 문자도 쓸 수 있고&quot;;
union = 1234;
union = &quot;이렇게 숫자도 쓸 수 있고&quot;;
union = true;
union = &quot;이렇게 참 거짓도 쓸 수 있다&quot;;</code></pre>
<h3 id="교집합intersection-타입">교집합(Intersection) 타입</h3>
<blockquote>
<p><code>&amp;</code>를 이용하여 인터렉션 타입을 정의할 수 있다.</p>
</blockquote>
<pre><code class="language-ts">let value: number &amp; string;</code></pre>
<p>숫자타입과 문자타입의 공통적인 요소가 있을까?
-&gt; 존재하지 않는다. 그렇기에 <code>never</code> 타입으로 추론이 된다.
대체적으로 기본 타입들에는 서로 공통적인 요소가 없기에 <code>인터렉션</code> 타입은
보통 객체 다팁들에 자주 사용된다.</p>
<p>그럼 이제 객체에서의 <code>인터렉션</code> 타입을 알아보자</p>
<pre><code class="language-ts">type Dog = {
    name: string;
    old: number;
};

type Person = {
    name: string;
    birth: string;
};

type Intersection = Dog &amp; Person;

let intersection1: Intersection = {
    name: &#39;&#39;,
    old: 1,
    birth: &#39;&#39;,
};</code></pre>
<ul>
<li>서로의 공통된 집합만을 타입으로 가질 수 있다.</li>
</ul>
<h2 id="타입-추론">타입 추론</h2>
<blockquote>
</blockquote>
<p>타입스크립트는 정의가 되어있지 않은 변수의 타입을 자동으로 추론한다.
변수의 초기값을 통해 추론을 할 수 있다.</p>
<h4 id="타입-추론이-가능한-상황들에-대해-알아보자">타입 추론이 가능한 상황들에 대해 알아보자</h4>
<h3 id="1-변수선언">1. 변수선언</h3>
<blockquote>
<p>변수 선언의 경우 초기값을 통해 타입을 추론한다.</p>
</blockquote>
<pre><code class="language-ts">let num = 10;
// number 타입으로 추론

let str = &quot;string&quot;;
// string 타입으로 추론

let book = {
      name: &#39;Deep Dive&#39;,
      price: 20000,
      lang: &#39;JavaScript&#39;,
}
// 각각의 name, price, lang은 초기값을 통해 각각의 타입을 가지는 객체로 추론</code></pre>
<h3 id="2-구조-분해-할당">2. 구조 분해 할당</h3>
<pre><code class="language-ts">let {name, price, lagn} = book;

let [one, two, three] = [1, true, &quot;string];</code></pre>
<ul>
<li>위와 같이 객체, 배열을 구조 분해 할당을 하여도 타입이 추론이 가능하다.</li>
</ul>
<h3 id="3-함수의-반환값-함수에서의-매개변수">3. 함수의 반환값, 함수에서의 매개변수</h3>
<pre><code class="language-ts">function func() {
    return &quot;TS Study&quot;;
}</code></pre>
<ul>
<li>위와 같은 함수 반환값의 타입은 return 문을 기준으로 추론이 된다.</li>
</ul>
<pre><code class="language-ts">function func(ts = &quot;TS Study&quot;) {
    return &quot;TS Study&quot;;
}</code></pre>
<ul>
<li>기본값이 설정이 된 매개변수의 타입은 기본값을 기준으로 추론이 되지만,
기본 값이 설정이 되지 않으면 오류를 발생시킨다.</li>
</ul>
<h3 id="암시적-any-type">암시적 any Type</h3>
<pre><code class="language-ts">let any;</code></pre>
<ul>
<li>위와 같은 코드가 있다고 생각을 해보자 이는 초기값이 없기에 <code>any</code> 타입으로 추론이 된다.</li>
<li>여기서 변수를 추가 할당해보자</li>
</ul>
<pre><code class="language-ts">let anyValue;

anyValue = 9;
Math.sqrt(anyValue);
anyValue.toFixed();

anyValue = anyValue.toString();
anyValue.toUpperCase();
anyValue.toFixed(); // 오류 발생 </code></pre>
<ul>
<li>왜 <code>toFixed</code> 가 위에선 오류가 없고 밑에선 오류가 생길까?</li>
<li>이는 암시적으로 <code>any</code> 타입으로 추론을 하기 때문이다.</li>
<li>두번째 줄에서 <code>anyValue</code> 에 넘버타입의 값을 넘겨줘서 그 이후부터는 <code>anyValue</code> 를 number 타입으로 추론을 하기 시작</li>
<li><code>anyValue</code> 를 문자열로 바꾸게 되면 문자 타입으로 추론 그렇기에 number타입에 사용하는 메서드인 <code>toFixed</code> 가 오류를 발생 시키는 것이다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Type Script - 3]]></title>
            <link>https://velog.io/@_imhyunnn/Type-Script-3</link>
            <guid>https://velog.io/@_imhyunnn/Type-Script-3</guid>
            <pubDate>Tue, 12 Dec 2023 06:32:54 GMT</pubDate>
            <description><![CDATA[<h2 id="ts에서의-객체">Ts에서의 객체</h2>
<p>user의 정보를 담고 있는 객체를 한 번 만들어 보자</p>
<pre><code class="language-ts">let user:object = {
    id: 1,
      name:&#39;현&#39;,
}
</code></pre>
<p>이렇게 만들어 버리면 문제가 발생해버린다</p>
<blockquote>
<p>&#39;object&#39;형식에 &#39;id&#39;속성이 없다</p>
</blockquote>
<ul>
<li>타입을 <code>object</code>로 정의를 하면 이 요소는 객체인것만 알려주고 더이상의 정보는 주어지지 않기 떄문이다.</li>
</ul>
<pre><code class="language-ts">let user: {
    id:number;
      name:string;
} = {
    id:1,
      name:&#39;김동현&#39;,
}</code></pre>
<p>위와 같은 방식을 객체리터럴 방식이라고 하며 이렇게 했을 시 객체에 요소에 접근할 수 있고 요소가 어떠한 타입을 가지는지 알 수가 있다.</p>
<h3 id="선택적-프로퍼티optional">선택적 프로퍼티(Optional)</h3>
<p>만약 객체를 생성했고 어떠한 값을 받게 되는데 이 값이 있어도 되고 없어도 되는 상황이라면 어떻게 해야할까?</p>
<pre><code class="language-ts">let user: {
    id?: number;
      name: string;
} = {
    id:1,
      name:&#39;김동현&#39;,
}</code></pre>
<ul>
<li>이 말은 id는 있어도 되고 없어도 되지만, 만약 있게 된다면 number의 타입을 갖는 값이여야한다는 점이다.</li>
</ul>
<h3 id="읽기-전용-프로퍼티readonly">읽기 전용 프로퍼티(readonly)</h3>
<p>이 객체의 값에서 수정이 되면 안되는 값이 있다면??</p>
<pre><code class="language-ts">let config = {
    readonly apiKey = string;
} = {
    apiKey: &quot;MY API KEY&quot;,
}</code></pre>
<ul>
<li>이렇게 객체의 프로퍼티 값을 <code>readonly</code> 를 하게 되면 읽기 전용 속성이므로 어떠한 값을 할당 할 수 없다.</li>
</ul>
<h3 id="타입-별칭">타입 별칭</h3>
<p>유저의 정보에 대한 객체의 타입을 지정함에 있어서 </p>
<pre><code class="language-ts">let user1: {
  id: number;
  name: string;
  nickname: string;
} = {
  id: 1,
  name: &#39;김동현&#39;,
  nickname: &#39;ddd&#39;,
};

let user2: {
  id: number;
  name: string;
  nickname: string;
} = {
  id: 2,
  name: &#39;동현&#39;,
  nickname: &#39;hhh&#39;,
};</code></pre>
<p>이렇게 되어버리면 중복되는 유저의 타입이 거슬릴 수 밖에 없다 이럴때엔 타입을 변수처럼 사용하여 중복된 타입을 줄일 수 있다.</p>
<pre><code class="language-ts">type User = {
  id: number;
  name: string;
  nickname: string;
};
</code></pre>
<p>이 값을 마치 변수 처럼 타입 지정할 수 있게끔 할 수 있다.</p>
<h3 id="인덱스-시그니처">인덱스 시그니처</h3>
<blockquote>
<p>객체의 타입을 지정하는데 그 객체의 value와 key값의 타입의 규칙을 통해 쉽게 타입을 정할 수 있다.</p>
</blockquote>
<pre><code class="language-ts">let 대한민국 = {
    서울: &quot;특별시&quot;,
      대전: &quot;광역시&quot;,
      부산: &quot;광역시&quot;,
      대구: &quot;광역시&quot;,
      독도: &quot;우리땅&quot;,
}</code></pre>
<p>위 대한민국 객체를 보면 value,key값 또한 string이기에 다음과 같이 타입을 정의할 수 있다.</p>
<pre><code class="language-ts">type Korea = {
    [key: string] : string,
};

let 대한민국:Korea = {
    서울: &quot;특별시&quot;,
      대전: &quot;광역시&quot;,
      부산: &quot;광역시&quot;,
      대구: &quot;광역시&quot;,
      독도: &quot;우리땅&quot;,
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Type Script - 2]]></title>
            <link>https://velog.io/@_imhyunnn/Type-Script-2</link>
            <guid>https://velog.io/@_imhyunnn/Type-Script-2</guid>
            <pubDate>Tue, 12 Dec 2023 06:13:09 GMT</pubDate>
            <description><![CDATA[<h2 id="ts에서의-배열-타입">Ts에서의 배열 타입</h2>
<h3 id="배열에-들어가는-요소들의-타입이-같을-경우">배열에 들어가는 요소들의 타입이 같을 경우</h3>
<pre><code class="language-ts">let numArr:number[] = [1, 2, 3];
let strArr:string[] = [&quot;hello&quot;, &quot;world&quot;];
let boolArr:Array&lt;boolean&gt; = [true, false, true];</code></pre>
<ul>
<li>배열타입을 명시하는데에는 두가지 방법이 있다 <ul>
<li>요소의 타입 + <code>[]</code>를 사용한 가장 기본적인 방법</li>
<li><code>Array&lt;배열의 요소 타입&gt;</code> - 제네릭 방법</li>
</ul>
</li>
</ul>
<p>이 두가지 방법이 존재하지만, 기본적인 방법이 간단하기에 주로 쓰인다.</p>
<h3 id="배열에-들어가는-요소들의-타입이-다양할-경우">배열에 들어가는 요소들의 타입이 다양할 경우</h3>
<pre><code class="language-ts">let nultiArr:(number | string) = [1, &quot;Hello&quot;];
let doubleArr: number[][] = [[1,2,3],[4,5]];</code></pre>
<h3 id="튜플">튜플</h3>
<blockquote>
<p>길이와 타입이 고정된 배열</p>
</blockquote>
<pre><code class="language-ts">let tup1: [number, number] = [1, 2];
let tup2: [number, string, boolean] = [1, &quot;str&quot;, true];</code></pre>
<ul>
<li>튜플로 정의된 배열은 타입 또는 길이가 벗어나면 오류를 발생한다.</li>
<li>자리 또한 지켜지기에 순서를 지키는게 중요할 때 튜플타입을 통해 값을 잘못 넣지 않도록 방지할 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[페이지를 이동한다 Page Routing]]></title>
            <link>https://velog.io/@_imhyunnn/%ED%8E%98%EC%9D%B4%EC%A7%80-ROUTING</link>
            <guid>https://velog.io/@_imhyunnn/%ED%8E%98%EC%9D%B4%EC%A7%80-ROUTING</guid>
            <pubDate>Sun, 10 Dec 2023 09:48:29 GMT</pubDate>
            <description><![CDATA[<h2 id="what-is-routing">What is ROUTING</h2>
<p>ROUTING의 사전적 의미는 어떤 네트워크 내에서 통신 데이터를 보낼 경로를 선택하는 일련의 과정이다.
ROUTER의 사전적 의미는 데이터의 경로를 실시간으로 지정해주는 역하을 해주는 무언가</p>
<blockquote>
<p>즉 라우팅이란 데이터의 경로를 정해주는 행위</p>
</blockquote>
<h4 id="mpa멀티페이지어플리케이션에서의-페이지-라우팅">MPA(멀티페이지어플리케이션)에서의 페이지 라우팅</h4>
<p>웹사이트에 접속한다는 것은 브라우저를 통해서 웹서버에 경로를 요청하고, 해당 웹 문서를 받아보는 과정이라고 할 수 있다.</p>
<h4 id="spa싱글페이지어플리케이션에서의-페이지-라우팅">SPA(싱글페이지어플리케이션)에서의 페이지 라우팅</h4>
<p>어떠한 페이지를 요청하더라도 index.html을 내보내준다.
또한 서버와 통신 없이 브라우적 알아서 렌더링을 해준다. -&gt; 페이지 전환이 빠르다
데이터가 필요한 페이지일 경우 해당 필요한 데이터만 서버와 통신해서 렌더링 하게 해준다.</p>
<h2 id="reacr-router-dom의-유용한-기능에-대해-알아보자">Reacr Router Dom의 유용한 기능에 대해 알아보자</h2>
<blockquote>
<p>React에서 CSR기반의 페이지 라우팅을 할 수 있게 해주는 라이브러리이다.</p>
</blockquote>
<h3 id="path-variable-feat-useparams">Path Variable (feat. useParams)</h3>
<blockquote>
<p>URL의 일부를 동적으로 처리하기 위해 사용된다.</p>
</blockquote>
<pre><code class="language-jsx">// 라우팅하는 상위 컴포넌트 파일

&lt;Route path=&quot;동적으로원하는경로/:동적인 값&quot;/&gt;

// 해당 동적인 값을 설정하는 컴포넌트 파일

import { useParams } from &quot;react-router&quot;

const 컴포넌트이름 =() =&gt; {
    const { 동적인값 } = useParams();
      console.log(동적인값);
};
</code></pre>
<p>위와 같이 코드를 구성하게 되면 해당 프로젝트의 url에서 
/해당폴더이름/동적인값 에 들어가게되면
콘솔 창에 해당 동적인 값을 들고 올 수 있게 된다.</p>
<p>--&gt; 매개변수를 기반으로 서로 다른 컴포넌트를 렌더링할 수 있게 된다.</p>
<h3 id="query-string-feat-usesearchparams">Query String (feat. useSearchParams)</h3>
<blockquote>
<p>페이지에 데이터를 전달하는 가장 간단한 방법이다.</p>
</blockquote>
<p>ex) www.아무페이지이름.com/?id=10&amp;<del>~</del>
이렇게 되어져 있는데 path variable과 다른점은 라우팅이 자동으로 래핑이 되어져있다는 점이다.
? 뒤에 있는 경로들은 페이지 라우팅에 영향을 주지 않는다는 점</p>
<p>해당 데이터를 수정하는 페이지를 만든다고 했을 때 그 특정 동적인 값을 끌고 와야하는 상황에서 
query string을 통해 라우팅을 설정해보자</p>
<p>ex-url)www.페이지이름.com/페이지이름?id=10</p>
<pre><code class="language-jsx">import { useSearchParams } from &#39;react-router-dom&#39;;

const 컴포넌트이름 = () =&gt; {
    const [searchParams, setSearchParams] = useSearchParams();

      const id = searchParams.get(&quot;id&quot;);
      console.log(&quot;id&quot;); // 10
};</code></pre>
<p>이렇게 사용을 해서 페이지에 어떠한 값을 전달할 수 있게끔 도와준다.</p>
<h4 id="그럼-이제-이-동적인-값을-변경을-해보자">그럼 이제 이 동적인 값을 변경을 해보자</h4>
<p>useState()와 같이 생긴 useSearchParams()를 통해 동적인 값 변경하기</p>
<pre><code class="language-jsx">&lt;button onClick={setSearchParams({ 이걸로: &#39;바굽니다&#39; })}&gt;QS&lt;/button&gt;</code></pre>
<p>그럼 이제 url이 ?이걸로=바꿉니다로 변경되는것을 볼 수 있다.</p>
<h3 id="page-moving-feat-usenavigate">Page Moving (feat. useNavigate)</h3>
<blockquote>
<p>useNavigate() =&gt; 로케이션을 변경하는 값을 반환한다</p>
</blockquote>
<pre><code class="language-jsx">const navigate = useNavigate();

if(userID == &#39;&#39;) {
    navigate(&#39;/로그인이 없는 경우 보내줄 페이지 경로&#39;)
}</code></pre>
<p>Link컴포넌트와 달리 특정 상황에서 이런식으로 페이지를 강제로 보낼 수 있게금 할 수 있을 것 같다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[react-icons 효율적으로 사용하기]]></title>
            <link>https://velog.io/@_imhyunnn/react-icons</link>
            <guid>https://velog.io/@_imhyunnn/react-icons</guid>
            <pubDate>Fri, 17 Nov 2023 08:58:17 GMT</pubDate>
            <description><![CDATA[<p>react-Icons 공식 문서를 보면서 작업을 하던 도중 효율적으로 사용하기 위한 
내가 시도한 방법에 대해서 정리 해보려고 한다.</p>
<h2 id="기존-사용-방법">기존 사용 방법</h2>
<p><code>import { IconName } from &#39;react-icons/IconCategories&#39;</code></p>
<p>위와 같이 아이콘 이름 + 아이콘의 카테고리를 정해서 <code>import</code>를 하는데 뭔가 불편했고, 
아이콘이 한두개면 괜찮지만 아이콘이 많아질수록 쌓여가는 아이콘 관련 <code>import</code>가 너무 불편했다.</p>
<p>다른 사람들은 어떻게 사용할까 하면서 찾아봤는데 원하는 답을 얻지는 못하였다 </p>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/e726ebca-83a3-4b5e-99c5-d0e65d487eb7/image.png" alt=""></p>
<blockquote>
<p> 넵!</p>
</blockquote>
<br>

<h2 id="내가-개선한-방법--사용-방법">내가 개선한 방법 + 사용 방법</h2>
<h3 id="1-가장-먼저-react-icons를-사용하기-위해-설치를-해보자">1. 가장 먼저 <code>react-icons</code>를 사용하기 위해 설치를 해보자</h3>
<pre><code class="language-bash">$ npm install react-icons</code></pre>
<h3 id="2-내가-프로젝트에서-사용할-아이콘의-카테고리-및-아이콘-리스트를-정리를-한다">2. 내가 프로젝트에서 사용할 아이콘의 카테고리 및 아이콘 리스트를 정리를 한다.</h3>
<blockquote>
<p>나는 Font Awesome6를 사용하기로 했고, 아이콘들의 리스트를 정했다.</p>
</blockquote>
<h3 id="3-icon-스타일--리스트를-기본적으로-사용할-파일을-생성한다">3. icon 스타일 + 리스트를 기본적으로 사용할 파일을 생성한다.</h3>
<p>프로젝트마다 폴더 구조도 다르겠지만 나의 구조는 각각의 컴포넌트들의 
기본 스타일 + 전체적으로 쓸 컬러 + 각각의 규칙을 정하여 theme 폴더에서 관리를 했고,
여기에 iocn를 추가하여 작성하였다</p>
<h3 id="4-내가-쓸-아이콘의-스타일을-정해보자">4. 내가 쓸 아이콘의 스타일을 정해보자</h3>
<pre><code class="language-js">// themes/default/components/icon.js

import { FaAngleLeft, FaAngleRight, FaAngleUp, FaAngleDown, FaXmark, FaRegCircleXmark, FaPlus, FaMagnifyingGlass, FaBars, FaEye, FaEyeSlash, FaRotateRight, FaGear } from &#39;react-icons/fa6&#39;;

const baseStyle = {
  display: &#39;inline-flex&#39;,
  justifyContent: &#39;center&#39;,
  alignItems: &#39;center&#39;,
};

const iconTypes = {
  arrowLeft: FaAngleLeft,
  arrowRight: FaAngleRight,
  arrowUp: FaAngleUp,
  arrowDown: FaAngleDown,
  close: FaXmark,
  closeFill: FaRegCircleXmark,
  plus: FaPlus,
  search: FaMagnifyingGlass,
  hamburger: FaBars,
  visible: FaEye,
  unvisible: FaEyeSlash,
  refresh: FaRotateRight,
  system: FaGear,
};

const iconSizes = {
  lg: {
    width: &#39;24px&#39;,
    height: &#39;24px&#39;,
  },
  md: {
    width: &#39;20px&#39;,
    height: &#39;20px&#39;,
  },
  sm: {
    width: &#39;16px&#39;,
    height: &#39;16px&#39;,
  },
};

export default { baseStyle, iconTypes, iconSizes };
</code></pre>
<ul>
<li>아이콘의 기본 스타일, 사이즈, 타입을 정의한다.</li>
</ul>
<h3 id="5-전역으로-쓸-준비--폴더-구조-설명">5. 전역으로 쓸 준비 + 폴더 구조 설명</h3>
<pre><code class="language-js">// themes/default/index.js

import components from &#39;./components&#39;;
import tokens from &#39;./tokens&#39;;

export default {
  ...tokens,
  components,
};</code></pre>
<ul>
<li>내가 쓸 컴포넌트들의 기본 스타일 + 규칙들이 정해져있는 파일들을 export해준다</li>
</ul>
<pre><code class="language-js">// themes/index.js

export { default as defaultTheme } from &#39;./default&#39;;</code></pre>
<ul>
<li>마지막으로 다시 이거를 <code>deafultTheme</code>로 묶어 export를 해준다.</li>
</ul>
<pre><code class="language-jsx">import { createContext, useContext } from &#39;react&#39;;
import { defaultTheme } from &#39;../themes&#39;;
import PropTypes from &#39;prop-types&#39;;

const ThemeContext = createContext();

// eslint-disable-next-line react-refresh/only-export-components
export const useTheme = () =&gt; {
  return useContext(ThemeContext);
};

export const ThemeProvider = ({ children }) =&gt; {
  return &lt;ThemeContext.Provider value={defaultTheme}&gt;{children}&lt;/ThemeContext.Provider&gt;;
};

ThemeProvider.propTypes = {
  children: PropTypes.node, 
};
</code></pre>
<ul>
<li>전역으로 쓰기 위해서 useContext를 사용하였고 해당 <code>defaultTheme</code>를 다른 컴포넌트에서
<code>useTheme</code>를 사용하여 쓸 수 있게 된다.</li>
</ul>
<pre><code class="language-jsx">// App.js

import { ThemeProvider } from &#39;./theme/ThemeContext&#39;;

function App() {
  return (
    &lt;ThemeProvider&gt;
        {/* 각각의 프로젝트에 맞는 구성 */}
    &lt;/ThemeProvider&gt;
  );
}

export default App;
</code></pre>
<ul>
<li>프로젝트마다 상이할테니 생략된 점 최상위에서 <code>ThemeProvider</code>를 통해 전역 설정을 해준다.</li>
</ul>
<h3 id="6-icon-컴포넌트를-내-입맛대로-설정해보자">6. Icon 컴포넌트를 내 입맛대로 설정해보자</h3>
<p>가장 먼저 내가 고려한 것은 아이콘을 유동적으로 사용하기 위함이고 그게 아니였다면 
그냥 주먹구구식 import를 사용해서 썼을 것이다.
컴포넌트를 사용하는게 편하게 사용하기 위함인데 너무 불편했었다.</p>
<p>나만의 Icon컴포넌트 emotion과 함께 응용하여 만들어보자 </p>
<pre><code class="language-jsx">// components/Icon/Icon.jsx

import styled from &#39;@emotion/styled&#39;
import { useTheme } from &#39;../../../theme/ThemeContext&#39;;

const StyledIcon = styled.span`
  ${(props) =&gt; props.theme.components.icon.baseStyle}

  .Icon {
    ${(props) =&gt; props.theme.components.icon.iconSizes[props.size]}
    color:${(props) =&gt; props.theme.colors[props.color]};
  }
`;</code></pre>
<ul>
<li><p><code>react-icons</code>를 통해 컴포넌트를 사용하면 <code>svg</code> 태그를 단독으로 렌더링 해주는데,
이거는 조금 별로 안 좋은 방법이고 입맛대로 수정하기 위해선 감싸는 태그가 하나 필요하기에
<code>span</code>를 통해 스타일을 해준다.</p>
</li>
<li><p>아이콘들에 따라 <code>import</code>를 하기 싫기에 name + size + color를 통해 나만의 컴포넌트로 설정해보았다.</p>
</li>
<li><p>해당 프로젝트에서 하나하나 width=&quot;&quot;를 지정하기엔 너무 번거로우니 프로젝트의 일관성을 위해 
정해진 size, color를 props를 받을 수 있게 한다.</p>
</li>
</ul>
<pre><code class="language-jsx">// components/Icon/Icon.jsx

const Icon = ({ name, size, color }) =&gt; {
  const PREFIX = &#39;Icon&#39;;
  const theme = useTheme();
  const SelectedIcon = theme.components.icon.iconTypes[name];

  return (
    &lt;StyledIcon size={size} theme={theme} color={color}&gt;
      &lt;SelectedIcon className={PREFIX} /&gt;
    &lt;/StyledIcon&gt;
  );
};

Icon.defaultProps = {
  size: &#39;md&#39;,
  color: &#39;black&#39;,
};

Icon.propTypes = {
  name: PropTypes.string.isRequired,
  size: PropTypes.oneOf([&#39;lg&#39;, &#39;md&#39;, &#39;sm&#39;]),
  color: PropTypes.string,
};

export default Icon;
</code></pre>
<ul>
<li>기본 size, color를 정해두고 필요시마다 size, color를 조정한다</li>
</ul>
<h4 id="다르게-생각하는-사람도-있을것이다">다르게 생각하는 사람도 있을것이다.</h4>
<p>물론 이것보다 폴더구조를 간단하게 해서 iocn파일을 만들고 거기에서 icon 리스틀 정하고 
Icon컴포넌트에 icon 리스트를 import를 해도 된다</p>
<p>하지만 정답은 없고 이러한 방법도 해보고 저러한 방법도 해봐야 어떤게 좋고 나쁨을 구분할 수 있기에
나는 전체적인 기본 스타일을 관리하는 파일이 있었으면 하는 생각에 이러한 구조를 선택하게 되었다.</p>
<h3 id="7-icon컴포넌트를-통해-이제-사용해보자">7. Icon컴포넌트를 통해 이제 사용해보자</h3>
<p>기본 스타일을 위한 다른 코드들은 생략을 한 점은 양해를 구한다.</p>
<pre><code class="language-jsx">// pages/components

import Icon from &#39;../../components/hds/Icon/Icon&#39;;

const TestPages = () =&gt; {
  const theme = useTheme();

  return (
    &lt;div&gt;
      &lt;StyledPreview theme={theme}&gt;
        {Object.keys(iconMap).map((name, idx) =&gt; (
          &lt;IconPreview key={idx} className=&quot;IconPreview&quot;&gt;
            &lt;Icon name={name} color={randomColor} /&gt;
            &lt;p&gt;{name}&lt;/p&gt;
          &lt;/IconPreview&gt;
        ))}
      &lt;/StyledPreview&gt;
    &lt;/div&gt;
  );
};
export default TestPages;</code></pre>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/ab4d23b5-b815-464f-a6ae-279d6422d784/image.png" alt=""></p>
<p>아주 잘 나옵니다 구우우욷</p>
<blockquote>
<p>정답은 아니지만 확실히 <code>import</code>줄이 한줄로 끝이 났고 필요할 때 마다 유동적으로 쓸 수 있게되었다.</p>
</blockquote>
<p>모든 질문 의견 환영합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Type Script - 1]]></title>
            <link>https://velog.io/@_imhyunnn/TypeScript-1</link>
            <guid>https://velog.io/@_imhyunnn/TypeScript-1</guid>
            <pubDate>Wed, 15 Nov 2023 12:48:41 GMT</pubDate>
            <description><![CDATA[<h2 id="ts-왜-생겼는가">TS 왜 생겼는가?</h2>
<p><strong>TypeScript</strong> 배워 보기 전에 왜 생겼는지에 대해 알아보자</p>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/12c9627e-6b92-46b6-bc11-5455a90f8fd9/image.png" alt="typescript"></p>
<p>JS를 쓰는 100명의 개발자 중 TS를 안쓰는 개발자는 10명밖에 안된다 즉 100명 중 90명이 TS를 사용하고있다.</p>
<p>JS는 원래 간단한 상호작용 정도로(웹브라우저에서만 실행) 처리하기 위해 개발 되었고 그렇기에 유연한 문법 + 자유로움이 있었다 </p>
<p>Node.js가 생기고 나서 웹브라우저에서만 실행되던 JS가 이제 어디서든 구동기 가능해졌고 이로 인해 웹서버, 모바일 앱, 데스크탑 앱으로까지 개발이 가능해졌다 그러나 JS의 본질적 성질때문에 버그 가능성이 높아지면서 장점이 단점이 되어버렸고 이 단점을 극복하기 위해 생긴 것이 TS이다.</p>
<h4 id="타입스크립트--자바스크립트의-확장판">타입스크립트 = 자바스크립트의 확장판</h4>
<blockquote>
<p>자바스크립트를 더 안전하게 사용할 수 있도록 <code>type</code>관련 기능들을 추가한 언어</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/1b26f287-fd8c-4158-bdb6-7c5de9544198/image.png" alt=""></p>
<p>JS는 전세계적으로 가장 인기있는 프로그래밍 언어이다.</p>
<h4 id="인기-많은-js만으로-충분하지-않을까-ts-굳이-배워야하나">인기 많은 JS만으로 충분하지 않을까? TS 굳이 배워야하나?</h4>
<blockquote>
<p>응</p>
</blockquote>
<h2 id="타입type-시스템">타입(Type) 시스템</h2>
<blockquote>
<p>값들을 어떤 기준으로 묶어 타입을 규정할 것인가?
<strong>언어의 타입 관련된 문법 체계</strong></p>
</blockquote>
<ul>
<li>Number - 0.1, 1, 100</li>
<li>Boolean - true, false</li>
<li>String - &quot;안녕&quot;, &quot;그래&quot;</li>
</ul>
<h3 id="정적-타입-시스템">정적 타입 시스템</h3>
<p>코드 실행 이전 모든 변수의 타입을 <strong>고정적</strong>으로 결정
즉 엄격하고 고정적이다 
ex) C,Java</p>
<h3 id="동적-타입-시스템">동적 타입 시스템</h3>
<p>코드를 실행하고 나서 그때 그때 마다 <strong>유동적</strong>으로 변수의 타입을 결정
즉 자유롭고 유연하다
ex) Python, JavaScript</p>
<h3 id="ts의-타입-시스템">TS의 타입 시스템</h3>
<pre><code class="language-js">// index.js

let num = 1;
num.toUpperCase();</code></pre>
<p>JS 에서는 위 코드가 코드 실행 전 아무런 표시가 뜨지 않는다.</p>
<p>TS는 어떠할까?</p>
<pre><code class="language-ts">// index.ts

let num: number = 1;
num.toUpperCase();</code></pre>
<p>toUpperCase부분에 빨간줄이 뜬다.
그렇지만 항상 매번 변수에 타입을 지정하는거는 너무 번거로운 일이지 않냐?</p>
<blockquote>
<p>그렇지 않다.</p>
</blockquote>
<pre><code class="language-ts">// index.ts

let num = 1;
num.toUpperCase();</code></pre>
<p>모든 변수에 타입을 일일이 지정할 필요가 없음</p>
<blockquote>
<p>초기 값을 통해 타입을 추론</p>
</blockquote>
<h2 id="ts-동작-원리">TS 동작 원리</h2>
<p>TS 동작 원리를 알아보기 전 JS의 동작 원리에 대해 알아보자</p>
<h4 id="js-컴파일-과정">JS 컴파일 과정</h4>
<blockquote>
<p>컴파일 - 우리가 쓰는 프로그래밍 언어를 컴퓨터가 이해하기 쉬운 형태(바이트 코드)로 변환하는 작업</p>
</blockquote>
<ol>
<li>JS코드를 AST(추상 문법 트리)로 변환 </li>
<li>AST -&gt; 바이트 코드로 변환 컴파일 종료</li>
</ol>
<blockquote>
<p>AST - 코드에 필요한 것을 제외(공백, 주석 등)</p>
</blockquote>
<h4 id="ts-컴파일-과정">TS 컴파일 과정</h4>
<ol>
<li>TS코드를 AST(추상 문법 트리)로 변환</li>
<li>변환된 AST에 대해 타입 검사
2-1. 타입에 오류가 있을 시 컴파일이 종료</li>
<li>타입 오류가 없다면 AST를 JS로 변환 후 컴파일 종료</li>
</ol>
<p>-&gt; 타입 검사가 된 JS는 안전한 코드이기에 버그 발생 확률이 현저히 낮다 </p>
<h2 id="ts-컴파일러-옵션-설정">TS 컴파일러 옵션 설정</h2>
<blockquote>
<p>TS를 시작하기 앞서 이제 컴파일러 옵션에 대해 알아보자 </p>
</blockquote>
<p>해당 프로젝트에서 다음과 같은 명령어를 사용</p>
<pre><code class="language-bash">tsc --init</code></pre>
<p>이렇게 하게되면 tsconfig.json 파일이 생성되고 그 안을 열어보면 뭐가 많은데 그냥 다 삭제해버리자</p>
<p>컴파일러 옵션이기에 프로젝트에 따라 다르게 설정할 수 있으니 입맛대로 설정해보면서 어떠한 옵션이 있는지 알아보자</p>
<pre><code class="language-json">{
    &quot;compilerOptions&quot;: {
        &quot;target&quot;: &quot;ESNext&quot;,
        &quot;module&quot;: &quot;ESNext&quot;,
        &quot;outDir&quot;: &quot;dist&quot;,
        &quot;strict&quot;: false,
        &quot;moduleDetection&quot;: &quot;force&quot;
    },
    &quot;include&quot;: [&quot;src&quot;]
}
</code></pre>
<p>하나하나 알아보자 </p>
<p><code>target</code> - 컴파일된 JS코드를 어떤 ECMAScript 버전으로 타겟팅할 지에 대한 설정
<code>module</code> - 컴파일된 JS 모듈 형식을 설정
<code>outDir</code> - 컴파일된 JS 파일이 생성될 디렉토리 설정
<code>strict</code> - TS의 엄격한 타입 체크 설정
<code>include</code> - TS컴파일러에게 컴파일 할 파일이나 디렉토리 지정
<code>moduleDetection</code> - 모듈 감지 방법</p>
<pre><code class="language-js">// file1.ts
const message = &quot;Hello from file1&quot;;

// file2.ts
const message = &quot;Hello from file2&quot;;</code></pre>
<p>위와 같은 파일이 존재하고 같은 변수가 존재한다고 하자
그럼 TS는 오류가 발생했다고 알려준다.</p>
<p>TS는 변수 충돌을 방지를 하기때문이다 
그래서 <code>moduleDetection</code> 이 옵션을 <code>force</code>로 바꾸게 되면
조금 더 자유로운 변수를 공유할 수 있게 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터를 수정하고 화면에 렌더링해보자]]></title>
            <link>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B06</link>
            <guid>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B06</guid>
            <pubDate>Sun, 05 Nov 2023 08:16:03 GMT</pubDate>
            <description><![CDATA[<p>전 장에서 데이터를 추가하고, 삭제해보는 기능까지는 해보았다.
해당 데이터를 수정해서 그 수정한 값을 렌더링 해보자</p>
<h4 id="dataitemjsx">DataItem.jsx</h4>
<pre><code class="language-jsx">const DataItem = ({ id, name, content, score }) =&gt; {
  return (
    &lt;div clssName=&quot;DataItem&quot;&gt;
      &lt;h2&gt;
        {id}. {name}
      &lt;/h2&gt;
      &lt;div&gt;{content}&lt;/div&gt;
      &lt;div&gt;점수 : {score}&lt;/div&gt;
      &lt;div&gt;
        &lt;button onClick={handleRemove}&gt;삭제 하기&lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
};
</code></pre>
<p>현재 <code>DataItem</code> 컨포넌트는 데이터를 삭제하는 기능만 있다 이제 수정 할 수 있기 위해선 다음과 같이 진행해보자</p>
<blockquote>
<ol>
<li>해당 컴포넌트에서 수정을 하는지 안하는지에 대한 상택값이 필요하다. </li>
</ol>
</blockquote>
<ul>
<li>수정을 한다면 <code>false</code> 수정을 하지 않는다면 <code>true</code>로 상태값을 업데이트한다.</li>
</ul>
<blockquote>
<ol start="2">
<li>수정 여부에 따라 렌더링 되는 내용이 바뀌어야한다.</li>
</ol>
</blockquote>
<ul>
<li>상태값을 이용하여 렌더링 되는 것을 조절한다.</li>
</ul>
<blockquote>
<ol start="3">
<li>수정을 하고 최종 데이터를 최상위 컴포넌트에 전달해준다.</li>
</ol>
</blockquote>
<ul>
<li>이러한 순서를 통해 수정한 값을 화면에 렌더링 해보자</li>
</ul>
<h3 id="1-컴포넌트의-상태값을-추가해보자">1. 컴포넌트의 상태값을 추가해보자</h3>
<h4 id="dataitemjsx-1">DataItem.jsx</h4>
<pre><code class="language-jsx">const DataItem = () =&gt; {
  const [isEdit, setIsEdit] = useState(false);
};
</code></pre>
<p>수정 버튼을 눌렀을 때 해당 <code>useState</code>값을 <code>true</code>로 바꿔주면 해당 사용자가 수정을 하구나, 하지 않구나를 알 수 있다.</p>
<h3 id="2-상태에-따른-렌더링-업데이트">2. 상태에 따른 렌더링 업데이트</h3>
<p>상태에 따른 렌더링을 하기 위해선 해당 버튼을 눌렀을 때 
상태를 바꿔야하고 바꼈다면 업데이트를 해줘야한다.</p>
<h4 id="dataitemjsx-2">DataItem.jsx</h4>
<pre><code class="language-jsx">const DataItem = () =&gt; {
  const [isEdit, setIsEdit] = useState(false);

  const toggleEdit = () =&gt; setIsEdit(!isEdit);

  const handleQuitEdit = () =&gt; {
    setIsEdit(false);
  };

  return (
    &lt;div className=&quot;DataItem&quot;&gt;
      &lt;div className=&quot;SubjectContent&quot;&gt;
        {isEdit ? (
          &lt;&gt;
            &lt;textarea /&gt;
          &lt;/&gt;
        ) : (
          &lt;&gt;{content}&lt;/&gt;
        )}
      &lt;/div&gt;
      &lt;div className=&quot;BtnArea&quot;&gt;
        {isEdit ? (
          &lt;&gt;
            &lt;button onClick={handleQuitEdit}&gt;수정 취소&lt;/button&gt;
            &lt;button&gt;수정 완료&lt;/button&gt;
          &lt;/&gt;
        ) : (
          &lt;&gt;
            &lt;button onClick={toggleEdit}&gt;수정 하기&lt;/button&gt;
            &lt;button onClick={handleRemove}&gt;삭제 하기&lt;/button&gt;
          &lt;/&gt;
        )}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};
export default DataItem;
</code></pre>
<p>이제 해당 상태에 따라 버튼 + 수정할 수 있는 <code>textarea</code>까지 렌더링 되는걸 볼 수 있다.</p>
<h3 id="3-수정이-완료된-데이터를-화면에-렌더링-해보자">3. 수정이 완료된 데이터를 화면에 렌더링 해보자</h3>
<h4 id="dataitemjsx-3">DataItem.jsx</h4>
<pre><code class="language-jsx">const DataItem = ({ onEdit }) =&gt; {
  const [localContent, setLocalContent] = useState(content);

  const handleChangeContent = (e) =&gt; {
    setLocalContent(e.target.value);
  };

  const handleEdit = () =&gt; {
    onEdit(id, localContent);
    toggleIsEdit();
  };

  return (
    // ...
    &lt;button onClick={handleEdit}&gt;수정 완료&lt;/button&gt;
    // ...
  );
};
</code></pre>
<p><code>DataItem</code>에서 현재 content의 내용 바뀐 content의 내용을 
<code>[localContent, setLocalContent]</code>로 관리를 하고, <code>onEdit</code>를 통하여
해당 <code>id</code>, content내용을 전달해준다.</p>
<h4 id="appjsx">App.jsx</h4>
<pre><code class="language-jsx">function App() {
  const OnEdit = (targetId, newContent) =&gt; {
    setData(
      data.map((it) =&gt;
        it.id === targetId ? { ...it, content: newContent } : it
      )
    );
  };
}
</code></pre>
<p>수정을 원하는 데이터의 아이디와, 수정된 내용을 매게변수로 받아
수정하고자하는 데이터의 아이디와 일치하면 기존의 데이터에 수정된 데이터를 추가해준다.</p>
<p>처음에 무작정 하다보니까 어려웠었는데 계속 콘솔창 찍어보면서 하다보니까 이제 좀 이해가 되는 듯 하다</p>
<blockquote>
<p>데이터 관리는 최상위 컴포넌트에서 관리하고 이벤트는 하위 컴포넌트에서 관리하는 방식</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[어 그래 (정)규식이 왔나?]]></title>
            <link>https://velog.io/@_imhyunnn/%EC%A0%95%EA%B7%9C-%ED%91%9C%ED%98%84%EC%8B%9D</link>
            <guid>https://velog.io/@_imhyunnn/%EC%A0%95%EA%B7%9C-%ED%91%9C%ED%98%84%EC%8B%9D</guid>
            <pubDate>Tue, 31 Oct 2023 14:59:57 GMT</pubDate>
            <description><![CDATA[<p>요즘 주말에 코딩테스트 문제 풀면서 공부를 하고 있는데 정규식에 관한 문제에 많이 부족한 것 같아서 
정리 하면서 공부하면 좋을 것 같아서 적게 되었다.</p>
<p>가장 먼저 정규 표헌식이 무엇일까부터 알아보자</p>
<h2 id="정규-표현식이란">정규 표현식이란?</h2>
<blockquote>
</blockquote>
<p><strong>문자열</strong>을 대상으로 패턴 매칭 기능을 제공한다.
패턴 매칭 기능 - 특정 패턴과 일치하는 문자열을 검색하거나 추출 또는 치환할 수 있는 기능</p>
<p>내가 문제를 풀면서 해당 문자열에서 특정 문자를 다른 문자로 치환하는 문제를 
반복문과 조건문을 통해서 풀었는데 정규 표현식으로 풀면 되게 쉽고 알면 좋을 것 같다는 생각이 들었다.</p>
<h2 id="정규-표현식을-만들어보자">정규 표현식을 만들어보자</h2>
<blockquote>
</blockquote>
<p>정규 표현식은 패턴과 플래그를 가지고 있다.
/패턴(pattern)/플래그(flag)</p>
<p>예제로 알아보자</p>
<pre><code class="language-js">const target = &quot;Is this yours?&quot;;

const regexp = /is/i;

regexp.test(target) // true</code></pre>
<p><code>test</code>메서드는 <code>target</code> 문자열에 대하여 정규 표헌식 <code>regexp</code>의 패턴을 검색하여 불리언 값으로 반환</p>
<p>그럼 메서드와 플래그에 대해서 알아보자 </p>
<h3 id="정규-표현식에서의-메서드">정규 표현식에서의 메서드</h3>
<h4 id="1-패턴-검사-test">1. 패턴 검사 test()</h4>
<p>패턴 검사에서는 크게 두가지로 나뉜다. </p>
<ul>
<li>단일 패턴</li>
</ul>
<pre><code class="language-js">const regExp = new RegExp(&quot;a&quot;);
console.log(regExp.test(&quot;abc&quot;)); // true</code></pre>
<p><code>test</code> 메서드를 통하여 해당 문자열에서 &quot;a&quot;가 포함되어 있는지에 대해 검사한다.</p>
<ul>
<li>복합 패턴</li>
</ul>
<pre><code class="language-js">const regExp = new RegExp(&quot;ab | cd&quot;);
console.log(regExp.test(&quot;abc&quot;)); // true
console.log(regExp.test(&quot;cde&quot;)); // true</code></pre>
<pre><code class="language-js">const regExp = /ab.*cd/;
console.log(regExp.test(&quot;abc&quot;)); // false
console.log(regExp.test(&quot;abcd&quot;)); // true
console.log(regExp.test(&quot;cde&quot;)); // false</code></pre>
<p>정규 표현식에서 <code>|</code>는 or을 나타내고, <code>.*</code>는 and를 나타낸다.</p>
<h4 id="2-문자열-검색-exec">2. 문자열 검색 exec()</h4>
<pre><code class="language-js">const regExp = new RegExp(&quot;a&quot;);
const str = &quot;abc&quot;;
const result = regExp.exec(str);
console.log(result); // [&quot;a&quot;, 0, 1]</code></pre>
<p><code>str</code> 문자열에서 &quot;a&quot;가 포함되어 있는지 있으면 다음과 같은 결과를 반환한다.</p>
<ul>
<li>&quot;a&quot; - 정규 표현식 /a/와 일치한다.</li>
<li>0 - 문자열 &quot;a&quot;가 idx 0 에서 시작한다.</li>
<li>1 - 문자열 &quot;a&quot;가 idx 1 에서 끝이난다.</li>
</ul>
<blockquote>
<p><code>str</code>에서 idx 0에서 1까지 일치한다는 것</p>
</blockquote>
<h4 id="3-문자열-치환-replace">3. 문자열 치환 replace()</h4>
<pre><code class="language-js">const regExp = new RegExp(&quot;a&quot;, &quot;b&quot;);
const str = &quot;abc&quot;;
const result = regExp.replace(str, &quot;b&quot;);
console.log(result); // &quot;bbc&quot;</code></pre>
<ul>
<li>&quot;a&quot;는 찾을 대상 문자열 </li>
<li>&quot;b&quot;는 대체할 문자열</li>
<li><code>str</code> 문자열에서 &quot;a&quot;가 포함되어 있으면 &quot;a&quot; -&gt; &quot;b&quot;로 대체되어 반환한다.</li>
</ul>
<h4 id="4-문자열-분할-split">4. 문자열 분할 split()</h4>
<pre><code class="language-js">const regExp = new RegExp(&quot;,&quot;);
const str = &quot;a,b,c&quot;;
const result = regExp.split(str);
console.log(result); // [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]</code></pre>
<ul>
<li>정규 표현식으로 해당 문자열에서 <code>,</code>를 찾는다.</li>
<li><code>,</code>를 기준으로 분할을 한다.</li>
<li><code>split</code> 을 통하여 배열로 반환 된다.</li>
</ul>
<h3 id="정규-표현식에서의-플래그">정규 표현식에서의 플래그</h3>
<table>
<thead>
<tr>
<th>플래그</th>
<th>의미</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>i</td>
<td>Ignore case</td>
<td>대소문자를 구별하지 않고 패턴을 검색한다.</td>
</tr>
<tr>
<td>g</td>
<td>Gloval</td>
<td>대상 문자열 내에서 패턴과 일치하는 모든 문자열을 전역 검색한다.</td>
</tr>
<tr>
<td>m</td>
<td>Multi line</td>
<td>문자열의 행이 바뀌더라도 패턴 검색을 계속한다.</td>
</tr>
</tbody></table>
<hr>
<h3 id="정규-표현식을-통한-문제-풀이">정규 표현식을 통한 문제 풀이</h3>
<ol>
<li>알파벳으로 이루어진 문자열 myString과 pat이 주어집니다. myString의 연속된 부분 문자열 중 pat이 존재하면 1을 그렇지 않으면 0을 return 하는 solution 함수를 완성해 주세요.</li>
</ol>
<pre><code class="language-js">function solution(myString, pat) {
    const regExp = new RegExp(pat, &#39;i&#39;);
    return regExp.test(myString) ? 1 : 0;
}</code></pre>
<ol start="2">
<li>문자열 myString이 주어집니다. &quot;x&quot;를 기준으로 해당 문자열을 잘라내 배열을 만든 후 사전순으로 정렬한 배열을 return 하는 solution 함수를 완성해 주세요.
단, 빈 문자열은 반환할 배열에 넣지 않습니다.</li>
</ol>
<pre><code class="language-js">function solution(myString) {
    let answer = [];
      answer = myString.split(&#39;x&#39;).filter(Boolean);
      return answer.sort();
}</code></pre>
<blockquote>
<p><code>filter(Boolean)</code>을 사용하면 해당 분자가 빈 문자이면 포함하지 않는다.</p>
</blockquote>
<ol start="3">
<li>문자열 배열 strArr가 주어집니다. 배열 내의 문자열 중 &quot;ad&quot;라는 부분 문자열을 포함하고 있는 모든 문자열을 제거하고 남은 문자열을 순서를 유지하여 배열로 return 하는 solution 함수를 완성해 주세요.</li>
</ol>
<pre><code class="language-js">function solution(strArr) {
    var answer = [];
    const regExp = /.*ad.*/;
    for (let i = 0; i &lt; strArr.length; i++) {
        if (!regExp.test(strArr[i])) {
            answer.push(strArr[i]);
        }
    }

    return answer;
}</code></pre>
<blockquote>
<p><code>/.*STR.*/</code> 을 사용하게 되면 해당 문자열에서 STR이 포함되어 있는지에 대한 검사를 한다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터를 추가,제거 하고 화면에 렌더링 해보자]]></title>
            <link>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B0-5</link>
            <guid>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B0-5</guid>
            <pubDate>Tue, 24 Oct 2023 13:18:36 GMT</pubDate>
            <description><![CDATA[<p>가장 먼저 생각 해봐야 할 것이 있다. 어떤 방향으로 데이터를 주고 받을 것 인지 </p>
<p>가장 상위의 <code>App</code> 그 하위에 리스트를 보여주는 <code>DataList</code>,
<code>DataList</code>를 추가 삭제할 수 있는 <code>DataEditor</code> 이렇게 트리 형태로 구조가 형성 되어있다.</p>
<p>그러나 리액트에서는 같은 레벨에 있는 컴포넌트끼리는 데이터를 주고 받지 못한다.</p>
<h2 id="🔎-단방향의-리액트">🔎 단방향의 리액트</h2>
<blockquote>
</blockquote>
<p>같은 레벨끼리는 데이터를 주고 받을 수 없다!
그럼 어떻게 데이터를 주고 받고 추가 삭제 할 수 있어?</p>
<p>글로 이해를 하려고 하니 어려운 부분이 있어 그림으로 알아보자 </p>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/e3913f94-19a3-46db-9c63-de7c25b069b1/image.png" alt=""></p>
<h4 id="app">App</h4>
<p><code>DataEditor</code>와 <code>DataList</code>의 공통 부모인 <code>App</code>가 <code>State</code>로 관리를 한다.
이게 무슨 말이지?</p>
<h4 id="datalist">DataList</h4>
<p><code>DataList</code> 에서는 부모인 <code>App</code> 에게 <code>Data</code>를 받아 화면에 렌더링을 해주는 역할</p>
<h4 id="dataeditor">DataEditor</h4>
<p><code>DataEditor</code> 에서는 Data라는 <code>State</code>를 변경할 수 있는 <code>setData</code> 를 통해 변경 해주는 역할</p>
<p>정리를 해보자면</p>
<blockquote>
</blockquote>
<ol>
<li><code>State</code>는 배열이며, [item1] 을 가지고 있다고 가정하자</li>
<li><code>DataList</code>는 <code>Data</code>에서 받은 item1을 <code>prop</code>로 받아 화면에 렌더링 하고 있는 상태</li>
<li><code>DataEditor</code>에서 [item2]를 추가를 하면 <code>setData</code>를 통해 <code>Data</code> 의 값을 바꾸게 된다. </li>
<li>그렇게 되면 <code>State</code>에는 [item1, item2]가 생기게 된다.</li>
<li><code>DataList</code>에는 새로운 데이터가 <code>prop</code> 되고 두개의 아이템이 화면에 렌더링되게 된다.</li>
</ol>
<p>데이터를 수정하는 EVENT는 밑에서 위로, 수정된 데이터를 전달받는 DATA는 위에서 밑으로</p>
<p>그럼 이제 코드를 작성해보러 가자 </p>
<h3 id="🔥-데이터를-추가하여-화면에-렌더링-하기">🔥 데이터를 추가하여 화면에 렌더링 하기</h3>
<ul>
<li>App.jsx</li>
</ul>
<pre><code class="language-jsx">import { useState } from &#39;react&#39;;

function App () {
    const [data,setData] = useState([])

    return(
        &lt;div className=&quot;App&quot;&gt;
          &lt;DataEditor/&gt;
        &lt;DataList dataList={data}/&gt;
      &lt;/div&gt;
    )
}</code></pre>
<p>data를 받아 화면에 렌더링 될 준비가 된 <code>DataList</code>
위의 코드에서 <code>data</code>를 변경 시켜줄 <code>setData</code> 함수를 추가해보자</p>
<pre><code class="language-jsx">import { useState, useRef } from &#39;react&#39;;
import &#39;./App.css&#39;;

import DataEditor from &#39;./DataEditor&#39;;
import DataList from &#39;./DataList&#39;;

function App() {
  const subject = [&#39;국어&#39;, &#39;수학&#39;, &#39;영어&#39;, &#39;과학탐구&#39;, &#39;사회탐구&#39;];

  const [data, setData] = useState([]);

  const dataId = useRef(0);

  const onCreate = (name, content, score) =&gt; {
    const newItem = {
      name,
      content,
      score,
      id: dataId.current,
    };
    dataId.current += 1;
    setData([newItem, ...data]);
  };
  return (
    &lt;div className=&quot;App&quot;&gt;
      &lt;div className=&quot;TitleArea&quot;&gt;
        &lt;h2&gt;커리큘럼&lt;/h2&gt;
        &lt;ul className=&quot;SubjectLuist&quot;&gt;
          {subject.map((it, idx) =&gt; (
            &lt;li key={idx}&gt;{it}&lt;/li&gt;
          ))}
        &lt;/ul&gt;
      &lt;/div&gt;
      &lt;DataEditor onCreate={onCreate} /&gt;
      &lt;DataList dataList={data} /&gt;
    &lt;/div&gt;
  );
}
export default App;
</code></pre>
<ul>
<li><code>dataId</code> - 0값을 참조하는데 newItem을 만들 때 마다 +1씩 증가</li>
<li><code>onCreate</code> - <code>DataEditor</code>에서 호출한 함수 + 상위 컴포넌트에 새로운 데이터 전달</li>
</ul>
<blockquote>
<p>리액트에서는 상위 컴포넌트에서 데이터를 관리, 하위 컴포넌트에 필요한 데이터를 prop로 전달하는 패턴을 가진다.</p>
</blockquote>
<ul>
<li>DataEditor.jsx </li>
</ul>
<p>전 장에서는 버튼을 눌렀을 때 조건을 걸고 맞지 않으면 <code>focus</code>되고 맞으면 <code>state</code>를 콘솔에 저장까지 해보았다.</p>
<pre><code class="language-jsx">const DataEditor = () =&gt; {
  const handleSubmit = () =&gt; {
    onCreate(state.name, state.content, state.score);
  };
};
</code></pre>
<blockquote>
<p><code>handleSubmit</code>함수를 통해 <code>state.name</code>, <code>state.content</code>, <code>state.score</code>을 <code>onCreate</code>의 전달 하게 끔 하는 역할을 한다.</p>
</blockquote>
<ul>
<li>DataList.jsx</li>
</ul>
<pre><code class="language-jsx">const DataList = ({ dataList }) =&gt; {
  return (
    &lt;div className=&quot;DataList&quot;&gt;
      &lt;div&gt;
        {dataList.map((it) =&gt; (
          &lt;DataItem key={it.id} {...it} /&gt;
        ))}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};</code></pre>
<blockquote>
<p><code>dataList</code>를 prop으로 받아 key 값은 <code>it.id</code> <code>...it</code>을 통해 해당 요소의 속성을 <code>DataItem</code>에 전달</p>
</blockquote>
<ul>
<li>DataItem.jsx</li>
</ul>
<pre><code class="language-jsx">const DataItem = ({id, name, content, score}) =&gt; {
    return (
        &lt;div className=&quot;DataItem&quot;&gt;
        &lt;h2&gt;{id}. {name}&lt;/h2&gt;
        &lt;p&gt;{content}&lt;/p&gt;
        &lt;p&gt;{score}&lt;/p&gt;
      &lt;/div&gt;
    )
}
export default DataItem;</code></pre>
<h3 id="🔥-추가한-데이터-기존-데이터-삭제-해보기">🔥 추가한 데이터, 기존 데이터 삭제 해보기</h3>
<blockquote>
<p>데이터를 삭제하기 위해선 해당 데이터가 고유한 값을 가지고 있어야 해당 데이터에 접근을 해서 삭제, 수정이 가능하다. 그렇기에 ID에 접근해 해당 데이터를 삭제해보자</p>
</blockquote>
<ul>
<li>App.jsx</li>
</ul>
<p>각각의 ID에 접근하여 Data를 수정하여 setData에 반영을 해보기 위해 
<code>onDelete</code> 함수를 prop해준다.</p>
<pre><code class="language-jsx">const onDelete = (targetId) =&gt; {
  const newDataList = data.filter((it) =&gt; it.id !== targetId);
  setData(newDataList);
};
{/* 생략 */}

&lt;DataList onDelete={onDelete}/&gt;</code></pre>
<p>현재 상태의 <code>data</code> 는 추가된 Item을 모두 보여주는 상태이기에 
해당 ID를 가진 Item을 제외한 상태를 다시 <code>setData</code>를 통해 상태를 업데이트 시켜준다.</p>
<ul>
<li>DataList.jsx</li>
</ul>
<pre><code class="language-jsx">const DataList = ({ dataList, onDelete }) =&gt; {
    &lt;DataItem onDelete={onDelete}/&gt;
}</code></pre>
<p><code>DataItem</code>은 <code>DataList</code>에 포함이 되어 있기에 <code>DataList</code>가 받은 <code>onDelete</code>를 다시 <code>DataItem</code>에게 <code>prop</code></p>
<ul>
<li>DataItem.jsx</li>
</ul>
<pre><code class="language-jsx">const DataItem = ({ id, name, content, score, onDelete }) =&gt; {
  &lt;button
    onClick={() =&gt; {
      console.log(id); // id가 잘 출력이 되기에
      onDelete(id); // 해당 id 삭제
    }}
  &gt;
    삭제하기
  &lt;/button&gt;;
};
</code></pre>
<p>이렇게 추가, 삭제하는 것을 알아 보았는데 아직 갈길이 멉니다
다음에는 해당 데이터를 수정해보는 것을 배워오겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[컴포넌트를 반복적으로 렌더링해보자]]></title>
            <link>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B0-4</link>
            <guid>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B0-4</guid>
            <pubDate>Mon, 23 Oct 2023 14:06:27 GMT</pubDate>
            <description><![CDATA[<p>오늘은 <code>map()</code> 이라는 JS 내장 함수를 이용하여 반복되는 컴포넌트를 렌더링하는 방법에 대해 공부해보자</p>
<h2 id="🗺️-map-지도아님">🗺️ map() <del>지도아님</del></h2>
<p><code>map()</code>함수를 알아보기 전 간단하게 문법과 예제를 알아보고 가자</p>
<blockquote>
</blockquote>
<p>arr.map(callbak, [thisArg])</p>
<ul>
<li>callback에 해당하는 새로운 배열을 만들기 위한 파라미터는 3가지가 있다.<ul>
<li>currentValue - 현재 처리하고 있는 요소</li>
<li>index - 현재 처리하고 있는 요소의 index 값</li>
<li>array - 현재 처리하고 있는 원본 배열</li>
</ul>
</li>
<li>thisArg - callback 함수 내부에서 사용할 this 레퍼런스</li>
</ul>
<p><strong>항상 느끼는건데 기본이 제일 어려운 법인 것 같다</strong></p>
<p>그래서 예제를 통해 조금 더 알아보자</p>
<h3 id="map-함수의-예제">map() 함수의 예제</h3>
<pre><code class="language-js">let arr = [1, 2, 3, 4, 5];

let multipled = arr.map((num) =&gt; {
  return num * 2;
});

console.log(multipled); // [2, 4, 6, 8, 10]
</code></pre>
<p>위의 코드는 파라미터를 뒤에 2개를 생략했기에 currentValue만으로 새로운 배열을 만들고 있다.
이를 통해서 알 수 있는 것 <code>currentValue</code> - &gt; <code>1, 2, 3, 4, 5</code></p>
<ul>
<li>index(idx) - <code>0, 1, 2, 3, 4</code></li>
<li>array - <code>[1, 2, 3, 4, 5]</code></li>
</ul>
<h3 id="🔥-그럼-이제-렌더링을-하러-가보자">🔥 그럼 이제 렌더링을 하러 가보자</h3>
<p>기본이 가장 중요하기에 위의 코드를 바꿔서 코드를 작성해보자</p>
<h4 id="1-데이터-배열을-생성해보자">1. 데이터 배열을 생성해보자</h4>
<ul>
<li><p>하위 컴포넌트 </p>
<pre><code class="language-jsx">const ChildrenComponent = () =&gt; {
const weathers = [&#39;봄&#39;, &#39;여름&#39;, &#39;가을&#39;, &#39;겨울&#39;, &#39;핵겨울&#39;];

return (
  &lt;div className=&quot;ChildrenComponent&quot;&gt;
    &lt;div&gt;
      {weathers.map((weather) =&gt; (
        &lt;div&gt;{weather}&lt;/div&gt;
      ))}
    &lt;/div&gt;
  &lt;/div&gt;
);
};
export default ChildrenComponent;
</code></pre>
</li>
</ul>
<pre><code>
&gt; 위의 코드는 한가지 문제점이 있다. 무엇일까? 
-&gt; ` Missing &quot;key&quot; prop for element in iterator  `
반복 되는 컴포넌트에 고유한 key 속성을 추가해줘야 한다는 말이다. 

그럼 추가해보자 

```jsx
const ChildrenComponent = () =&gt; {
  const weathers = [&#39;봄&#39;, &#39;여름&#39;, &#39;가을&#39;, &#39;겨울&#39;, &#39;핵겨울&#39;];

  return (
    &lt;div className=&quot;ChildrenComponent&quot;&gt;
      &lt;div&gt;
        {weathers.map((weather,idx) =&gt; (
          &lt;div key={idx}&gt;{weather}&lt;/div&gt;
        ))}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};
export default ChildrenComponent;</code></pre><blockquote>
</blockquote>
<p>여기서도 느낄 수 있는 건 기본이 중요하다. 현재 배열은 딱히 키라고 부를 수 있는 것이 없다.
그렇기에 <code>map</code>함수의 <code>idx</code> 값을 고유의 키 값으로 전달해 주니 문제가 해결 된 것을 볼 수 있다.</p>
<h4 id="2-화면에-렌더링-하기">2. 화면에 렌더링 하기</h4>
<ul>
<li>상위 컴포넌트</li>
</ul>
<pre><code class="language-jsx">import ChildrenComponent from &#39;./ChildrenComponent&#39;;

const ParentComponent = () =&gt; {
  return (
    &lt;div className=&quot;ParentComponent&quot;&gt;
      &lt;ChildrenComponent /&gt;
    &lt;/div&gt;
  );
};
</code></pre>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/8d35625e-a900-4397-865e-edf4967615fd/image.png" alt=""></p>
<p>사실 이거는 정말 간단한 예제였고 이를 통해 데이터를 추가, 제거를 할 수 있는 응용력을 길러보자 </p>
<h3 id="🔥-데이터를-전달-받고-전달-받은-데이터를-렌더링-해보자">🔥 데이터를 전달 받고 전달 받은 데이터를 렌더링 해보자</h3>
<p>상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달해주고 
전달 받은 데이터를 통해 화면에 렌더링 하는것에 대해 알아보자</p>
<h4 id="1-객체를-포함한-배열을-dummylist로-생성--하위-컴포넌트로-prop을-해준다">1. 객체를 포함한 배열을 <code>dummyList</code>로 생성 + 하위 컴포넌트로 prop을 해준다.</h4>
<ul>
<li>상위 컴포넌트</li>
</ul>
<pre><code class="language-jsx">import BottomComponent from &#39;./BottomComponent&#39;;

const TopComponent = () =&gt; {
  const dummyList = [
    { id: 1, 이름: &#39;김동현&#39;, 나이: 22, 생월: 8 },
    { id: 2, 이름: &#39;박동현&#39;, 나이: 21, 생월: 8 },
    { id: 3, 이름: &#39;최동현&#39;, 나이: 29, 생월: 8 },
    { id: 4, 이름: &#39;강동현&#39;, 나이: 27, 생월: 8 },
  ];
  return (
    &lt;div className=&quot;TopComponent&quot;&gt;
      &lt;BottomComponent dummyList={dummyList} /&gt;
    &lt;/div&gt;
  );
};

export default TopComponent;
</code></pre>
<h4 id="2-prop한-데이터를-받아-map-함수를-통해-렌더링을-한다">2. prop한 데이터를 받아 map() 함수를 통해 렌더링을 한다.</h4>
<ul>
<li>하위 컴포넌트 </li>
</ul>
<pre><code class="language-jsx">const BottomComponent = ({ dummyList }) =&gt; {
  return (
    &lt;div&gt;
      {dummyList.map((it) =&gt; (
        &lt;div key={it.id}&gt;
          &lt;p&gt;안녕하세요 {it.이름} 입니다.&lt;/p&gt;
          &lt;p&gt;나이는 {it.나이}입니다.&lt;/p&gt;
          &lt;p&gt;태어난 달은 {it.생월}입니다.&lt;/p&gt;
        &lt;/div&gt;
      ))}
    &lt;/div&gt;
  );
};

export default BottomComponent;
</code></pre>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/e1b3305e-6707-4c41-bf41-3bab3ac8a4ea/image.png" alt=""></p>
<p>잘 렌더링 되는 것을 볼 수 있다. </p>
<p>다음 장에서는 데이터를 추가 또는 제거를 할 수 있는 방법에 대해 알아보자 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React - 유저가 입력한 폼 다루기 2]]></title>
            <link>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B0-3</link>
            <guid>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B0-3</guid>
            <pubDate>Sun, 22 Oct 2023 13:26:41 GMT</pubDate>
            <description><![CDATA[<p>전 장에서는 버튼을 눌렀을 때 유저가 입력한 값을 얻어보았는데, <strong>유저가 입력한 값에 대해 조건</strong>을 
걸고 그 조건이 맞지 않을 시 <code>focus</code>를 해주는 기능에 대해 알아보자</p>
<h2 id="useref">useRef</h2>
<blockquote>
</blockquote>
<pre><code class="language-jsx">const refContainer = useRef(initialValue);</code></pre>
<p>공식문서를 찾아보면 &quot;<code>useRef</code>는 <code>.current</code> 프로퍼티로 전달된 인자 <code>initialValue</code>로 
초기화된 변경 가능한 객체를 반환한다&quot; 이게 무슨 말일까? 코드를 작성해보면서 알아보자 </p>
<h3 id="useref-사용하기">useRef 사용하기</h3>
<p>일단 가장 먼저 useRef는 React에서 사용되는 훅 그렇기에 import를 해준다.</p>
<pre><code class="language-jsx">import {useRef, useState} from &#39;react&#39;;</code></pre>
<p>전 장에서는 유저가 버튼을 클릭 했을 때 <code>console.log</code>에 입력한 값을 출력을 해보았다.
편의를 위해 전 장에 있는 코드는 생략이 되었음에 양해를 구한다.</p>
<pre><code class="language-jsx">const userInput = useRef();
const userTextarea = useRef();
const userSelect = useRef();
...

&lt;input ref={userInput}&gt; ... &lt;/input&gt;
&lt;textarea ref={userTextarea}&gt; ... &lt;/textarea&gt;
&lt;select ref={userSelect}&gt; ... &lt;/select&gt;</code></pre>
<p>이렇게 유저가 입력한 <code>input</code>, <code>textarea</code>, <code>select</code>에 <code>useRef</code>를 할당해준다.
-&gt; <code>userInput</code>, <code>userTextarea</code>, <code>userSelect</code> ref 객체가 각각 
<code>input</code>, <code>textarea</code>, <code>select</code> 요소에 연결이 된다.</p>
<p>그럼 조건을 걸어서 focust를 시켜보자
<code>handleSubmit</code>함수에 조건에 따라 <code>focus</code> 기능 추가해보자</p>
<pre><code class="language-jsx">const handleSubmit = () =&gt; {
  console.log(state);
  if (state.input.length &lt; 5) {
    userInput.current.focus();
    return;
  }
  if (state.textarea.length &lt; 10) {
    userTextarea.current.focus();
    return;
  }
  if (state.select === &quot;default&quot;) {
    userSelect.current.focus();
    return;
  }
  alert(&quot;저장 성공&quot;);
};

</code></pre>
<blockquote>
<p>여기서 알아 두면 좋은 점은 <code>select</code>의 <code>option</code> 중 하나는 <code>default</code>로 값이 설정이 되어 있어야한다는 점 +  <code>state</code>에서 초기 값은 <code>default</code>로 설정 해야한다는 것이다.</p>
</blockquote>
<p>처음엔 되게 어려워 보였는데 간단한거 하나씩 하다 보니까 조금씩 익숙해져서 그런가 재밌네요
12월 달 부터는 사이드 프로젝트 하나 시작하는 것이 목표이고, 그렇게 하기 위해선
퇴근 하고도 꾸준히 공부 하는 것이 중요할 것 같다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React - 유저가 입력한 폼 다루기]]></title>
            <link>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B0-2</link>
            <guid>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B0-2</guid>
            <pubDate>Thu, 19 Oct 2023 05:39:25 GMT</pubDate>
            <description><![CDATA[<h2 id="state를-통한-폼-컨트롤">State를 통한 폼 컨트롤</h2>
<blockquote>
<p>해당 단계에서는 한 개의 폼이 아닌 두개, 세개 그 이상의 폼을 다루는 방법에 대해 알아본다.</p>
</blockquote>
<p>유저가 입력할 수 있는 <code>input</code>, 여러 줄을 적을 수 있는 <code>textarea</code>, 옵션을 정할 수 있는 <code>select</code>에 대해서 알아보자 </p>
<h3 id="🙉-onchange---입력값을-제어하자">🙉 onChange - 입력값을 제어하자</h3>
<p>여기서 추가로 알아야 할 것은 폼(Form)을 다루기 위해선 onChange를 사용한다는 것이다.</p>
<p>입력값을 제어하기 위해 <code>onChange</code>에 대해서 알아보자.</p>
<p>편의를 위해 생략되는 코드가 있음을 양해를 구한다.</p>
<pre><code class="language-jsx">const [input, setInput] = useState(&#39;&#39;);

&lt;input value={input} onChange={(e) =&gt; {
    console.log(e);}}/&gt;</code></pre>
<h4 id="consoleloge에-무엇이-출력될까">console.log(e)에 무엇이 출력될까?</h4>
<p>일단 해당 콘솔창을 보게되면 여러가지가 뜨는데 가장 보이는 것은 <code>InputEvent</code> + <code>Object</code>라는 것</p>
<h4 id="etarget은-input을-가르킨다">e.target은 input을 가르킨다.</h4>
<p>그럼이 <code>input</code>에서의 입력값을 알기 위해선 e.target.value 값에 접근을 해야한다.</p>
<pre><code class="language-jsx">&lt;input value={input} onChange={(e) =&gt; {
    console.log(e.target.value);}}/&gt;</code></pre>
<p>으로 변경을 하게되면 입력을 했을 때 한 글자씩만 콘솔에 뜨는것을 볼 수 있다. </p>
<p>내가 원하는 것은 전체 입력값인데,,,,</p>
<p>내가 입력한 값을 받기 위해 <code>setInput</code>을 통해 얻어보자</p>
<p>폼에서 <code>onChange</code> 이벤트가 일어나면 해당 <code>e.target.value</code> 를 통해 <code>input</code> 값을 읽을 수 있지만 그 순간의 변화만 읽어주기에 <code>setInput</code>함수에 <code>e.tartget.value</code>를 넘겨주어 전체 입력 값을 얻을 수 있다.</p>
<pre><code class="language-jsx">&lt;input value={input} onChange={(e) =&gt; {
    console.log(e.target.value);
    setInput(e.target.value);}}/&gt;</code></pre>
<h4 id="여기서-드는-생각">여기서 드는 생각</h4>
<p>만약 해당 페이지가 회원가입 페이지, 비밀번호 찾기 등 입력폼이 많으면? </p>
<pre><code class="language-jsx">const [a,setA] = useState(&#39;&#39;);
...
...
...
const [z,setZ] = useState(&#39;&#39;);</code></pre>
<p>.... 또 다시 만난 무한굴레 🥵</p>
<h3 id="state를-관리해보자">State를 관리해보자</h3>
<pre><code class="language-jsx">const [state, setState] = useState({
    input: &#39;&#39;,
      textarea: &#39;&#39;,
      select: 1,
});

return (
&lt;div&gt;
  &lt;h2&gt;입력 폼 공부하기&lt;/h2&gt;
  &lt;div&gt;
    &lt;input
      value={state.input}
      onChange={(e)=&gt;{
          setState({
            input: e.target.value,
            textarea: state.textarea,
              select: state.select
        })
      }}
      /&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;textarea 
      value={state.textarea}
      onChnage={(e)=&gt;{
          setState({
            input: state.input,
              textarea: e.target.value,
              select: state.select
        })
      }}
      /&gt;
  &lt;/div&gt;
  &lt;div&gt;
        &lt;select
          value={state.select}
          name=&quot;select&quot;
          onChange={(e) =&gt; {
            setState({
                input: state.input,
                  textarea: state.textarea,
                  select: e.target.value
            });
          }}
        &gt;
          &lt;option value=&quot;1&quot;&gt;1&lt;/option&gt;
          &lt;option value=&quot;2&quot;&gt;2&lt;/option&gt;
          &lt;option value=&quot;3&quot;&gt;3&lt;/option&gt;
          &lt;option value=&quot;4&quot;&gt;4&lt;/option&gt;
          &lt;option value=&quot;5&quot;&gt;5&lt;/option&gt;
        &lt;/select&gt;
      &lt;/div&gt;
&lt;/div&gt;
)</code></pre>
<ol>
<li>둘다 입력 폼의 입력값의 State를 관리하는 역할이니 state로 묶어준다</li>
<li><code>setState</code>에서 <code>input</code>값이 변하는데 <code>textarea</code>값도 같이 변경되면 안된다.</li>
<li>그렇기에 <code>input</code>에 입력을 할 때엔 <code>textarea</code>의 값은 &#39;&#39;가지게 된다.</li>
</ol>
<h4 id="⚙️-여기서-코드를-조금-더-수정해보자---1">⚙️ 여기서 코드를 조금 더 수정해보자 - 1</h4>
<p>어떤 점이 아쉬운가? -&gt; 전 보다는 조금 관리가 쉬워진 것은 맞지만, <code>setState</code>에서 하지 않는것에 대한 값을 계속 불러야 한다는 점이다.</p>
<p><code>...</code>스프레드 연산자를 사용하여 해당코드 수정하기</p>
<pre><code class="language-jsx">import { useState } from &#39;react&#39;;

const UserForm = () =&gt; {
  const [state, setState] = useState({
    input: &#39;&#39;,
    textarea: &#39;&#39;,
    select: 1,
  });

  return (
    &lt;div className=&quot;UserForm&quot;&gt;
      &lt;div&gt;
        &lt;input
          value={state.input}
          onChange={(e) =&gt; {
            setState({
              ...state,
              input: e.target.value,
            });
            console.log(e.target.value);
          }}
        /&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;textarea
          value={state.textarea}
          onChange={(e) =&gt; {
            setState({
              ...state,
              textarea: e.target.value,
            });
            console.log(e.target.value);
          }}
        &gt;&lt;/textarea&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;select
          value={state.select}
          name=&quot;select&quot;
          onChange={(e) =&gt; {
            setState({
              ...state,
              select: e.target.value,
            });
            console.log(e.target.value);
          }}
        &gt;
          &lt;option value=&quot;1&quot;&gt;1&lt;/option&gt;
          &lt;option value=&quot;2&quot;&gt;2&lt;/option&gt;
          &lt;option value=&quot;3&quot;&gt;3&lt;/option&gt;
          &lt;option value=&quot;4&quot;&gt;4&lt;/option&gt;
          &lt;option value=&quot;5&quot;&gt;5&lt;/option&gt;
        &lt;/select&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
};

export default UserForm;

</code></pre>
<blockquote>
<p>여기서 조금 주의해야할 점은 <code>(...)</code>스프레드 연산자를 사용해서 기존 <code>state</code>를 불러오는데 이게 순서가 뒤집어 지면 
바뀐 <code>state</code>를 기존 <code>state</code>로 덮게 된다. 그렇게 되면 아무리 값을 입력해도 바뀐 값에 대해서 알지 못할 것이다.</p>
</blockquote>
<h4 id="⚙️-여기서-코드를-조금-더-수정해보자---2">⚙️ 여기서 코드를 조금 더 수정해보자 - 2</h4>
<blockquote>
<p>위의 코드는 지금 태그 안에서 onChnage를 통해 <code>state</code>를 관리하고 있는데 이렇게 되면 코드가 너무 길어지기에 <code>state</code>를 관리하는 함수를 만들어서 코드를 줄여보자</p>
</blockquote>
<p><strong>state의 변화를 관리하는 <code>handleChnageState</code> 함수를 만든다.</strong></p>
<pre><code class="language-jsx">const handleChnageState = (e)=&gt;{
    setState({
        ...state,
          &quot;변경 되는 값&quot;:e.target.value;
    })
}</code></pre>
<p>위의 코드를 보면 변경되는 값의 변화를 체크하면 되기에 해당 이벤트가 일어나는 폼의 이름만 알면 되기에 &quot;변경 되는 값&quot; -&gt; <code>e.target.name</code>으로 변경하여 코드를 수정해보자 </p>
<pre><code class="language-jsx">import { useState } from &#39;react&#39;;

const UserForm = () =&gt; {
  const [state, setState] = useState({
    input: &#39;&#39;,
    textarea: &#39;&#39;,
    select: 1,
  });

  const handleChnageState = (e) =&gt; {
    setState({
      ...state,
      [e.target.name]: e.target.value,
    });
    console.log(e.target.value);
  };

  return (
    &lt;div className=&quot;UserForm&quot;&gt;
      &lt;div&gt;
        &lt;input name=&quot;input&quot; value={state.input} onChange={handleChnageState} /&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;textarea name=&quot;textarea&quot; value={state.textarea} onChange={handleChnageState}&gt;&lt;/textarea&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;select name=&quot;select&quot; value={state.select} onChange={handleChnageState}&gt;
          &lt;option value=&quot;1&quot;&gt;1&lt;/option&gt;
          &lt;option value=&quot;2&quot;&gt;2&lt;/option&gt;
          &lt;option value=&quot;3&quot;&gt;3&lt;/option&gt;
          &lt;option value=&quot;4&quot;&gt;4&lt;/option&gt;
          &lt;option value=&quot;5&quot;&gt;5&lt;/option&gt;
        &lt;/select&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
};

export default UserForm;
</code></pre>
<p>확실히 한 눈에 <code>onChnage</code>를 했을때 어떠한 행동을 하는지 보여서 깔끔해 진 것 같다 </p>
<h3 id="그럼-최종적으로-유저가-입력한-값을-얻어보자">그럼 최종적으로 유저가 입력한 값을 얻어보자</h3>
<pre><code class="language-jsx">const handleSubmit = () =&gt; {
    console.log(state)
}

&lt;button onClick={handleSubmit}&gt;&lt;/button&gt; </code></pre>
<p>해당 버튼을 누르게 되면 이제 다음과 같은 결과를 얻을 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/40371b58-341e-4965-b9ad-9b8b4d459f4d/image.png" alt=""></p>
<blockquote>
<p>다음 장에서는 <code>useRef</code> 를 통하여 해당 입력값에 조건을 걸어 입력하지 않으면 포커스를 해주는 기능에 대해 알아보자 </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[이메일 폼 작업 - 테이블 태그와 인라인 스타일의 무한 굴레]]></title>
            <link>https://velog.io/@_imhyunnn/%EC%9D%B4%EB%A9%94%EC%9D%BC-%ED%8F%BC-%EC%9E%91%EC%97%85</link>
            <guid>https://velog.io/@_imhyunnn/%EC%9D%B4%EB%A9%94%EC%9D%BC-%ED%8F%BC-%EC%9E%91%EC%97%85</guid>
            <pubDate>Thu, 19 Oct 2023 03:12:47 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>오늘 회사에서 이메일 폼 관련 작업을 하면서 얻게 된 정보를 정리해보려고 한다.</p>
</blockquote>
<h2 id="❗️이메일-폼-작업-전-유의사항">❗️이메일 폼 작업 전 유의사항</h2>
<p>먼저 이미엘 작업을 하기 위해 몇 가지 알아야 할 사실을 체크해보자</p>
<h3 id="1-인라인-스타일inline-style로-작성하자">1. 인라인 스타일(inline style)로 작성하자</h3>
<blockquote>
<p><code>&lt;head&gt;</code>태그 안 <code>&lt;style&gt;</code>태그가 아닌 <code>&lt;div style=&quot;padding:0&quot;&gt;</code>이와 같이 <strong>inline style</strong>로 작성을 해야한다.</p>
</blockquote>
<h4 id="지원하지-않는-style-태그">지원하지 않는 style 태그</h4>
<ul>
<li>국내 대부분의 메일 플랫폼들은 <code>&lt;style&gt;</code>태그를 지원하지 않는다. </li>
</ul>
<h4 id="그렇다면-왜-지원을-하지-않을까">그렇다면 왜 지원을 하지 않을까?</h4>
<ul>
<li>내가 찾아본 결과로는 보안 문제가 큰 문제로 보인다.<ul>
<li>이메일은 스팸, 악의적인 코드로 보안문제가 있을 수 있기에 js, 스타일 시트의 사용을 제한하는 경우가 많다.</li>
</ul>
</li>
</ul>
<h3 id="2-크로스-브라우징을-고려하자">2. 크로스 브라우징을 고려하자</h3>
<blockquote>
<p>여러 브라우저에서 문제 없는 버전이 낮은 CSS의 스타일을 사용해야 한다.</p>
</blockquote>
<h4 id="메일은-브라우저를-통해-열린다">메일은 브라우저를 통해 열린다.</h4>
<ul>
<li>메일을 읽기 위해선 브라우저를 통해 이메일폼을 확인 하는 경우가 대다수이기에 이말은 브라우저를 고려하여 작성해야 한다는 점이다.</li>
</ul>
<h3 id="3-table-태그를-지향하자">3. Table 태그를 지향하자</h3>
<blockquote>
<p>일부 태그의 CSS의 속성이 무시, 다르게 적용이 될 수 있다. 따라서 이메일에 최적화된 테이블 레이아웃을 사용하자</p>
</blockquote>
<h4 id="table-태그-안-table태그의-무한-굴레">table 태그 안 table태그의 무한 굴레</h4>
<ul>
<li>레이아웃을 위하여 <code>&lt;table&gt;</code>안 <code>&lt;table&gt;</code>태그를 반복할 텐데 이때문에 이메일 폼 작성이 어렵고 힘든 일이 될 수 있다.</li>
</ul>
<h2 id="💻-이메일-폼-작업">💻 이메일 폼 작업</h2>
<blockquote>
<p>작업을 하기 전 반드시 알아야 할 사실은 네이버, 다음(국내 이메일 플랫폼) 메일 폼에서는 <code>&lt;html&gt;</code>태그 내에 <code>&lt;body&gt;</code>가 없어지기에 가장 상단 <code>&lt;div&gt;</code> &gt; <code>table</code>를 통해 가장 먼저 레이아웃을 잡아 주는것이 좋다.</p>
</blockquote>
<p>자 그럼 유의사항, 알아야 할 내용에 대해 알아봤으니 이메일 폼을 만들어보자</p>
<h3 id="1-전체-크기를-먼저-잡아보자">1. 전체 크기를 먼저 잡아보자.</h3>
<blockquote>
<p>이메일 폼은 <code>width</code>를 800px 이하로 가져가는 것이 좋다.</p>
</blockquote>
<p>위에서 <code>&lt;body&gt;</code>태그가 없어진다고 <code>&lt;div&gt;</code> &gt; <code>table</code>이렇게 설명하였는데 어떻게 전체 크기를 잡았는지?</p>
<pre><code class="language-html">&lt;body style=&quot;margin: 0; padding: 0&quot;&gt;
  &lt;!-- 이메일 본문 --&gt;
  &lt;div style=&quot;width: 100%; margin: 0; padding: 0&quot;&gt;
    &lt;table style=&quot;max-width: 560px; width: 100%&quot;&gt;&lt;/table&gt;
  &lt;/div&gt;
  &lt;!-- //이메일 본문 --&gt;
&lt;/body&gt;
</code></pre>
<h4 id="고정적인-width보다는-유동적으로-가져가자">고정적인 width보다는 유동적으로 가져가자</h4>
<ul>
<li>저자는 <code>width</code> 값을 고정보다는 <code>max-width</code>를 잡되 레이아웃의 형태를 위하여 <code>width:100%</code>를 통해 크기가 적을 시에도 화면에 꽉 찰 수 있게끔 크기를 조절하였다.</li>
</ul>
<h3 id="2-어떠한-영역을-잡기-위해서-빈-태그-사용하는-것을-지향하기">2. 어떠한 영역을 잡기 위해서 빈 태그 사용하는 것을 지향하기</h3>
<blockquote>
<p>content와 content사이에 빈 공간은 빈 태그를 사용하고 <code>height</code>를 사용해보자</p>
</blockquote>
<pre><code class="language-html">&lt;tr&gt;
  &lt;td style=&quot;height: 400px&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;</code></pre>
<h4 id="셀의-높이를-고정함으로-일관된-디자인을-가져가자">셀의 높이를 고정함으로 일관된 디자인을 가져가자</h4>
<ul>
<li>이는 어떠한 영역의 크기를 정확하게 제어 할 수 있기에 정확성, 일관성을 높일 수 있다.</li>
</ul>
<h3 id="3-마진margin-property-지양하기">3. 마진(Margin Property) 지양하기</h3>
<blockquote>
<p>아직은 Margin Property를 지원하지 않는 곳이 존재한다.</p>
</blockquote>
<h4 id="padding-height를-통하여-여백을-잡기">padding, height를 통하여 여백을 잡기</h4>
<ul>
<li>또한 Padding Property를 사용할 때 인자를 모두 넣는것을 지향해자 <ul>
<li><code>padding: 0 10px 0 10px</code></li>
</ul>
</li>
</ul>
<h3 id="4-이미지-alt-태그-반드시-사용하기">4. 이미지 alt 태그 반드시 사용하기</h3>
<blockquote>
<p>이메일폼에 이미지가 포함된다면, alt 태그는 중요한 내용이다.</p>
</blockquote>
<h4 id="내부-이미지-사용하기">내부 이미지 사용하기</h4>
<ul>
<li>폼 안에 이미지가 있기에 메일의 크기가 증가하고, 이로 인해 전송 시간이 늘어날 수 있다는 점 + 🥵스팸 필터링</li>
</ul>
<h4 id="외부-이미지-사용하기">외부 이미지 사용하기</h4>
<ul>
<li>웹 서버, 호스팅 서버에서 가져오는 방식</li>
<li>이메일의 크기가 줄어들고, 이미지 업데이트시 메일을 수정하지 않아도 된다는 점</li>
</ul>
<h4 id="그렇지만-결국은-사용자의-옵션이-중요하다">그렇지만 결국은 사용자의 옵션이 중요하다</h4>
<p>아무리 사진을 내부, 외부 이미지로 보낸다고 해도 받는 사용자가 이미지 디스플레이 옵션을 제한 해둔다면 외부, 내부 이미지는 소용이 없는 셈💧이다.</p>
<h3 id="5-hex를-통한-색상-이용하기">5. hex를 통한 색상 이용하기</h3>
<blockquote>
<p>RGB, RGBA는 지원하지 않는 경우가 많다.</p>
</blockquote>
<h4 id="hex-코드를-줄이지말자">hex 코드를 줄이지말자</h4>
<ul>
<li>hex 코드는 #000000을 #000으로 단축시킬 수 있지만,
#000000괕이 전체를 다 적어주는 것이 좋다.</li>
</ul>
<h3 id="6-작업이-끝난-후-페이지-검사하기">6. 작업이 끝난 후 페이지 검사하기</h3>
<p>저자가 검사를 하면서 참고한 사이트를 추천</p>
<blockquote>
<p><a href="https://htmlemail.io/inline/">https://htmlemail.io/inline/</a>
UI를 미리 볼 수 있는 사이트</p>
</blockquote>
<blockquote>
<p><a href="https://validator.w3.org/">https://validator.w3.org/</a>
이메일 폼 검사를 할 수 있는 사이트</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/c65d733f-2400-4bae-b234-bbef598a1a92/image.png" alt=""></p>
<p>😅 이렇게 끝이난 것 같지만 아직 한 단계가 더 남았다...</p>
<h3 id="7-검사가-끝난-메일-여러-플랫폼에서-확인하기">7. 검사가 끝난 메일 여러 플랫폼에서 확인하기</h3>
<blockquote>
<p>플랫폼마다 다를 수 있다는 점을 인지하자</p>
</blockquote>
<p>정식 테스트 전 내 계정으로 여러 플랫폼으로 보내서 자체 검사해보기 </p>
<p>저자가 검수할 때 체크한 플랫폼</p>
<ul>
<li>Naver</li>
<li>Daum</li>
<li>Nate</li>
<li>Gmail</li>
<li>Outlook</li>
</ul>
<blockquote>
<p>위의 플랫폼들을 맥 + 윈도우환경에서 검수를 진행했고,
아웃룩에서 레이아웃이 깨지지 않고, 네이버에서 정확하게 나오면 거의 다 나온다고 생각하면 될 것이다.</p>
</blockquote>
<p>다음은 완성 된 결과물 </p>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/2c4beecf-68fc-4363-acd2-5fa633caf9eb/image.png" alt=""></p>
<p>여러 플랫폼에 보내면서 영역이 정상적으로 나오는지에 대해 확인을 했다</p>
<blockquote>
<p>오늘 인라인 스타일을 거의 처음 접하다 보니 생각보다 손이 정말 많이 가는 듯했다.
그렇지만 이 또한 안 해본 것보다는 해보는 것이 경험이기에 좋은 경험이라 생각한다 😀</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[React 장인 되기 -1]]></title>
            <link>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B0-1</link>
            <guid>https://velog.io/@_imhyunnn/React-%EC%9E%A5%EC%9D%B8-%EB%90%98%EA%B8%B0-1</guid>
            <pubDate>Wed, 11 Oct 2023 14:06:11 GMT</pubDate>
            <description><![CDATA[<h1 id="🌐-react">🌐 React</h1>
<blockquote>
<p>리액트는 자바스크립트 라이브러리로 사용자 인터페이스를 만드는데 사용한다.
구조가 MVC, MVW 등인 프레임워크와 달리, 오직 V(View)만을 신경 쓰는 라이브러리이다.</p>
</blockquote>
<h2 id="1-리액트를-공부하기-위해-작업-환경을-설정-해보자">1. 리액트를 공부하기 위해 작업 환경을 설정 해보자</h2>
<blockquote>
</blockquote>
<p>Node.js가 설치 되었다는 전제로 시작한다.
저자는 <code>npm</code>을 통하여 설치를 진행한다.</p>
<ul>
<li><code>npx create-react-app &lt;프로젝트 이름&gt;</code></li>
<li><code>npm create-react-app &lt;프로젝트 이름&gt;</code></li>
</ul>
<p>두개의 명령어가 있는데 무엇이 다를까? </p>
<table>
<thead>
<tr>
<th></th>
<th>npm</th>
<th>npx</th>
</tr>
</thead>
<tbody><tr>
<td><strong>의미</strong></td>
<td>Node.js 패키지 매니저로 사용</td>
<td>패키지를 실행하지만, 설치하지 않음</td>
</tr>
<tr>
<td><strong>사용 목적</strong></td>
<td>패키지 설치 및 전역 명령 실행</td>
<td>일회성 패키지 실행 및 설치 (전역 설치 X)</td>
</tr>
<tr>
<td><strong>실행 방법</strong></td>
<td><code>npm install -g 패키지명</code></td>
<td><code>npx 패키지명</code></td>
</tr>
<tr>
<td><strong>패키지 버전</strong></td>
<td>패키지의 전역 설치 버전 사용</td>
<td>항상 최신 버전을 사용</td>
</tr>
<tr>
<td><strong>특징</strong></td>
<td>패키지 버전 관리가 가능, 여러 프로젝트에서 재사용 가능</td>
<td>글로벌 설치 없이 필요한 패키지를 즉시 실행</td>
</tr>
</tbody></table>
<p>설치가 완료 되었으면, 해당 폴더로 이동 <code>cd 프로젝트 이름</code> -&gt; <code>npm start</code></p>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/04ec15f6-4618-4007-a110-2b1b9f7edcc6/image.png" alt=""></p>
<p>오케이 시작이 반이라고 했으니 반정도 왔다.</p>
<h2 id="2-react-프로젝트의-기본-폴더-구조를-파악해보자">2. React 프로젝트의 기본 폴더 구조를 파악해보자</h2>
<h3 id="2-1-packagejson">2-1. Package.json</h3>
<p>가장 먼저 package.json 파일에 대해 알아보자</p>
<blockquote>
<p>Node.js 프로젝트의 구성 및 의존성 정보를 저장하는 .json 파일 </p>
</blockquote>
<ul>
<li>프로젝트 구성 정보 - 프로젝트의 이름, 버전, 설명 등이 포함
<code>name</code>, <code>version</code>, <code>private</code>, ....</li>
<li>의존성 목록<strong>(dependencies)</strong> - 해당 프로젝트를 실행,개발하는 데 필요한 모든 외부 라이브러리 및 모듈을 포함</li>
<li>스크립트<strong>(scripts)</strong> - 해당 프로젝트를 빌드, 실행, 배포 하기 위한 명령어가 포함
<code>start</code>, <code>build</code>, <code>test</code>, ....</li>
</ul>
<p>스크립트 부분에서 <code>start</code> 부분이 <code>react-scripts start</code>인 것을 보아 
왜 <code>npm start</code>를 했을 때 리액트 프로젝트가 실행이 되는 것을 알 수 있다.</p>
<h3 id="2-2-appjs-indexjs-파일-파헤쳐보기">2-2. App.js, index.js 파일 파헤쳐보기</h3>
<pre><code class="language-js">import React from &#39;react&#39;;</code></pre>
<p>CSS에서 어떠한 파일을 불러와 사용하는 문법이랑 똑같이 생겼다.</p>
<blockquote>
<p>위 코드는 내가 생각한 것 처럼 리앤트를 불러와 사용할 수 있게 해주는데
프로젝트 생성 과정에서 node_modules 폴더에 react 모듈이 설치 되고, 이를 통해 
<code>import</code>문을 통하여 리액트를 불러와 사용할 수 있는 것이다.</p>
</blockquote>
<pre><code class="language-js">import logo from &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;</code></pre>
<blockquote>
<p><code>import</code> 문을 사용하여 다른 파일에서 정의한 내용을 현재 파일로 불러와 사용할 수 있으며, 이를 통해 코드를 모듈화하고 다른 파일에서 정의한 내용을 현재 파일에서 재사용할 수 있다.</p>
</blockquote>
<pre><code class="language-jsx">function App() {
  return (
    &lt;div className=&quot;App&quot;&gt;
        ...
    &lt;/div&gt;
  )
};</code></pre>
<p><code>App</code>이라는 컴포넌트를 <code>function</code> 키워드를 사용하여 컴포넌트를 만들게 되는데 
이를 함수형 컴포넌트라 부른다. 이러한 코드를 <code>JSX</code>라고 부르는데 <code>JSX</code>가 무엇인지 알아보자</p>
<h2 id="3-what-is-jsx">3. What is JSX</h2>
<blockquote>
<p><code>JSX</code>(JavaScript XML) 자바스크립트의 확장 문법으로, JS코드 내에서 HTML과 유사한 구문을 사용하여 UI 컴포넌트를 만들고 렌더링하는 데 도움을 준다.</p>
</blockquote>
<pre><code class="language-jsx">function App() {
    return(
        &lt;div&gt;
            Hello! &lt;b&gt;React&lt;/b&gt;
          &lt;/div&gt;
    )
};</code></pre>
<p>이러한 코드는 다음과 같이 변환이 된다.</p>
<pre><code class="language-js">    function App() {
        return React.createElement(&quot;div&quot;, null, &quot;Hello!&quot;, React.createElement(&quot;b&quot;, null, &quot;React&quot;));
    }</code></pre>
<p><code>JSX</code> 문법을 사용하는 것이 아니라 항상 <code>createElement</code>를 쓰게 되면 불편할 것이다 
그렇기에 <code>JSX</code>를 사용하면 편하게 렌더링을 할 수 있다.</p>
<h3 id="3-1-jsx의-문법">3-1. JSX의 문법</h3>
<blockquote>
<p><code>JSX</code>를 올바르게 사용하기 위해 규칙에 대하여 알아보자 </p>
</blockquote>
<h4 id="1-여러-요소를-감싸는-부모-요소가-반드시-하나가-필요하다">1. 여러 요소를 감싸는 부모 요소가 반드시 하나가 필요하다.</h4>
<pre><code class="language-jsx">import React from &#39;react&#39;;

function App () {
  return (
    &lt;h1&gt;리액트의 JSX 문법 공부&lt;/h1&gt;
    &lt;p&gt;1. 감싸인 요소를 꼭 포함한다.&lt;/p&gt;
  )
}

export default App;</code></pre>
<p>이렇게 되게 되면 제대로 작동하지 않을 것이다.</p>
<p>&quot;JSX 식에는 부모 요소가 하나 있어야 합니다&quot; 라고 에러가 발생하는 것을 볼 수 있다.
위의 식을 에러 없이 제대로 작동하게끔 코드를 수정해보자 </p>
<ol>
<li><code>div</code> 태그 사용하기<pre><code class="language-jsx">import React from &#39;react&#39;;
</code></pre>
</li>
</ol>
<p>function App () {
  return (
    <div>
      <h1>리액트의 JSX 문법 공부</h1>
      <p>1. div 태그로 감싸기</p>
    </div>
  )
}</p>
<p>export default App;</p>
<pre><code>2. `Fragment` 태그 사용하기

```jsx
import React from &#39;react&#39;;

function App () {
  return (
    &lt;React.Fragment&gt;
      &lt;h1&gt;리액트의 JSX 문법 공부&lt;/h1&gt;
      &lt;p&gt;2. 최상위 요소를 두기 싫을 때 Fragment 사용하기&lt;/p&gt;
    &lt;/React.Fragment&gt;
  )
}

export default App;</code></pre><ol start="3">
<li>빈 태그 사용하기 </li>
</ol>
<pre><code class="language-jsx">import React from &#39;react&#39;;

function App () {
  return (
    &lt;&gt;
      &lt;h1&gt;리액트의 JSX 문법 공부&lt;/h1&gt;
      &lt;p&gt;3. 빈 태그 사용하기&lt;/p&gt;
    &lt;/&gt;
  )
}

export default App;</code></pre>
<h4 id="2-자바스크립트-표현식을-사용하는-방법">2. 자바스크립트 표현식을 사용하는 방법</h4>
<p><code>jsx</code>내부에서 js 표현식 사용하기 </p>
<pre><code class="language-jsx">import React from &#39;react&#39;;

function App () {
  const name = &quot;리액트&quot;;
  return (
    &lt;div&gt;
        &lt;h1&gt;{name}의 JSX 문법 공부&lt;/h1&gt;
    &lt;/div&gt;
  )
}

export default App;</code></pre>
<p><code>{}</code>를 사용하여 <code>jsx</code> 내부에서 렌더링 하기 </p>
<h4 id="3-if-문-대신-조건부-연산자를-사용하자">3. if 문 대신 조건부 연산자를 사용하자</h4>
<blockquote>
<p>JSX 내부의 자바스크립트 표현식에서 if문을 사용 할 수 없다.</p>
</blockquote>
<pre><code class="language-jsx">import React from &#39;react&#39;;

function App() {
    const name = &#39;리액트&#39;;
    return &lt;div&gt;{name === &#39;리액트&#39; ? &lt;h1&gt;리액트 입니다.&lt;/h1&gt; : &lt;h1&gt;리액트가 아닙니다&lt;/h1&gt;}&lt;/div&gt;;
}

export default App;</code></pre>
<p><code>JSX</code>내부에선 삼항 연산자를 사용하자 </p>
<h4 id="4-and-연산자를-사용한-조건부-연산자">4. AND 연산자(&amp;&amp;)를 사용한 조건부 연산자</h4>
<blockquote>
<p>아무것도 렌더링을 하고 싶지 않을 때 AND연산자를 사용하자</p>
</blockquote>
<p>위의 <strong>3번에서 배운 조건부 연산자</strong>를 사용하여 <code>null</code>값을 사용하여 아무것도 렌더링 하지 않을 수 있지만
AND 연산자(&amp;&amp;)를 사용하면 더 간결하게 사용할 수 있다.</p>
<pre><code class="language-jsx">import React from &#39;react&#39;;

function App() {
    const name = &#39;리액트&#39;;
    return &lt;div&gt;{name === &#39;리액트&#39; &amp;&amp; &lt;h1&gt;리액트 입니다.&lt;/h1&gt;}&lt;/div&gt;;
}

export default App;</code></pre>
<p><code>name</code>이 &quot;리액트&quot;일 경우 화면에 표시가 되지만 아닐 경우 아무것도 표시가 되지 않는걸 볼 수 있다.</p>
<h4 id="5-인라인-스타일링">5. 인라인 스타일링</h4>
<blockquote>
<p>카멜표기법으로 작성하자</p>
</blockquote>
<pre><code class="language-jsx">import React from &#39;react&#39;;
function App() {
    const name = &#39;리액트&#39;;
    const style = {
        backgroundColor: &#39;black&#39;,
        fontSize: &#39;50px&#39;,
        textAlign: &#39;center&#39;,
        color: &#39;aqua&#39;,
    };
    return &lt;div style={style}&gt;{name}&lt;/div&gt;;
}

export default App;
</code></pre>
<ul>
<li>위와 같이 스타일을 적용할 때에는 문자열이 아닌 객체 형태로 넣어준다.</li>
<li>background-color가 아닌 backgroundColor와 같이 카멜 표기법을 사용한다.</li>
</ul>
<h4 id="6-태그는-꼭-닫아야-한다">6. 태그는 꼭 닫아야 한다.</h4>
<pre><code class="language-js">import React from &#39;react&#39;;

function App() {
    return (
        &lt;div&gt;
            &lt;h2&gt;리액트를 배워보자&lt;/h2&gt;
            &lt;input&gt;
        &lt;/div&gt;
    );
}

export default App;
</code></pre>
<p>해당 코드는 <code>Parsing error : Unterminated JSX contents</code>
즉 모든 태그는 닫는 태그를 사용해야한다.</p>
<p><code>&lt;input /&gt;</code>, <code>&lt;br /&gt;</code> ....</p>
<h4 id="7-주석을-사용할-때-이렇게-사용하자">7. 주석을 사용할 때 이렇게 사용하자</h4>
<p>JS나 HTML에서 사용하는 주석을 사용하게 되면 화면에 표시되게 된다 
그렇기에 <code>{/* ... */}</code>의 형태로 사용하자!</p>
<pre><code class="language-jsx">import React from &#39;react&#39;;
function App() {
    return (
        &lt;&gt;
            &lt;h1&gt;리액트의 JSX 문법 공부&lt;/h1&gt;
              {/* 주석은 이렇게 사용합니다 */}
              // 이렇게 사용하면 화면에 보여지게 됩니다.
              /* 이렇게 사용해도 화면에 보여지게 됩니다.*/
        &lt;/&gt;
    );
}

export default App;
</code></pre>
<h2 id="4-state상태">4. State(상태)</h2>
<blockquote>
<p>컴포넌트 내부에서 바뀔 수 있는 값</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/_imhyunnn/post/38b6b9b0-fdef-4258-b6b7-2362d4e5d157/image.gif" alt=""></p>
<p>React에서 사용하는 State를 알아보기 위해 기본적으로 버튼을 눌렀을 때 
1씩 증가, 1씩 감소 그 값을 화면에 렌더링 하는것을 구현해보자</p>
<ol>
<li>먼저 리액트의 <code>State</code>를 사용하기 위해서는 <code>React</code>를 import 하고 
상태변화에 사용되는 <code>useState</code>를 추가적으로 적어야 한다.</li>
</ol>
<pre><code class="language-jsx">import React, { useState } from &#39;react&#39;;</code></pre>
<blockquote>
<p>Returns a stateful value, and a function to update it
-&gt; &quot;현재 상태 값을 나타내는 변수 + 상태 값을 업데이트하는 함수를 반환한다&quot; 라고 알려준다.</p>
</blockquote>
<ol start="2">
<li><code>useState</code>를 사용하여 상태 값을 초기화, 업데이트 함수를 선언</li>
</ol>
<pre><code class="language-jsx">const [count, setCount] = useState(0);</code></pre>
<blockquote>
<p>배열의 비구조화 할당을 이용하여 다음과 같은 값을 가지게 한다.
<code>count</code> - 상태 값
<code>setCount</code> - 상태 값을 업데이트하는 함수 </p>
</blockquote>
<ol start="3">
<li>상태 값을 업데이트 하는 함수를 만들기</li>
</ol>
<pre><code class="language-jsx">const onIncrease = () =&gt; {
    setCount(count + 1);
};
const onDecrease = () =&gt; {
    setCount(count - 1);
};</code></pre>
<blockquote>
<p>증가,감소 함수를 사용하여 현재 상태 값인 <code>count</code>를 +1, -1씩 하는 함수를 만들어 봤다.</p>
</blockquote>
<ol start="4">
<li>전체 코드를 작성해보자 </li>
</ol>
<pre><code class="language-jsx">import React, { useState } from &#39;react&#39;;

const Counter = () =&gt; {
  const [count, setCount] = useState(0);

  const onIncrease = () =&gt; {
    setCount(count + 1);
  };
  const onDecrease = () =&gt; {
    setCount(count - 1);
  };

  return (
    &lt;div&gt;
      &lt;h2&gt;{count}&lt;/h2&gt;
      &lt;button onClick={onIncrease}&gt;증가 버튼&lt;/button&gt;
      &lt;button onClick={onDecrease}&gt;감소 버튼&lt;/button&gt;
    &lt;/div&gt;
  );
};
</code></pre>
<p>처음 보는 문법이라 아직 익숙하진 않은데 확실한건 js로만 했을 때보다는 더 간결하다는 점 </p>
<ul>
<li><code>useState(0)</code> - 초기 값 0 그렇기에 count가 0으로 출력 되는 걸 볼 수 있다.</li>
</ul>
<h2 id="5-propproperties">5. Prop(Properties)</h2>
<blockquote>
<p>컴포넌트에 데이터 전달하기 </p>
</blockquote>
<p>부모 컴포넌트인 <code>App.js</code> 파일이 있고 자식 컴포넌트인 <code>Counter.js</code>가 있다
위에서 버튼을 눌렀을 때 증감이 되는 함수가 포함된 파일 즉 자식 컴포넌트가 Counter.js</p>
<h3 id="5-1-부모-컴포넌트에서-데이터-내려주기">5-1. 부모 컴포넌트에서 데이터 내려주기</h3>
<h4 id="appjs">App.js</h4>
<pre><code class="language-jsx">import React from &#39;react&#39;;
import Counter from &#39;./Counter&#39;;

function App() {
    return(
        &lt;&gt;
            &lt;Counter initialNumber={5}/&gt;
        &lt;/&gt;
    ) 
}</code></pre>
<h3 id="5-2-자식-컴포넌트에서-데이터-받기">5-2. 자식 컴포넌트에서 데이터 받기</h3>
<h4 id="counterjs">Counter.js</h4>
<pre><code class="language-jsx">import React, { useState } from &#39;react&#39;;

const Counter = (props) =&gt; {
  console.log(props);
  const [count, setCount] = useState(0);

  const onIncrease = () =&gt; {
    setCount(count + 1);
  };
  const onDecrease = () =&gt; {
    setCount(count - 1);
  };

  return (
    &lt;div&gt;
      &lt;h2&gt;{count}&lt;/h2&gt;
      &lt;button onClick={onIncrease}&gt;증가 버튼&lt;/button&gt;
      &lt;button onClick={onDecrease}&gt;감소 버튼&lt;/button&gt;
    &lt;/div&gt;
  );
};

export default Counter;
</code></pre>
<p>부모 컴포넌트에서 데이터를 적기만 한다고 자식 컴포넌트에 전달이 되는것이 아닌
데이터를 받고자 하는 자식 컴포넌트에서 props를 매개변수로 받는다.
이를 <code>console.log</code>에 찍어보면 <code>object</code> 즉 객체로 받는것을 볼 수 있다.</p>
<h4 id="그럼-받은-데이터를-사용해보자">그럼 받은 데이터를 사용해보자</h4>
<p>편의를 위해 코드를 생략하고 작성하겠다</p>
<pre><code class="language-jsx">// App.js
function App() {
  return (
    &lt;&gt;
      &lt;Counter initialNumber={5} /&gt;
    &lt;/&gt;
  );
}


// Counter.js
const Counter = (props) =&gt; {
  const [count, setCount] = useState(props.initialNumber); // 화면에 초기 값이 5로 경 된 것을 볼 수 있다.
};
</code></pre>
<blockquote>
<p><code>props</code>가 console 창에서 객체로 나오기에 그 값에 접근 하기 위해서 props.키값
으로 접근을 하였고 화면에 받은 데이터 </p>
</blockquote>
<h4 id="주고자-하는-데이터가-많을-경우-스프레드-연산자를-활용하자">주고자 하는 데이터가 많을 경우 스프레드 연산자를 활용하자</h4>
<pre><code class="language-jsx">// App.js

function App() {
  const counterProps = {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    f: 5,
  };

  return (
    &lt;&gt;
      &lt;Counter {...counterProps} /&gt;
    &lt;/&gt;
  );
}
</code></pre>
<blockquote>
<p>넘겨주고자 하는 데이터가 많을 경우 태그 안에 나열 보다는 새로운 객체를 생성해서 
스프레드 연산자로 받는것을 지향하자 </p>
</blockquote>
<h4 id="넘겨준-값을-정의-하지-않은-경우-초기-설정-값을-해두자">넘겨준 값을 정의 하지 않은 경우 초기 설정 값을 해두자</h4>
<pre><code class="language-jsx">// App.js

import React from &#39;react&#39;;
import Counter from &#39;./Counter&#39;;

function App() {
  const counterProps = {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    f: 5,
  };
  return (
    &lt;&gt;
      &lt;Counter {...counterProps} /&gt;
    &lt;/&gt;
  );
}

export default App;


// Counter.js

import React, { useState } from &#39;react&#39;;

const Counter = (props) =&gt; {
  const [count, setCount] = useState(props.initialNumber);

  const onIncrease = () =&gt; {
    setCount(count + 1);
  };
  const onDecrease = () =&gt; {
    setCount(count - 1);
  };

  return (
    &lt;div&gt;
      &lt;h2&gt;{count}&lt;/h2&gt;
      &lt;button onClick={onIncrease}&gt;증가 버튼&lt;/button&gt;
      &lt;button onClick={onDecrease}&gt;감소 버튼&lt;/button&gt;
    &lt;/div&gt;
  );
};

export default Counter;
</code></pre>
<p>이렇게 되면 <code>initialNumber</code>이 <code>undefined</code>가 되기에 여기에 연산을 하게 되면 <code>NaN</code>이 렌더링 된다.
이는 오류이기에 해당 코드를 초기 설정값을 통해 이러한 문제를 해결해보자 </p>
<pre><code class="language-jsx">Counter.defaultProps = {
  initialNumber: 0,
};
</code></pre>
<p><code>App.js</code>에 해당 코드를 넣음으로써 <code>NaN</code>이 렌더링 되는것을 방지할 수 있다.</p>
<p>또한 신기한 사실은 부모 컴포넌트의 State의 변경에 따른 자식 요소 컴포넌트도 리렌더링 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript 기초부터 배우기-6]]></title>
            <link>https://velog.io/@_imhyunnn/JavaScript-%EA%B8%B0%EC%B4%88%EB%B6%80%ED%84%B0-%EB%B0%B0%EC%9A%B0%EA%B8%B0-6</link>
            <guid>https://velog.io/@_imhyunnn/JavaScript-%EA%B8%B0%EC%B4%88%EB%B6%80%ED%84%B0-%EB%B0%B0%EC%9A%B0%EA%B8%B0-6</guid>
            <pubDate>Sat, 07 Oct 2023 08:02:20 GMT</pubDate>
            <description><![CDATA[<p>먼저 비동기 프로그래밍을 알아보기 전에 동기 처리와 비동기 처리에 대해서 알아보자</p>
<h2 id="1-동기-처리와-비동기-처리">1. 동기 처리와 비동기 처리</h2>
<blockquote>
</blockquote>
<ul>
<li>동기적으로 작업이란? </li>
<li><blockquote>
<p>순서가 보장 된 처리 방식, 다른 작업을 완료 전 까지 다른 작업을 블로킹(작업 중단)
하는 처리 방식</p>
</blockquote>
</li>
<li>비동기적으로 작업이란? </li>
<li><blockquote>
<p>순서가 보장 되지 않은 처리 방식, 다른 작업이 완료 되기 전에도 블로킹(작업 중단) 
하지 않고 다음 작업을 실행하는 처리 방식</p>
</blockquote>
</li>
</ul>
<h3 id="1-1-동기적-처리-방식">1-1. 동기적 처리 방식</h3>
<p>간단한 예시로 동기적 처리 방식에 대해 알아보자</p>
<pre><code class="language-js">function foo () {
    console.log(&quot;foo&quot;);
}
function bar () {
    console.log(&quot;bar&quot;);
}
foo(); // foo
bar(); // bar</code></pre>
<p>위와 같이 어떠한 작업이 끝이 나고 나서 그 다음 작업을 실행 <strong>순차적</strong> 실행</p>
<h3 id="1-2-비동기적-처리-방식">1-2. 비동기적 처리 방식</h3>
<p>간단한 예시로 비동기적 처리 방식에 대해 알아보자</p>
<pre><code class="language-js">// 위와 같이 실행을 하되 setTimeout으로 바꾸어 실행 해보자
function foo () {
    console.log(&quot;비동기에서 foo&quot;);
}
function bar () {
    console.log(&quot;비동기에서 bar&quot;);
}

setTimeout(foo, 0);
bar();
</code></pre>
<p>실행을 해보면 비동기에서 bar ,비동기에서 foo 이렇게 나오게 된다.
왜 foo가 먼저 실행이 되지 않고 bar가 먼저 실행이 될까?</p>
<h4 id="비동기-코드의-실행-순서와-동기-코드의-실행-순서의-차이때문이다">비동기 코드의 실행 순서와 동기 코드의 실행 순서의 차이때문이다.</h4>
<ol>
<li><code>setTimeout(foo, 0)</code>가 <code>foo</code>를 비동기적으로 실행 되도록 예약</li>
<li>그에 비해 <code>bar</code>는 동기적으로 실행</li>
<li>스택(Stack)에서 <code>bar</code> 함수가 실행 후 출력</li>
<li><code>bar</code> 함수가 실행이 완료 되었기에 스택(Stack)이 비어진 상태</li>
<li><code>foo</code> 함수가 비어 있는 스택(Stack)으로 이동</li>
<li><code>foo</code> 함수가 실행 후 출력</li>
</ol>
<blockquote>
<p>이러한 과정을 거치기에 <code>setTimeout</code> 이 0초라고 하더라도 바로 실행 되지 않는 현상이다.</p>
</blockquote>
<h4 id="콜-스택call-stack">콜 스택(Call Stack)</h4>
<blockquote>
</blockquote>
<p>함수를 호출할 때, 해당 함수의 정보(변수, 매개 변수 등) 스택에 푸쉬(push), 
함수가 실행이 완료 되면 해당 정보를 스택에서 팝(pop)되어 제거 -&gt; 스택이 비어짐</p>
<hr>
<br>


<h2 id="2-promise약속-아님">2. Promise(<del>약속 아님</del>)</h2>
<blockquote>
</blockquote>
<p><strong>Escape Callback Hell</strong>🔥
연속적으로 발생하는 비동기 함수를 처리할 때, 비동기 함수의 결과를 사용하기 위해 콜백 함수가 
중첩되어 복잡해지는 현상을 해결해보자</p>
<h4 id="비동기-작업이-가질-수-있는-3가지-상태를-먼저-알아보자">비동기 작업이 가질 수 있는 3가지 상태를 먼저 알아보자</h4>
<ul>
<li>Pending(대기 상태) - 현재 비동기 작업이 진행중, 비동기 작업이 실행될 수 없는 문제가 발생한 상태</li>
<li>Fulfilled(성공) - 비동기 작업이 정상적으로 완료된 상태 <strong><code>resolve</code></strong></li>
<li>Rejected(실패) - 비동기 작업이 어떠한 이유로 실패한 상태(서버의 응답X, 지연 시간) <strong><code>reject</code></strong></li>
</ul>
<h3 id="2-1-promise가-없는-비동기-처리">2-1. Promise가 없는 비동기 처리</h3>
<p>a, b의 값을 더하고 그 값을 콜백함수에 전달해서 X2를 하고, 또 다시 -X2를 하는 함수를 콜백함수로 나타냈다. </p>
<pre><code class="language-js">function taskA(a, b, cb) {
  setTimeout(() =&gt; {
    const res = a + b;
    cb(res);
  }, 1000);
}

function taskB(a, cb) {
  setTimeout(() =&gt; {
    const res = a * 2;
    cb(res);
  }, 1000);
}

function taskC(a, cb) {
  setTimeout(() =&gt; {
    const res = a * -2;
    cb(res);
  }, 1000);
}

taskA(4, 4, (a_res) =&gt; {
  console.log(&quot;taskA : &quot;, a_res); // taskA : 8
  taskB(a_res, (b_res) =&gt; {
    console.log(&quot;taskB : &quot;, b_res); // taskB : 16
    taskC(b_res, (c_res) =&gt; {
      console.log(&quot;taskC : &quot;, c_res); // taskC : -32
    });
  });
});
</code></pre>
<p>흠 보기만 해도 조금 복잡하기도 하고 이게 줄이 더 길어지면 더 복잡해 질 것이다. 
위의 코드를 promise를 통해 코드를 고쳐보자</p>
<h3 id="2-2-promise로-코드-개선하기">2-2. Promise로 코드 개선하기</h3>
<blockquote>
<p><code>new Promise((resolve, reject) =&gt; {})</code></p>
</blockquote>
<ul>
<li>비동기 작업이 성공 했을 때 <code>(...resolve)</code> 호출</li>
<li>비동기 작업이 실패 했을 때 <code>(...reject)</code> 호출</li>
</ul>
<p>그럼 아까 코드를 수정 해보자 </p>
<pre><code class="language-js">function taskA(a, b) {
  return new Promise((resolve, reject) =&gt; {
    setTimeout(() =&gt; {
      const res = a + b;
      resolve(res);
    }, 1000);
  });
}

function taskB(a) {
  return new Promise((resolve, reject) =&gt; {
    setTimeout(() =&gt; {
      const res = a * 2;
      resolve(res);
    }, 1000);
  });
}

function taskC(a) {
  return new Promise((resolve, reject) =&gt; {
    setTimeout(() =&gt; {
      const res = a * -2;
      resolve(res);
    }, 1000);
  });
}

taskA(4, 4)
  .then((a_res) =&gt; {
    console.log(&quot;taskA : &quot;, a_res);
    return taskB(a_res);
  })
  .then((b_res) =&gt; {
    console.log(&quot;taskB : &quot;, b_res);
    return taskC(b_res);
  })
  .then((c_res) =&gt; {
    console.log(&quot;taskC : &quot;, c_res);
  });
</code></pre>
<p><code>promise</code>를 통해 코드를 개선하였는데 어떠한 점이 이점인지에 대해 알아보자</p>
<ol>
<li><code>promise</code>를 사용함으로 콜백 함수를 직접 전달하지 않아도 된다는 점</li>
<li><code>then</code>체이닝의 사용 : <code>then</code>을 사용함으로 코드의 가독성이 올라갔다는 점</li>
<li>구문이 구분 되다 보니 어떤 작업인지에 대한 파악이 쉽다는 점</li>
<li>위의 코드는 실패에 대한 코드는 다루지 않았지만, 에러 핸들링이 보다 쉬울 것 같다는 점</li>
</ol>
<br>

<pre><code class="language-js">const 코드끊기 = taskA(4, 4).then((a_res) =&gt; {
  console.log(&quot;taskA : &quot;, a_res);
  return taskB(a_res);
});

console.log(&quot;a&quot;)

코드끊기
  .then((b_res) =&gt; {
    console.log(&quot;taskB : &quot;, b_res);
    return taskC(b_res);
  })
  .then((c_res) =&gt; {
    console.log(&quot;taskC : &quot;, c_res);
  });</code></pre>
<p>또한 콜백함수와 달리 중간에 코드를 나눠 어떠한 작업을 추가 할 수 있다는 점이 있다.
그렇지만 아직 복잡한 경향이 있다 그렇기에 이번에는 <code>async</code>, <code>await</code>를 통해 코드를 개선해보자</p>
<hr>
<br>

<h2 id="3-async--await">3. async / await</h2>
<blockquote>
<p><strong>Escape CallbackHell</strong>🔥, <strong>Escape thenHell</strong>🔥</p>
</blockquote>
<h3 id="3-1-async">3-1. async</h3>
<pre><code class="language-js">async function makeAsync() {
    return &quot;Make Async&quot;;
}

console.log(makeAsync()); // Promise {&lt;pending&gt;}</code></pre>
<p><code>async</code>를 붙인 함수<code>makeAsync</code>의 결과값이 <code>promise</code>로 나오는 것을 볼 수 있다 
-&gt; <code>then</code>을 사용 가능한 비동기 처리 함수가 된다</p>
<br>

<pre><code class="language-js">async function makeAsync() {
  return &quot;Make Async&quot;;
}

makeAsync().then((res) =&gt; {
  console.log(res); // Make Async
});</code></pre>
<p><code>return</code>한 값인 &quot;Make Async&quot;가 <code>resolve</code>값으로 쓰이는 것을 알 수 있다.</p>
<h3 id="3-2-await">3-2. await</h3>
<pre><code class="language-js">function delay(ms) {
  return new Promise((resolve) =&gt; {
    setTimeout(resolve, ms);
  });
}

async function makeAsync() {
  await delay(3000);
  return &quot;Make Async&quot;;
}

makeAsync().then((res) =&gt; {
  console.log(res); // 3초 뒤Make Async
});</code></pre>
<ul>
<li><code>await</code> 비동기 함수 앞에 붙이게 되면 비동기 함수를 마치 동기 함수로 사용 할 수 있게 된다.</li>
<li><code>await</code> 함수가 끝나고 나서 뒤에 함수가 실행이 된다.</li>
<li><code>await</code> 함수는 <code>async</code>가 붙은 함수 내에서만 사용 가능하다.</li>
</ul>
<br>

<h3 id="3-3-async-await으로-코드-개선하기">3-3. async, await으로 코드 개선하기</h3>
<pre><code class="language-js">function delay(ms) {
  return new Promise((resolve) =&gt; setTimeout(resolve, ms));
}

async function taskA(a, b) {
  await delay(1000);
  const res = a + b;
  return res;
}

async function taskB(a) {
  await delay(1000);
  const res = a * 2;
  return res;
}

async function taskC(a) {
  await delay(1000);
  const res = a * -2;
  return res;
}

async function main() {
  try {
    const a_res = await taskA(4, 4);
    console.log(&quot;taskA : &quot;, a_res);

    const b_res = await taskB(a_res);
    console.log(&quot;taskB : &quot;, b_res);

    const c_res = await taskC(b_res);
    console.log(&quot;taskC : &quot;, c_res);
  } catch (error) {
    console.log(&quot;Error : &quot;, error);
  }
}

main();
</code></pre>
<ul>
<li><code>async</code>, <code>await</code>를 사용하여 코드를 수정 했는데 확실히 어떠한 작업인지 구분이 간다</li>
<li><code>await</code>을 통하여 비동기 처리 방식 내에서 그 결과를 기다리는 방식으로 작동이 된다.</li>
<li><code>main</code>함수를 통하여 작업이 순서대로 수행되고, 에러핸들링이 된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript 기초부터 배우기 - 5]]></title>
            <link>https://velog.io/@_imhyunnn/javascript-5</link>
            <guid>https://velog.io/@_imhyunnn/javascript-5</guid>
            <pubDate>Fri, 22 Sep 2023 07:15:33 GMT</pubDate>
            <description><![CDATA[<h2 id="1-객체object">1. 객체(Object)</h2>
<blockquote>
<p>객체는 관련된 데이터와 함수의 집합 <strong>(프로퍼티와 메소드)</strong></p>
</blockquote>
<p>다음은 객체를 생성하는 두 가지 방법이다.</p>
<p>객체 생성자</p>
<pre><code class="language-js">let user = new Obejct(); </code></pre>
<p>객체 리터럴 </p>
<pre><code class="language-js">let user = {}; // 객체 리터럴을 사용한 빈 객체 만들기</code></pre>
<p>객체 리터럴을 사용하는 방법이 일반적이고 더 간단하여 자주 사용된다.</p>
<blockquote>
</blockquote>
<ul>
<li>객체에는 여러가지 값들을 넣을 수 있지만, 키와 값 쌍을 넣어야 된다.</li>
<li>키와 값을 쌍으로 가지는 것을 프로퍼티, 객체의 프로퍼티를 통해 데이터를 구조화하고 관리 할 수 있다.</li>
<li>객체의 메서드는 객체가 가지고 있는 함수, 객체 내의 동작 또는 객체와 관련된 동작을 수행한다.</li>
</ul>
<br>

<h3 id="1-1-프로퍼티property와-메소드method">1-1. 프로퍼티(Property)와 메소드(Method)</h3>
<pre><code class="language-js">let user = {
  name: &quot;Hyun&quot;,
  age: 27,
  greet: function() {
      console.log(&quot;Hello, I&#39;m &quot; + this.name + &quot; and I&#39;m &quot; + this.age + &quot; years old.&quot;);
  },
};

user.greet(); // Hello, I&#39;m Hyun and I&#39;m 27 years old.
</code></pre>
<ul>
<li>콜론 <code>:</code>을 사용하여 키와 값을 구분한다.</li>
<li>키에는 문자형, 값에는 모든 <code>type</code>이 사용된다.</li>
<li>객체의 동작을 수행하는 <code>메소드</code> </li>
</ul>
<h3 id="1-2-객체의-값-추가-삭제-변경">1-2. 객체의 값 추가, 삭제, 변경</h3>
<pre><code class="language-js">const user = {
    name: &quot;Hyun&quot;,
      age : 26,
      blood : &quot;B&quot;,
}

user.birth = (&quot;97/08/22&quot;); // 객체의 birth 값 추가하기

console.log(user.birth); // 97/08/22
console.log(user[&quot;birth&quot;]); // 97/08/22

user.age = 27; // 객체의 age 값 변경하기

console.log(user.age); // 27
console.log(user[&quot;age&quot;]); // 27

delete user.blood; // delete를 이용하여 객체의 blood 값 삭제하기

console.log(user.blood); // undefined
console.log(user[&quot;blood&quot;]); // undefined

// delete를 사용하게 되면 메모리에서 지워지지 않는다. 그렇기에 다음과 같은 방법 지향

user.age = null; // null 을 이용하여 객체의 age 값 삭제하기

console.log(user.age); // null</code></pre>
<blockquote>
</blockquote>
<p>왜 상수로 선언된 <code>user</code> 객체를 수정해도 에러가 발생하지 않을까?
-&gt; 객체 내의 프로퍼티 값을 변경하는 것은 상수 객체를 변경하는 것이 아니기 때문이다.</p>
<h3 id="1-3-메소드와-this">1-3. 메소드와 This</h3>
<pre><code class="language-js">let user = {
    name: &quot;Hyun&quot;,
      age : 27,
      greet() {
        console.log(this.name); // this -&gt; 현재 객체를 나타낸다.
    }
};

user.greet(); // Hyun</code></pre>
<h4 id="this의-동작-방식을-알아보자">this의 동작 방식을 알아보자</h4>
<pre><code class="language-js">let user1 = { name: &quot;Dong&quot; };
let user2 = { name: &quot;Hyun&quot; };

function greet() {
    console.log( this.name );    
}

user1.func = greet;
user2.func = greet;

user1.func(); // Dong
user2.func(); // Hyun</code></pre>
<p>이와 같이 <code>this</code>는 . 앞의 객체를 참조하기에 <code>this</code>의 값이 서로 달리즈는 것을 알 수 있다.</p>
<hr>
<br>

<h2 id="2-배열array">2. 배열(Array)</h2>
<blockquote>
<p>여러 개의 값을 <span style=color:#0f0;>순서</span>대로 저장하는 데이터 구조</p>
</blockquote>
<h3 id="2-1-배열-선언하기">2-1. 배열 선언하기</h3>
<pre><code class="language-js">const arr1 = new Array();
const arr2 = [];</code></pre>
<p>대부분 두번째 방법으로 배열을 선언한다.</p>
<h3 id="2-2-배열에-접근-수정하기">2-2. 배열에 접근, 수정하기</h3>
<pre><code class="language-js">let oddNumbers = [1,3,5,7,9];
console.log( oddNumbers[0] ); // oddNumbers[N] 을 통해 N번째 요소에 접근을 할 수 있다.

oddNumbers[4] = 11;
console.log( oddNumbers[4] ); // N번째의 요소 수정하기

console.log( oddNumbers.length ); // 5 length를 통해 배열의 담긴 요소위 갯수 파악하기

console.log( oddNumbers ); // 요소 전체를 출력하기

oddNumbers.push(15);
console.log( oddNumbers[5] ); // push를 통해 배열에 새로운 요소 추가하기</code></pre>
<br>

<h3 id="2-3-배열의-내장함수-알아보기">2-3. 배열의 내장함수 알아보기</h3>
<h4 id="foreach">forEach</h4>
<blockquote>
<p>반복문 for문을 대체 할 수 있다.</p>
</blockquote>
<pre><code class="language-js">const korea = [&quot;서울&quot;, &quot;대구&quot;, &quot;부산&quot;, &quot;경기도&quot;];

for (let i = 0; i &lt; korea.length; i++) {
    console.log(korea[i]);
}</code></pre>
<p>위와 같은 반복문을 <code>forEach</code> 문으로 변경해보자</p>
<pre><code class="language-js">const korea = [&quot;서울&quot;, &quot;대구&quot;, &quot;부산&quot;, &quot;경기도&quot;];

korea.forEach(city =&gt; {
    console.log(city);
});</code></pre>
<blockquote>
<p>forEach 함수의 파라미터 city는 각 원소를 가르키게 된다.</p>
</blockquote>
<br>

<h4 id="map">map</h4>
<blockquote>
<p>새로운 배열을 만들때 유용하다.</p>
</blockquote>
<pre><code class="language-js">const array = [1,2,3,4,5,6,7,8,9,10];

const array2 = [];

array.forEach(el =&gt; {
    array2.push(el * 2);
})

console.log(array2);</code></pre>
<p>새로운 배열을 <code>map</code>을 이용하여 만들어보자</p>
<pre><code class="language-js">const array = [1,2,3,4,5,6,7,9,10];

const array2 = array.map(n =&gt; n * 2);

console.log(array2);</code></pre>
<blockquote>
<p>변화를 주는 함수를 전달하여 새로운 배열 생성</p>
</blockquote>
<br>

<h4 id="indexof">indexOf</h4>
<blockquote>
<p>원하는 원소의 순서 찾기</p>
</blockquote>
<pre><code class="language-js">const korea = [&quot;서울&quot;, &quot;대구&quot;, &quot;부산&quot;, &quot;경기도&quot;];
const index = korea.indexOf(&quot;대구&quot;);

console.log(index); // 1</code></pre>
<blockquote>
</blockquote>
<p>index의 값은 0 부터 시작하여 원소의 순서를 반환
-1이 반환 되는 경우 해당 배열에 없다는 뜻</p>
<br>

<h4 id="findindex">findIndex</h4>
<blockquote>
<p>배열 안에 있는 값이 객체, 배열일 경우 <code>indexOf</code>를 사용 할 수 없어서 <code>findIndex</code>를 사용한다.</p>
</blockquote>
<pre><code class="language-js">const korea = [
  {
    id: 1,
    city: &quot;Seoul&quot;
  },
  {
    id: 2,
    city: &quot;Daegu&quot;
  },
  {
    id: 1,
    city: &quot;Busan&quot;
  },
  {
    id: 1,
    city: &quot;Ulsan&quot;
  }
];
</code></pre>
<p>다음과 같이 배열에 있는 값이 객체일 경우 <code>findIndex</code> 를 통해 원하는 조건을 찾을 수 있다.</p>
<pre><code class="language-js">const korea = [
  {
    id: 1,
    city: &quot;Seoul&quot;
  },
  {
    id: 2,
    city: &quot;Daegu&quot;
  },
  {
    id: 1,
    city: &quot;Busan&quot;
  },
  {
    id: 1,
    city: &quot;Ulsan&quot;
  }
];

const index = korea.findIndex(el =&gt; el.city === &quot;Seoul&quot;);
console.log(index); // 0</code></pre>
<br>

<h4 id="find">find</h4>
<blockquote>
<p><code>findIndex</code>에서 순서가 아닌 값 자체를 반환해준다.</p>
</blockquote>
<pre><code class="language-js">
const korea = [
  {
    id: 1,
    city: &quot;Seoul&quot;
  },
  {
    id: 2,
    city: &quot;Daegu&quot;
  },
  {
    id: 1,
    city: &quot;Busan&quot;
  },
  {
    id: 1,
    city: &quot;Ulsan&quot;
  }
];

const index = korea.find(el =&gt; el.city === &quot;Seoul&quot;);
console.log(index); // {id: 1, city: &quot;Seoul&quot;}</code></pre>
<br>

<h4 id="filter">filter</h4>
<blockquote>
<p>배열에서 특정 조건을 만족하는 값들만 따로 추출하여 새로운 배열 만들기</p>
</blockquote>
<pre><code class="language-js">const korea = [
  {
    id: 1,
    city: &quot;Seoul&quot;,
    visit: true,
  },
  {
    id: 2,
    city: &quot;Daegu&quot;,
    visit: false,
  },
  {
    id: 1,
    city: &quot;Busan&quot;,
    visit: true,
  },
  {
    id: 1,
    city: &quot;Ulsan&quot;,
    visit: false,
  }
];

const visitNoCity = korea.filter(el =&gt; el.visit === false);

console.log(visitNoCity); </code></pre>
<br>

<h4 id="splice">splice</h4>
<blockquote>
<p>특정 항목 제거하기</p>
</blockquote>
<pre><code class="language-js">const array = [10,20,30,40,50];
const index = numbers.indexOf(30);
array.splice(index,1);
console.log(array);</code></pre>
<ul>
<li><code>splice(n,m)</code> 일 때 n에서부터 m개 제거라 생각 하면 쉽고,</li>
<li><code>splice(n)</code>일 때는 n번째 이후로 제거가 된다라 생각 하면 쉽다.</li>
</ul>
<br>

<h4 id="slice">slice</h4>
<blockquote>
<p><code>splice</code>랑 비슷하지만 기존 배열은 건들지 않는다.</p>
</blockquote>
<pre><code class="language-js">const array = [1,2,3,4,5];
const array2 = array.slice(0,2) // 0~2 까지

console.log(array2); // [1,2]
console.log(array); // [1,2,3,4,5]</code></pre>
<h4 id="shift와-pop">shift와 pop</h4>
<blockquote>
<p>배열에서 원소를 추출하기</p>
</blockquote>
<pre><code class="language-js">// shift
const array = [1,2,3,4,5];
const number = array.shift();

console.log(array); // [2,3,4,5]
console.log(number); // 1</code></pre>
<pre><code class="language-js">// pop
const array = [1,2,3,4,5];
const number = array.pop();

console.log(array); // [1,2,3,4]
console.log(number); // 5</code></pre>
<blockquote>
<p><code>shift</code>는 배열의 첫번째 원소, <code>pop</code>은 배열의 마지막 원소 추출</p>
</blockquote>
<br>

<h4 id="unshift">unshift</h4>
<blockquote>
<p>배열의 맨 앞에 새 원소 추가하기</p>
</blockquote>
<pre><code class="language-js">const array = [1,2,3,4,5];
array.unshift(0);

console.log(array);</code></pre>
<br>

<h4 id="concat">concat</h4>
<blockquote>
<p>여러개의 배열을 하나의 배열로 합치기</p>
</blockquote>
<pre><code class="language-js">const arr1 = [1,2,3];
const arr2 = [4,5,6];

const arr3 = arr1.concat(arr2);
console.log(arr3); // [1,2,3,4,5,6]</code></pre>
<blockquote>
<p>합쳐진 배열의 순서는 A.concat(B) 라고 하면 [A,B] 순으로 반환된다.</p>
</blockquote>
<br>

<h4 id="join">join</h4>
<blockquote>
<p>배열 안의 값들을 문자열 형태로 합치기</p>
</blockquote>
<pre><code class="language-js">const array = [1,2,3,4,5];
console.log(array.join()); // 1,2,3,4,5
console.log(array.join(&#39; &#39;)); // 1 2 3 4 5
console.log(array.join(&#39;, &#39;)); // 1, 2, 3, 4, 5</code></pre>
<br>

<h4 id="reduce">reduce</h4>
<blockquote>
<p>해당 배열의 총합을 구할 때 사용한다.</p>
</blockquote>
<pre><code class="language-js">const array = [1,2,3,4,5];

let sum = 0;
array.forEach(n =&gt; {
    sum += n;
});
console.log(sum);</code></pre>
<p>해당 코드를 <code>reduce</code> 를 이용하여 변경해보자</p>
<pre><code class="language-js">const array = [1,2,3,4,5];
let sum = array.reduce((cal, current) =&gt; cal + current, 0);

console.log(sum);</code></pre>
<hr>
<br>

<h2 id="3-비-구조화-할당">3. 비 구조화 할당</h2>
<blockquote>
<p>객체나 배열을 변수에 할당하는 것</p>
</blockquote>
<h3 id="3-1-배열에서의-비-구조화-할당">3-1. 배열에서의 비 구조화 할당</h3>
<pre><code class="language-js">let arr = [&quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;];</code></pre>
<p>다음과 같은 배열이 있다고 생각을 해보자 배열에서의 값을 다 얻을려면 다음과 같이 값을 얻어야 한다.</p>
<pre><code class="language-js">console.log(arr[0]); // one
console.log(arr[1]); // two
console.log(arr[2]); // three
console.log(arr[3]); // four</code></pre>
<p>하나씩 다 호출을 해야하고, 반복적인 부분이 있기에 번거로울 수 있다 </p>
<pre><code class="language-js">let arr = [&quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;];
let [one, two, three, four] = arr;

console.log(one); // one
console.log(two); // two
console.log(three); // three
console.log(four); // four

// 위의 코드를 더 간단하게 수정해보자

let [one, two, three, four] = [&quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;];
console.log(one); // one
console.log(two); // two
console.log(three); // three
console.log(four); // four</code></pre>
<p>arr 배열에서 0번째 인덱스는 one, arr 배열에서 1번째 인덱스는 two ... 이렇게 
one, two, three, four에 index 0, 1, 2, 3번을 할당 한다
배열의 값을 순서대로 할당 받아 사용할 수 있다.</p>
<pre><code class="language-js">let [one, two, three, four, five] = [&quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;];
console.log(five) // undefined</code></pre>
<p>여기서 만약 선언 되지 않는 값에 대해서 값을 넣게 되면 <code>undefinde</code>가 나오게 되는데
<code>undefined</code>가 나오면 안되는 상황이라 하면
배열에서 새로운 값에 기본 값을 설정 하면 된다.</p>
<pre><code class="language-js">let [one, two, three, four, five = &quot;five&quot;] = [&quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;];
console.log(five) // five</code></pre>
<h3 id="3-2-배열에서-값들의-스왑swap">3-2. 배열에서 값들의 스왑(Swap)</h3>
<blockquote>
<p>배열 내에서 두 값을 서로 교환 하는 것</p>
</blockquote>
<pre><code class="language-js">let arr = [1, 2, 3, 4];</code></pre>
<p>배열 <code>arr</code>에서 첫번째 요소와 마지막 요소의 위치를 바꾸어 보자</p>
<pre><code class="language-js">let arr = [1, 2, 3, 4];

let tmp = arr[0];
arr[0] = arr[3];
arr[3] = tmp;

console.log(arr) // 4, 2, 3, 1</code></pre>
<p>어떠한 방식으로 값들이 바꼈는지?</p>
<ol>
<li><code>tmp</code>라는 임시 변수에 <code>arr[0]</code>의 값을 저장</li>
<li><code>arr[0]</code>에 <code>arr[3]</code>값을 넣고, <code>arr[3]</code>에 <code>tmp</code>값을 넣는다</li>
<li>결론 적으로는 <code>arr[0]</code>에 <code>arr[3]</code> 값을 넣고, <code>arr[3]</code>에 <code>arr[0]</code> 값을 넣는 개념</li>
</ol>
<br>
다음은 비 구조화 할등을 사용하여 값들을 스왑 해보는 과정이다.

<pre><code class="language-js">let arr = [1, 2, 3, 4];
[arr[0], arr[3]] = [arr[3], arr[0]];
console.log(arr); // 4, 2, 3, 1</code></pre>
<br >

<h3 id="3-3-객체에서의-비-구조화-할당">3-3. 객체에서의 비 구조화 할당</h3>
<pre><code class="language-js">let object = {one: &quot;one&quot;, two: &quot;two&quot;, three: &quot;three&quot;, four: &quot;four&quot;};</code></pre>
<p>다음과 같은 객체가 있다고 생각을 해보자 객체에서의 값을 새로운 변수에 할당하려면 다음과 같이 해야한다.</p>
<pre><code class="language-js">let one = object.one;
let two = object.two;
let three = object.three;
let four = object.four;

console.log(one, two, three, four); // one two three four</code></pre>
<p>하나씩 다 호출을 해야하고, 반복적인 부분이 있기에 번거로울 수 있다 
비 구조화 할당으로 코드를 조금 더 단순하게 만들어보자</p>
<pre><code class="language-js">let object = {one: &quot;one&quot;, two: &quot;two&quot;, three: &quot;three&quot;, four: &quot;four&quot;};

let {one, two, three, four} = object;
console.log(one, two, three, four);</code></pre>
<p><code>object</code>의 키 값을 기준으로 <code>one</code>이라는 키를 갖는 값을 변수 <code>one</code>에 저장 ...
<code>object</code>의 키 값을 기준으로 <code>four</code>이라는 키를 갖는 값을 변수 <code>four</code>에 저장하는 방식이다.</p>
<blockquote>
<p>객체에서의 비 구조화 할당은 <strong>순서</strong>가 아닌 <code>key</code>값을 기준으로 할당하게 된다. </p>
</blockquote>
<p>객체에서의 비 구조화 할당은 키 값으로 할당을 하기에 변수가 키 값으로 강제되는 경향이 있다.
다음은 키 값으로 얻은 변수의 네이밍을 바꾸는 과정이다</p>
<pre><code class="language-js">let object = {korea: &quot;서울&quot;, japan: &quot;도쿄&quot;, usa: &quot;워싱턴&quot;};

let {usa, korea, japan} = object; // 배열과는 다르게 순서와 상관이 없다는 것을 볼 수 있다.
console.log(korea, japan, usa);

// 그럼 이제 키와 동일한 변수의 네이밍을 바꾸어 보자

let object = {korea: &quot;서울&quot;, japan: &quot;도쿄&quot;, usa: &quot;워싱턴&quot;};
let {usa: 미국, korea: 한국, japan: 일본} = object; // 새로운 변수에 할당하기
console.log(한국, 일본, 미국);</code></pre>
<hr>
<br>

<h2 id="4-정리하는-문제">4. 정리하는 문제</h2>
<ol>
<li>정수 n이 매개변수로 주어질 때 n의 각 자리 숫자의 합을 return하도록 solution 함수를 완성해주세요</li>
</ol>
<pre><code class="language-js">function solution(n) {
    var answer = 0;
    const str = n.toString();

    for( let i = 0; i &lt; str.length; i++) {
        answer += parseInt(str[i])
    }

    return answer;
}</code></pre>
<p>처음에 join해서 구간을 나눠야 했나 했는데 그게 아니였다 숫자를 문자로 변경 후 
그 길이를 체크해서 각각 숫자열로 다시 변환 </p>
<blockquote>
</blockquote>
<p>문자열의 길이를 이용하여 반복문을 통해 자리수 자르기 </p>
<ol start="2">
<li>문자열 배열 strlist가 매개변수로 주어집니다. strlist 각 원소의 길이를 담은 배열을 retrun하도록 solution 함수를 완성해주세요.</li>
</ol>
<pre><code class="language-js">function solution(strlist) {
    const answer = [];
    for(let str of strlist) {
        answer.push(str.length);
    }
    return answer;
}</code></pre>
<p>이걸 풀고나면 다른 사람은 어떻게 풀었는지 볼 수 있는데 같은 문제여도 정말 다 다르다
이렇게도 풀 수 있구나라는 생각도 들더라</p>
<blockquote>
<p>배열로 새로운 배열을 만들 때 <code>map</code>함수가 유용하게 쓰이는 것 같다 다음엔 그렇게 풀어보자</p>
</blockquote>
<ol start="3">
<li>정수가 담긴 배열 array와 정수 n이 매개변수로 주어질 때, array에 n이 몇 개 있는 지를 return 하도록 solution 함수를 완성해보세요.</li>
</ol>
<pre><code class="language-js">function solution(array, n) {
    let answer = 0;
    const array2 = array.filter(el =&gt; el === n)

    answer = array2.length;

    return answer;
}</code></pre>
<p>고민 하다가 이거 <code>filter</code>로 하면 되겠는데? 라고 해서 했는데 처음에 error가 뜨길래 아 아닌가 했는데 fillter로 써버림,,,, 오타 잘 체크하자 그래도 공부한걸 써보니 조금 더 도움이 되었던 것 같다 </p>
<ol start="4">
<li>영어에선 a, e, i, o, u 다섯 가지 알파벳을 모음으로 분류합니다. 문자열 my_string이 매개변수로 주어질 때 모음을 제거한 문자열을 return하도록 solution 함수를 완성해주세요.</li>
</ol>
<pre><code class="language-js">function solution(my_string) {
    const vowels = &#39;aeiouAEIOU&#39;;
    let answer = &#39;&#39;;

    for(let i = 0; i &lt; my_string.length; i++) {
        const str = my_string[i];
        if(vowels.indexOf(str) === -1) {
            answer += str
        }
    }

    return answer
}</code></pre>
<p>나름 진지하게 푼 문제인데 어떻게 풀지 하다가 <code>indexOf</code>를 이용해서 포함이 아니면 -1 반환 하는걸 이용해서 풀었다</p>
<ol start="5">
<li>선분 세 개로 삼각형을 만들기 위해서는 다음과 같은 조건을 만족해야 합니다.
가장 긴 변의 길이는 다른 두 변의 길이의 합보다 작아야 합니다.
삼각형의 세 변의 길이가 담긴 배열 sides이 매개변수로 주어집니다. 세 변으로 삼각형을 만들 수 있다면 1, 만들 수 없다면 2를 return하도록 solution 함수를 완성해주세요.</li>
</ol>
<pre><code class="language-js">function solution(sides) {
    sides.sort((a, b) =&gt; a - b);
    console.log(sides);
    let [a, b, c] = sides;

    return a + b &gt; c ? 1 : 2
}</code></pre>
<blockquote>
</blockquote>
<p>이거 보자마자 비 구조화 할당 해서 변수 값 합쳐서 비교 하면 될 것 같은데
라고 생각 들어서 했는데 정답이여서 기분 좋았음 + <code>sort()</code> + 비교 함수 사용하기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript 기초부터 배우기 - 4]]></title>
            <link>https://velog.io/@_imhyunnn/javascript-4</link>
            <guid>https://velog.io/@_imhyunnn/javascript-4</guid>
            <pubDate>Thu, 21 Sep 2023 11:28:25 GMT</pubDate>
            <description><![CDATA[<p><strong>텍스트</strong>## 1. 함수</p>
<blockquote>
<p>특정 코드를 하나의 명령으로 실핼 할 수 있게 해주는 기능, 어떤 일의 단위
이 장에서는 함수를 알아보자</p>
</blockquote>
<p>함수는 기본적으로 다음과 같은 형식이다.</p>
<pre><code class="language-js">function 함수이름 (매개변수) {
    함수가 할 일;
    return 반환
}</code></pre>
<ul>
<li>매개변수 - 함수에 전달해야되는 내용이 있을 때, 이 함수가 실행될 때 알아야되는 내용이 있을 때 매개변수를 통해 전달한다.</li>
<li>retrun - <code>반환값</code>, 함수 완료 후, 반환되어야 하는 값이 있을 때 사용한다.</li>
</ul>
<h3 id="1-1-함수의-기본">1-1. 함수의 기본</h3>
<blockquote>
<p>함수를 선언하고, 지역 변수와 외부 변수를 알아보자</p>
</blockquote>
<h4 id="함수-선언-지역-변수">함수 선언, 지역 변수</h4>
<pre><code class="language-js">function showMessage() { // 함수 선언
    let message = &quot;안녕하세요&quot;; // 지역 변수
      console.log( message ); // 안녕하세요가 출력 된다
};

showMessage(); // 안녕하세요가 출력 된다

console.log( message ); // ReferenceError: message is not defined</code></pre>
<p>왜 이런 결과가 나올까?</p>
<ul>
<li>message는 <code>showMessage</code> 함수의 지역 변수 이기에 외부에서는 호출이 되지 않는 성질을 가지기 떄문이다. 
그럼 외부에서 호출이 가능한 변수도 있을까? 그게 외부 변수이다.</li>
</ul>
<h4 id="외부-변수">외부 변수</h4>
<blockquote>
<p>함수에선 외부 변수에 접근, 수정이 가능하다.</p>
</blockquote>
<pre><code class="language-js">let userName = &quot;John&quot;;

function showMessage() {
    userName = &quot;Bob&quot;; // (1)
      let message = &quot;hello&quot; + userName;
      console.log(message);
};

console.log( uesrName ); // (2) John이 출력된다.

showMessage(); // (3)

console.log( userName ); // (4) Bob이 출력된다.</code></pre>
<p>(1) - 외부 변수 <code>userName</code>을 함수 내부에서 수정함
(2) - 수정한 함수를 호출하지 않기에 John이 출력된다.
(3) - 수정한 함수를 호출
(4) - 외부 변수를 수정한 함수에 의해 Bob으로 출력이 된다.</p>
<h3 id="1-2-함수-이름-짓기">1-2. 함수 이름 짓기</h3>
<blockquote>
<p>동작을 수행하기 위한 코드</p>
</blockquote>
<ul>
<li>show - <code>showMessage()</code> 
  무언가를 보여주는 함수</li>
<li>get - <code>getAge()</code>
  값을 반환</li>
<li>calc - <code>calcSum()</code>
  무언가를 계산</li>
<li>create - <code>createForm()</code>
  무언가를 생성</li>
<li>check - <code>checkPermission()</code>
  무언가를 확인하고 불린값을 반환</li>
</ul>
<p>함수는 동작 하나만 담당해야 한다.</p>
<ul>
<li>getAge - 함수는 나이를 얻어오는 동작만 해야한다.</li>
<li>createForm - 함수는 form을 만들고 이를 반환하는 동작을 해야 한다.</li>
<li>checkPermission - 함수는 승인 여부를 확인하고 그 결과를 반환하는 동작만 해야한다.</li>
</ul>
<h2 id="2-함수-표현식function-expression">2. 함수 표현식(Function Expression)</h2>
<h3 id="2-1-함수-표현식-함수-선언문의-다른점---문법">2-1. 함수 표현식, 함수 선언문의 다른점 - 문법</h3>
<pre><code class="language-js">// 함수 선언문
function sum(a,b) {
    return a + b;
}</code></pre>
<pre><code class="language-js">// 함수 표현식
let sum = function(a,b) {
    retrun a+ b;
};</code></pre>
<h3 id="2-2-함수-표현식-함수-선언문의-다른점---함수의-생성-시점">2-2. 함수 표현식, 함수 선언문의 다른점 - 함수의 생성 시점</h3>
<pre><code class="language-js">// 함수 선언문
greet(&quot;Hyun&quot;); // 안녕하세요! Hyun님 출력

function greet(name) {
    console.log(`안녕하세요! ${name}님`);
}</code></pre>
<ul>
<li>함수 선언문 - 코드 실행전 호이스팅되어 함수가 정의된 위치에 상관없이 코드 어디서든 호출이 가능</li>
</ul>
<pre><code class="language-js">// 함수 표현식
greet(&quot;Hyun&quot;); // TypeError: greet is not a function

const greet = function(name) {
    console.log(`안녕하세요! ${name}님`);
};</code></pre>
<ul>
<li>함수 표현식 - 함수를 변수에 할당하기에 변수가 할당된 이후에 호출이 가능하다
변수에 값이 할당되기에 변수에 대한 스코프 규칙을 따른다.</li>
</ul>
<h2 id="3-콜백함수callback-function">3. 콜백함수(Callback Function)</h2>
<blockquote>
<ul>
<li>어떠한 함수가 실행이 끝난 뒤 호출되는 함수</li>
</ul>
</blockquote>
<ul>
<li>함수가 어떤 이벤트가 발생, 특정 시점에서 호출 되게끔 하는 함수</li>
<li>주로 비동기 작업에서 사용이된다.</li>
</ul>
<pre><code class="language-js">function fetchData(url, callback) {
    console.log(`데이터를 ${url}에서 가져오는 중..`);
      setTimeout(function() {
    const data = &quot;가져온 데이터&quot;;
       callback(data); // 콜백 함수 호출
    }, 2000);
}

fetchData(&quot;https://example.com/data&quot;, function(result){
    cosnole.log(`데이터를 가져오는데 성공했습니다 ${result}`);
})</code></pre>
<ol>
<li><code>fetchData</code> 함수가 호출되면서 데이터를 가져오는 중.. 메시지 호출</li>
<li>2초 후 <code>setTimeout</code> 내부의 <strong>콜백 함수</strong>가 실행되고, 가져온 데이터가 <code>callback</code>을 통해 전달</li>
<li><code>fetchData</code> 함수 완료 후 데이터를 가져오는데 성공했다는 메시지 출력</li>
</ol>
<p>-&gt; <code>콜백 함수</code>는 주로 비동기 작업의 완료를 처리하거나 특정 이벤트가 발생할 떄 실행되어야 하는 작업을 할 때 사용한다.</p>
<h2 id="4-화살표-함수arrow-function">4. 화살표 함수(Arrow Function)</h2>
<blockquote>
<p>함수 표현식보다 단순하고 간결하게 함수를 만들기</p>
</blockquote>
<pre><code class="language-js">let func = (arg1, arg2, ... argN) =&gt; experssion</code></pre>
<ul>
<li><code>arg1, ..argN</code>을 인자로 받는 함수 <code>func</code> 생성</li>
<li><code>func</code> 함수는 <code>=&gt;</code> 우측의 표현식(expression)을 평가하고 결과를 반환</li>
</ul>
<h4 id="함수-표현식을-화살표-함수로-변경하기">함수 표현식을 화살표 함수로 변경하기</h4>
<pre><code class="language-js">function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

ask(
  &quot;동의하십니까?&quot;,
  function() { alert(&quot;동의하셨습니다.&quot;); },
  function() { alert(&quot;취소 버튼을 누르셨습니다.&quot;); }
);</code></pre>
<pre><code class="language-js">let ask = (question, yes, no) =&gt; confirm(question) ? yes() : no();

ask(
  &quot;동의하십니까?&quot;,
  () =&gt; alert(&quot;동의하셨습니다.&quot;),
  () =&gt; alert(&quot;취소 버튼을 누르셨습니다.&quot;)
);
</code></pre>
<h2 id="5-함수-내용-정리하는-문제">5. 함수 내용 정리하는 문제</h2>
<ol>
<li>이름 매개변수로 전달받아 다양한 이름 프린트하는 함수 만들기<pre><code class="language-js">const greet = function (name) {
console.log(`안녕하세요 저는 ${name}입니다.`);
};
</code></pre>
</li>
</ol>
<p>greet(&quot;동현&quot;);</p>
<pre><code>
2. 다음 조건에 맞는 `meetAt` 함수 만들기 
* 인자를 세개 받는다
* 첫번째 인자는 년도에 해당하는 숫자
* 두번째 인자는 월에 해당하는 숫자
* 세번째 인자는 일에 해당하는 숫자
* 년도 인자만 받았을 경우 -&gt; &quot;1111년&quot;과 같은 형식의 문자열을 리턴
* 년도,월 인자 받았을 경우 -&gt; 년도와 월을 조합 &quot;1111년 1월&quot; 같은 형식의 문자열 리턴
* 년도,월,일 인자 받았을 경우 -&gt; &quot;년도/월/일&quot;과 같은 형식의 문자열 리턴

```js
const meetAt = function (year, month, date) {
  let todayYear = year;
  let todayMonth = month;
  let todayDate = date;

  if (todayDate) {
    return `${year}/${month}/${date}`;
  }
  if (todayMonth) {
    return `${year}년 ${month}월 입니다.`;
  }
  if (todayYear) {
    return `${year}년 입니다.`;
  }
};

console.log(meetAt(1997, 08,22));</code></pre><blockquote>
<ul>
<li>처음에 <code>todayYear</code>를 가장 위로 올리고 <code>todayDate</code>를 가장 밑에 했더니 
계속 년도만 표시 되었다 <code>return</code>은 첫 번째 조건이 만족되면 함수가 즉시 반환되는 
특성을 몰랐기에 발생한 문제였다.</li>
</ul>
</blockquote>
<ol start="3">
<li><code>findSmallestElement</code> 함수 구현하기</li>
</ol>
<ul>
<li>위 함수의 arr 인자는 숫자 값으로만 이루어진 배열입니다.</li>
<li>arr의 값들 중 가장 작은 값을 리턴해주세요.</li>
<li>만약 arr 비어있다면 0을 리턴 해주세요.</li>
<li>ex) 다음과 같은 배열이 인자(input)으로 들어왔다면 0이 리턴 되어야 한다
[100, 200, 3, 0, 2, 1]</li>
</ul>
<pre><code class="language-js">function findSmallestNumber(arr) {
  let result = arr[0];
  if (arr.length === 0) {
    return 0;
  }
  for (let i = 1; arr.length &gt; i; i++) {
    if (result &gt; arr[i]) {
      result = arr[i];
    }
  }
  return result;
}

let smallestNumber = findSmallestNumber([1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10]);

console.log(smallestNumber);</code></pre>
<p><code>for</code>문을 <code>forEach</code>문으로 바꿔보자 </p>
<pre><code class="language-js">function findSmallestNumber(arr) {
  let result = arr[0];
  if (arr.length === 0) {
    return 0;
  }

  arr.forEach(function (num) {
    if (result &gt; num) {
      result = num;
    }
  });
  return result;
}

let smallestNumber = findSmallestNumber([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

console.log(smallestNumber);</code></pre>
<blockquote>
<ul>
<li>이 문제의 포인트는 비교를 해서 작은 값이 나오면 다음값과 비교를 하는 것 그러고 끝이 되었을 때 작은 값을 return하는 것이다.</li>
</ul>
</blockquote>
<ol start="4">
<li>돈을 바꿔주는 함수 만들기</li>
</ol>
<ul>
<li>매개변수로 돈의 금액이 들어간다</li>
<li>금액이 들어가면 몇 개의 지폐와 동전이 필요한지 최소 개수를 계산해준다.</li>
<li>지폐의 기준은 한국으로 한다. (5만원, 1만원, 5천원, 1천원, 500원, 100원)</li>
<li>ex) 12500인 경우 
10000 X 1, 1000 X 2, 500 X 1</li>
</ul>
<pre><code class="language-js">let unit = [50000, 10000, 5000, 1000, 500, 100];

function calcChages(money) {
  let result = &quot;&quot;;
  for (let i = 0; i &lt; unit.length; i++) {
    let count = Math.floor(money / unit[i]);
    if (count &gt; 0) {
      result += `가장 최소 지폐는 ${unit[i]} X ${count}장 입니다.\n`;
    }

    money = money - unit[i] * count;
  }
  return result;
}

const chageDetails = calcChages(234500);
console.log(chageDetails);</code></pre>
<blockquote>
<ul>
<li>기준이 되는 배열을 만든다</li>
</ul>
</blockquote>
<ul>
<li>나머지는 버린다. <code>Math.floor</code></li>
<li>해당 결과값을 변수에 저장하고 반환한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript 기초부터 배우기 - 3]]></title>
            <link>https://velog.io/@_imhyunnn/javascript-3</link>
            <guid>https://velog.io/@_imhyunnn/javascript-3</guid>
            <pubDate>Tue, 19 Sep 2023 14:43:02 GMT</pubDate>
            <description><![CDATA[<h2 id="1-조건문">1. 조건문</h2>
<blockquote>
<p>조건문을 사용하면 특정 조건이 만족했을 때 특정 코드를 실행 할 수 있는 구문</p>
</blockquote>
<h3 id="1-1-if문">1-1. if문</h3>
<blockquote>
<p><code>if</code>(...)문은 괄호 안에 들어가는 조건을 평가, 그 결과가 <code>true</code>이면 해당 코드 블럭이 실행
-&gt; 괄호 안의 표현식을 평가 -&gt; 불린 값으로 변환</p>
</blockquote>
<ul>
<li>숫자 <code>0</code>, 빈 문자열 <code>&quot;&quot;</code>, <code>null</code>, <code>undefined</code>, <code>Nan</code> 모두 불린형으로 변환 시 <code>false</code></li>
</ul>
<pre><code class="language-js">const number = 1;
if(a + 1 === 2) {
    console.log(&quot;정답입니다.&quot;); // ()안의 조건이 true이니 정답입니다가 출력이 된다.
};</code></pre>
<p>그럼 a 의 값을 바꾼다면?</p>
<pre><code class="language-js">const number = 9;
if(a + 1 === 2) {
    console.log(&quot;정답입니다.&quot;); // ()안의 조건이 false이니 아무것도 출력이 되지 않는다.
};</code></pre>
<h3 id="1-2-if-else문">1-2. if-else문</h3>
<blockquote>
<p><code>if</code>(...)문의 괄호 안에 들어가는 조건을 평가하고 그 결과가 <code>false</code>일 때 실행되게 끔 하는 코드 블럭</p>
</blockquote>
<pre><code class="language-js">const number = 9;
if(a + 1 === 2) {
    console.log(&quot;정답입니다.&quot;); 
} else {
    console.log(&quot;오답입니다/&quot;); // ()안의 조건이 false이니 else문의 코드 블럭이 실행된다. 오답입니다가 출력이 된다.
}; </code></pre>
<p>특정 조건이 만족할 때와 만족하지 않을 때 서로 다른 코드를 실행해야 된다면 <code>if-else</code>문을 사용 할 수 있다.</p>
<h3 id="1-3-if-else-if문">1-3. if-else if문</h3>
<blockquote>
<p>여러 조건에 따라 다른 코드 블럭을 실행해야할 때 사용한다.</p>
</blockquote>
<pre><code class="language-js">const rank = 60;

if (rank &gt;= 90) {
    console.log(&quot;A+&quot;);
} else if (rank &gt;= 65) {
    console.log(&quot;B+&quot;);
} else {
    console.log(&quot;F&quot;); // 위 두개의 조건이 모두 충족이 되지 않았기에 F가 출력
}</code></pre>
<p>위의 조건식을 보면 지금은 위의 두 조건이 충족이 되지 않아 F가 출력 되었지만, 
값이 올라가면 B+, A+이 출력 될 수 있다. 
그렇기에 <code>if-else if</code>문은 여러 조건이 있을 때 사용하면 유용하다.</p>
<h3 id="1-4-switchcase-문">1-4. switch/case 문</h3>
<blockquote>
<p>switch/case 문은 특정 값이 무엇이냐에 따라 다른 코드 블럭을 실핼 할 때 사용한다.</p>
</blockquote>
<pre><code class="language-js">const device = &#39;iphone13&#39;;

switch (device) {
  case &#39;iphone13&#39;:
    console.log(&#39;아이폰 15로 바꾸고 싶어요&#39;);
    breack;
  case &#39;iphone14&#39; : 
    console.log(&#39;아이폰 15로 바꾸고 싶어요&#39;);
      breack;
  case &#39;iphone15&#39; : 
    console.log(&#39;아이폰 15 pro로 바꾸고 싶어요&#39;);
    break;
  default:
    console.log(&#39;아이폰 15가 최고입니다.&#39;);
}</code></pre>
<p>device 값을 &#39;iphone13&#39;, &#39;iphone14&#39;, &#39;iphone15&#39; 에 따라 다른 코드 블럭이 실행이 된다.
가장 밑의 default는 case로 준비하지 않는 값일 경우 실행 되는 코드 블럭이다.</p>
<h2 id="2-반복문">2. 반복문</h2>
<blockquote>
<p>특정 작업을 반복적으로 할 때 사용할 수 있는 구문</p>
</blockquote>
<h3 id="2-1-for">2-1. for</h3>
<blockquote>
<p>가장 기본적인 반복문 우리가 정한 조건이 만족 -&gt; 반복</p>
</blockquote>
<pre><code class="language-js">for( let i = 0; i  &lt; 10; i ++) {
    console.log(i); // 0 부터 9 까지 출력
}</code></pre>
<h3 id="2-2-while">2-2. while</h3>
<blockquote>
<p>특정 조건이 참 -&gt; 반복, 언젠간 false가 되도록 해야함 </p>
</blockquote>
<pre><code class="language-js">let i = 0;
while (i &lt; 10) {
  console.log(i);
  i++;
}</code></pre>
<p>조건문 내부에서 변화를 직접 주어야 성립</p>
<h3 id="2-3-for-of">2-3. for of</h3>
<blockquote>
<p>배열을 위한 반복문</p>
</blockquote>
<pre><code class="language-js">let numbers = [1, 2, 3, 4, 5, 6];
for (let number of numbers ) {
    console.log(number); // 1 부터 6 까지 출력
}</code></pre>
<h3 id="2-4-forin">2-4. for...in</h3>
<blockquote>
<p>객체를 위한 반복문</p>
</blockquote>
<pre><code class="language-js">const user = {
    name : &quot;Hyun&quot;,
      height : &quot;200&quot;,
      age : 27, 
};

console.log(Object.entries( user ));
console.log(Object.keys( user ));
console.log(Object.values( user ));</code></pre>
<ul>
<li><code>Object.entries</code> - <code>[[키, 값], [키, 값]]</code> 형태의 배열로 변환</li>
<li><code>Object.keys</code> - <code>[키, 키, 키]</code> 형태의 배열로 변환</li>
<li><code>Object.values</code> - <code>[값, 값, 값]</code> 형태의 배열로 변환</li>
</ul>
<p>위의 코드를 <code>for ... in</code>으로 전환해보자</p>
<pre><code class="language-js">const user = {
    name : &quot;Hyun&quot;,
      height : &quot;200&quot;,
      age : 27, 
};

for (let key in user) {
    console.log(key, user[key]);
};</code></pre>
<p>둘 중 상황에 맞게끔 사용하면 될 듯 하다</p>
<h2 id="3-정리하는-문제">3. 정리하는 문제</h2>
<ol>
<li>유저가 입력하는 숫자가 0인지 음성인지 양성인지 판단하는 로직 짜기</li>
</ol>
<pre><code class="language-js">const score = 1;

if (score &lt; 0){
    console.log(&quot;음수입니다.&quot;);
} else if (score &gt; 0) {
    console.log(&quot;양수입니다.&quot;)
} else {
    console.log(&quot;0입니다.&quot;)
}</code></pre>
<ol start="2">
<li>레포트 점수에 따른 등급을 메기는 로직 짜기</li>
</ol>
<pre><code class="language-js">const score = 100;
let grade = &#39;&#39;

if (score &gt;=90 &amp;&amp; score &lt;= 100) {
    grade = &#39;A&#39;;
} else if (score &gt;= 80 &amp;&amp; score &lt;= 89) { 
    grade = &#39;B&#39;;
} else if (score &gt;= 70 &amp;&amp; score &lt;= 79) {
    grade = &quot;C&quot;;
} else if (score &gt;= 60 &amp;&amp; score &lt;= 69) {
    grade = &quot;D&quot;;
} else if (score &gt;= 0 &amp;&amp; score &lt;= 59) {
    grade = &quot;F&quot;;
} else {
    cosnole.log(&quot;점수를 다시 입력해주세요&quot;);
}</code></pre>
<ol start="3">
<li><code>지원자의 스택이 [&quot;HTML&quot;, &quot;CSS&quot;, &quot;JavaScript&quot;, &quot;React&quot;]</code> 가 있다 
이 중 JS, React 둘다 가능하면 &quot;합격&quot;, 둘 중 하나만 할 줄 알면 &quot;예비&quot;, 두 스킬이 없으면 &quot;탈락&quot;하는 로직 짜기</li>
</ol>
<pre><code class="language-js">let userSkills = [&quot;HTML&quot;, &quot;CSS&quot;, &quot;JavaScript&quot;, &quot;React&quot;];

if (userSkills.includes(&quot;JavaScript&quot;) &amp;&amp; userSkills.includes(&quot;React&quot;)) {
    console.log(&quot;합격&quot;);
} else if (userSkills.includes(&quot;JavaScript&quot;) || userSkills.includes(&quot;React&quot;)) {
    console.log(&quot;예비&quot;);
} else {
    cosnole.log(&quot;탈락&quot;);
}</code></pre>
<ol start="4">
<li>프로그래머스 코테 연습 문제 1
정수 배열 <code>numbers</code>가 매개변수로 주어집니다. <code>numbers</code>의 원소의 평균값을 return하도록 solution 함수를 완성해주세요.</li>
</ol>
<pre><code class="language-js">function solution(numbers) {
    var answer = 0;
    var sum = 0;
    for (let i = 0; i &lt; numbers.length; i++) {
        sum += numbers[i];
        answer = sum / numbers.length;
    }

    return answer;
}</code></pre>
<ol start="5">
<li>프로그래머스 코테 연습 문제 2
정수 n이 주어질 때, n이하의 짝수를 모두 더한 값을 return 하도록 solution 함수를 작성해주세요.</li>
</ol>
<pre><code class="language-js">function solution(n) {
    var answer = 0;
    for (var i = 0; i &lt;= n; i += 2) {
        answer += i;
    }
    return answer;
}</code></pre>
<p>범위가 작은 것 부터 하나씩 해결 하기 조건에 대한 생각을 천천히 해보면 될 듯 하다
아직은 익숙하지 않아서 그런 느낌인데 하다 보면 많이 늘 것이다.</p>
]]></description>
        </item>
    </channel>
</rss>