<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>daymoon_.log</title>
        <link>https://velog.io/</link>
        <description>미지의 공간🌙</description>
        <lastBuildDate>Wed, 27 Jul 2022 15:12:07 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>daymoon_.log</title>
            <url>https://velog.velcdn.com/images/daymoon_/profile/d36a742d-21bc-4e5e-a1e7-8334c8f4c5aa/image.gif</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. daymoon_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/daymoon_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Git : Github 토큰 인증 에러(fatal)]]></title>
            <link>https://velog.io/@daymoon_/Git-Github-%ED%86%A0%ED%81%B0-%EC%9D%B8%EC%A6%9D-%EC%97%90%EB%9F%ACfatal</link>
            <guid>https://velog.io/@daymoon_/Git-Github-%ED%86%A0%ED%81%B0-%EC%9D%B8%EC%A6%9D-%EC%97%90%EB%9F%ACfatal</guid>
            <pubDate>Wed, 27 Jul 2022 15:12:07 GMT</pubDate>
            <description><![CDATA[<h2 id="✅-운영체제--windows-11">✅ 운영체제 : Windows 11</h2>
<br>

<h2 id="🤔-들어가기-전">🤔 들어가기 전</h2>
<p>분명... 비밀번호가 맞는데?!!</p>
<p>앗... 비번 까먹었.....ㄴ ㅏ..?</p>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/f1a8d06c-c813-4d32-80e4-1bbf86e2569a/image.png" alt=""></p>
<hr>
<h2 id="해결-방법">해결 방법</h2>
<blockquote>
<p>📖 <strong>참고자료</strong>
<a href="https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/">Github 공식문서</a>
<a href="https://hyeo-noo.tistory.com/184">개발냥발_[Mac] GitHub push token 오류 해결</a>
<a href="https://dev.classmethod.jp/articles/resolving-github-token-authentication-errors/">Kim Jaewook_GitHub 토큰 인증 에러 해결 remote: Support for password authentication was removed. Please use a personal access token instead.</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/38edb10d-22e0-4049-ba73-0845f4874802/image.png" alt=""></p>
<p>2021년 8월 31일부터 Github에서 <code>token</code> 방식으로 로그인을 해야 하며 이전 방식(Github 비밀번호)을 이용하면 위와 같은 <code>fatal</code>에러가 발생한다.</p>
<br>

<p>✨ <strong>solution</strong></p>
<ol>
<li><p>프로필 → settings
<img src="https://velog.velcdn.com/images/daymoon_/post/0311e7af-6bad-463e-8b57-bc1182cdc530/image.png" alt=""></p>
</li>
<li><p>메뉴바 최하단에 있는 <code>Developer settings</code> 클릭 
<img src="https://velog.velcdn.com/images/daymoon_/post/9abd8def-5608-40c3-84dc-2824ea343198/image.png" alt=""></p>
</li>
<li><p>메뉴바 하단에 있는 <code>Personal access token</code> 클릭 → 오른쪽에 있는 <code>Generate new token</code> 클릭
<img src="https://velog.velcdn.com/images/daymoon_/post/f7dcc991-36ff-4a47-8371-d47e80fd10a2/image.png" alt=""></p>
</li>
<li><p>key 생성</p>
</li>
</ol>
<ul>
<li>Note : key 이름</li>
<li>Expiration : 사용기간</li>
<li>Select scope : 토큰 허용 설정 <strong>(참고자료 블로그 확인하세요!)</strong>
<img src="https://velog.velcdn.com/images/daymoon_/post/d869e7cd-acea-4e50-9a57-640d9fa108c9/image.png" alt=""></li>
</ul>
</br>

<p>🛑 <strong>주의 사항</strong>🛑</p>
<ul>
<li>꼭! 반드시! Token key는 복사해서 메모장 또는 카톡, Notion 등 어딘가에 적어서 저장!</li>
<li>Github에서 Token을 딱 한 번! 생성할 때만 보여줍니다. 잃어버리면... 재생성해야 합니다. 되찾기도 없어요...</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Next : styled-components 적용 에러]]></title>
            <link>https://velog.io/@daymoon_/React-Next.js%EC%97%90-styled-components-%EC%A0%81%EC%9A%A9-%EC%97%90%EB%9F%AC</link>
            <guid>https://velog.io/@daymoon_/React-Next.js%EC%97%90-styled-components-%EC%A0%81%EC%9A%A9-%EC%97%90%EB%9F%AC</guid>
            <pubDate>Sun, 17 Jul 2022 06:05:00 GMT</pubDate>
            <description><![CDATA[<h2 id="✅-운영체제--windows-11">✅ 운영체제 : Windows 11</h2>
<br>

<h2 id="🤔-들어가기-전">🤔 들어가기 전</h2>
<p>Next가 에러를 뱉었다! 에러를 해결하자! </p>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/8cc2040d-425f-4fba-8619-623c2b3c406e/image.png" alt=""></p>
<hr>
<h2 id="해결-방법">해결 방법</h2>
<blockquote>
<p>📖 <strong>참고자료</strong>
<a href="https://seungjoon-lee.oopy.io/36e42d37-bbfc-4116-8a30-92a781ecc958">LSJ HOME_styled-components className 을 props 로 전달할 경우 발생하는 에러</a>
<a href="https://kyounghwan01.github.io/blog/React/styled-components/styled-components-render-error/">기억보다는 기록을_next.js styled-componsnts 스타일 적용 전에 렌더되는 에러 해결법</a>
<a href="https://dev.to/britotiagos/how-add-style-components-to-nextjs-and-start-using-it-4kdf">DEV_How to add Style-components to Next.js and start using it</a></p>
</blockquote>
<p>Next.js에서 <code>className</code>을 props로 전달할 경우 발생하는 에러이다.</p>
<p>즉, styled-components를 사용하는데, CSS가 적용되기 전에 렌더링되어 발생하는 것이다.</p>
<br>

<p>✨ <strong>solution</strong>
Next.js에서 styled-components를 사용하기 위해서 추가적인 설정을 해주어야 한다.</p>
<ol>
<li>babel-plugin-styled-components 설치<pre><code class="language-shell"># -D : 개발용 설치 (-D, --save-dev: Package will appear in your devDependencies.)
npm i -D babel-plugin-styled-components
</code></pre>
</li>
</ol>
<p>npm i babel-plugin-styled-components</p>
<pre><code>
&lt;br&gt;

2. root 폴더 안에 `.babelrc`를 생성
```javascript
// .babelrc 설정
{
  &quot;presets&quot;: [&quot;next/babel&quot;],
  &quot;plugins&quot;: [
    [
      &quot;babel-plugin-styled-components&quot;,
      { &quot;fileName&quot;: true, &quot;displayName&quot;: true, &quot;pure&quot;: true, &quot;ssr&quot;: true }
    ]
  ]
}

// fileName: 코드가 포함된 파일명을 알려줌
// displayName : 클래스명에 해당 스타일 정보 추가
// pure : 사용하지 않은 속성 제거
// ssr: server side rendering</code></pre><hr>
<h2 id="🗓️-수정-및-추가">🗓️ 수정 및 추가</h2>
<p>✅ 2022.07.26</p>
<ul>
<li>내용 추가</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JS : Optional chaining, Nullish coalescing]]></title>
            <link>https://velog.io/@daymoon_/JS-</link>
            <guid>https://velog.io/@daymoon_/JS-</guid>
            <pubDate>Fri, 15 Jul 2022 00:03:28 GMT</pubDate>
            <description><![CDATA[<h2 id="🤔-들어가기-전">🤔 들어가기 전</h2>
<p>JavaScript 신문법?! 나온지 꽤 됐지만 정리해 보자!</p>
<hr>
<h2 id="optional-chaining">Optional chaining</h2>
<blockquote>
<p>🧑‍🏫 <strong>참고 자료</strong>
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Optional_chaining">MDN Optional chaining</a></p>
</blockquote>
<p>Optional chaining 연산자는 체인의 각 참조가 유효한지 명시적으로 검증하지 않고, 연결된 객체 체인 내에 깊숙이 위치한 속성값을 읽을 수 있다.</p>
<p>만약 참조한 값이 <code>null</code> 또는 <code>undefined</code>라면 에러가 발생하지 않고 <code>undefined</code>를 반환한다.</p>
<p>✨ 왼쪽의 값이 비어있으면 오른쪽이 실행 X → 즉, <code>undefined</code> 반환
✨ 중첩된 object에서 자료를 뽑을 경우 참조에러(reference)없이 안전하게 사용 가능</p>
<br>

<h3 id="⚙️-문법">⚙️ 문법</h3>
<pre><code class="language-javascript">obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)</code></pre>
<br>

<p>✅ <strong>예시</strong></p>
<pre><code class="language-javascript">const person = {
  name: &quot;홍길동&quot;,
  age: 32,
  // phone: {
  //   value: 1
  // }
};

// TypeError: Cannot read properties of undefined (reading &#39;value&#39;)
// 🚨 에러 발생! 코드 중단
console.log(person.phone.value);

// undefined
console.log(person.phone?.value);</code></pre>
<br>

<h2 id="nullish-coalescing">Nullish coalescing</h2>
<blockquote>
<p>🧑‍🏫 <strong>참고 자료</strong>
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator">MDN Nullish coalescing operator</a></p>
</blockquote>
<p>Nullish coalescing operator는 왼쪽 피연산자가 <code>null</code> 또는 <code>undefined</code>일 때 오른쪽 피연산자를 반환하고, 그렇지 않으면 왼쪽 피연산자를 반환하는 논리 연산자이다.</p>
<p>✨ 만약 왼쪽 표현식이 <code>null</code> 또는 <code>undefined</code>인 경우, 오른쪽 표현식의 결과를 반환한다.
✨ 리액트에서 서버에게 데이터가 늦는 경우 해당 값이 없어 에러가 발생한다. 이런 경우 <code>??</code>을 사용하여 데이터를 기다리는 동안 다른 값을 보여주면 된다.</p>
<br>

<p>🛑 <strong>차이점</strong>
OR 연산자 <code>||</code>은<code>null</code> 또는 <code>undefined</code> 뿐만 아니라 <code>falsy</code>값 전부를 검사하지만 Nullish coalescing <code>??</code>은 <code>undefined</code>와 <code>null</code>같은 nullish만 검사하는 연산자이다.</p>
<br>

<h3 id="⚙️-문법-1">⚙️ 문법</h3>
<pre><code class="language-javascript">leftExpr ?? rightExpr</code></pre>
<br>

<p>✅ <strong>예시</strong></p>
<pre><code class="language-javascript">console.log(data.name.id ?? &quot;로딩중&quot;);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[JS : [object Object] 형태 출력하기]]></title>
            <link>https://velog.io/@daymoon_/JS-object-Object-%ED%98%95%ED%83%9C-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@daymoon_/JS-object-Object-%ED%98%95%ED%83%9C-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 28 Jun 2022 10:55:54 GMT</pubDate>
            <description><![CDATA[<h2 id="🤔-들어가기-전">🤔 들어가기 전</h2>
<p>aixos를 통해 받은 JSON 값을 <code>console.log</code>로 출력하면 <code>[object Object]</code>로 보인다.</p>
<p>나도 보고 싶다.. 데이터..
<img src="https://velog.velcdn.com/images/daymoon_/post/fd854c4c-d5d6-49fb-823b-f625311dbad4/image.png" alt=""></p>
<hr>
<h2 id="jsonstringify">JSON.stringify()</h2>
<blockquote>
<p>🧑‍🏫 <strong>참고 자료</strong>
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">MDN_JSON.stringify()</a>
<a href="https://stackoverflow.com/questions/28149462/how-to-print-json-data-in-console-log">Stackoeverflow_How to print JSON data in console.log?</a>
<a href="https://inpa.tistory.com/entry/JS-%F0%9F%9A%80-consolelog%EC%9D%98-Object-%EB%A5%BC-%EA%B0%9D%EC%B2%B4%EB%A1%9C-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0">DevScroll_[JS] console.log의 [Object]를 객체로 출력하기</a></p>
</blockquote>
<p>자바스크립트 값이나 객체를 JSON 문자열로 반환한다. <code>JSON.stringify</code> 메서드를 작성하면 객체 정보를 볼 수 있다.</p>
<pre><code class="language-javascript">console.log(`Promise.all 후에 받는 데이터 : ${JSON.stringify(data)}`);</code></pre>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/6d049ec9-3f81-4fa7-a6da-1944eaefbe42/image.png" alt=""></p>
<p>예쁘게 들여쓰기 된 일반적인 코드를 보고 싶다면 다음과 같이 작성하면 된다.</p>
<pre><code class="language-javascript">console.log(`Promise.all 후에 받는 데이터 : ${JSON.stringify(data, null, &quot;\t&quot;)}`);</code></pre>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/cd36a644-2576-4e6a-8efb-eeb36d0128da/image.png" alt=""></p>
<br>

<p>✨ <strong>MDN : console.log() 공식문서</strong></p>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/API/console/log">MDN_console.log()</a>
<img src="https://velog.velcdn.com/images/daymoon_/post/017d7fb6-be5f-4edb-bd1e-62db2d0662ff/image.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React : Redux createStore deprecated]]></title>
            <link>https://velog.io/@daymoon_/React-Redux-createStore-deprecated</link>
            <guid>https://velog.io/@daymoon_/React-Redux-createStore-deprecated</guid>
            <pubDate>Sun, 26 Jun 2022 17:27:02 GMT</pubDate>
            <description><![CDATA[<h2 id="✅-운영체제--windows-11">✅ 운영체제 : Windows 11</h2>
<br>

<h2 id="🤔-들어가기-전">🤔 들어가기 전</h2>
<p>Redux와 친해지려고 한순간 Store(스토어)가 나에게 취소선을 선사했다.</p>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/2d15890f-8249-4a37-bc8e-68e0900d0cd3/image.png" alt=""></p>
<hr>
<h2 id="해결-방법">해결 방법</h2>
<blockquote>
<p>📖 <strong>참고자료</strong>
<a href="https://ko.redux.js.org/introduction/getting-started/">Redux_Redux 시작하기</a>
<a href="https://redux-toolkit.js.org/introduction/getting-started">Redux Toolkit</a>
<a href="https://redux.js.org/introduction/why-rtk-is-redux-today">Redux_Why Redux Toolkit is How To Use Redux Today</a>
<a href="https://github.com/reduxjs/redux/releases">Redux Github_업데이트 내용</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/f68237fc-c10d-4b46-a7e0-206bc974a886/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/28a419d6-7065-4636-a097-c52063cd6b63/image.png" alt=""></p>
<p>관련 내용을 찾아본 결과 현재 공식 문서에서 <code>Redux Tooolkit</code>을 권장하고 있다.
결론은 <code>createStore</code>를 사용할 수 있고 기존의 모든 코드에서 작동한다. 그냥 취소선만 생겼을 뿐이다. </p>
<p>즉, <em><strong>그냥 사용해도 되는데, 난 <code>RTK</code>를 사용했으면 좋겠어!</strong></em> 라는 말이다.</p>
<br>

<p>✨ <strong>solution 1</strong>
공식 문서가 권장하는 방법을 따른다. 가장 BEST!</p>
<ol>
<li>Redux Toolkit을 설치<pre><code class="language-shell"># NPM
npm install @reduxjs/toolkit
</code></pre>
</li>
</ol>
<h1 id="yarn">Yarn</h1>
<p>yarn add @reduxjs/toolkit</p>
<pre><code>
&lt;br&gt;

2. `configureStore` 사용하기
```shell
import { configureStore } from &#39;@reduxjs/toolkit&#39;
import counterReducer from &#39;../features/counter/counterSlice&#39;

export default configureStore({
  reducer: {
    counter: counterReducer
  }
})</code></pre><br>

<p>✨ <strong>solution 2</strong>
공식 문서가 알려준 방법으로 취소선을 없앤다.</p>
<ol>
<li><code>legacy_createStore</code>를 추가해 준다.<pre><code class="language-javascript">import { legacy_createStore as createStore } from &quot;redux&quot;;</code></pre>
</li>
</ol>
<br>

<ol start="2">
<li>원래 쓰던 방식대로 코드를 작성한다.
<img src="https://velog.velcdn.com/images/daymoon_/post/99fa7538-7da2-4efb-8c3f-354bae4edf15/image.png" alt=""></li>
</ol>
<hr>
<h2 id="🏙️-comment">🏙️ Comment</h2>
<p>갑자기 취소선이 생겨서 놀랐네..</p>
<p>저는 그냥 둘 다 사용법 익혔습니다. 혹시 몰라서..</p>
<p><code>createStore</code>로 완성 → <code>configureStore</code>로 코드 리팩토링
(근데 <code>configureStore</code> 편하네요?! (｡･∀･)ﾉﾞ)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DS : 성능 분석 (Performance Analysis) [1]]]></title>
            <link>https://velog.io/@daymoon_/DS-%EC%84%B1%EB%8A%A5-%EB%B6%84%EC%84%9D-Performance-Analysis-1</link>
            <guid>https://velog.io/@daymoon_/DS-%EC%84%B1%EB%8A%A5-%EB%B6%84%EC%84%9D-Performance-Analysis-1</guid>
            <pubDate>Fri, 24 Jun 2022 10:17:06 GMT</pubDate>
            <description><![CDATA[<h2 id="성능과-점근적-분석법">성능과 점근적 분석법</h2>
<blockquote>
<p>🗃️ <strong>강의</strong>
<a href="http://www.kmooc.kr/courses/course-v1:SMUk+SMU2018_01+2021_1_T1/course/">K-MOOC 자료구조</a></p>
</blockquote>
<h3 id="성능이란-무엇인가">성능이란 무엇인가?</h3>
<p>🔸 <strong>성능 또는 효율 : 일 잘함 + 소요 시간 적음</strong></p>
<p>같은 기능을 가진 어플이어도 처리 성능이 빠른 어플이 성능이 좋다고 할 수 있다. (즉, 요구하는 자원을 최소로 사용)</p>
<br>

<p>🔸 <strong>성능</strong></p>
<ul>
<li>성능 또는 효율</li>
<li>동일한 성과를 도출하기 위해서 요구되는 자원의 크기는 다음과 같다. (성과를 자원으로 나눈 것)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/f5e2925a-3e13-4468-9038-8a4605399664/image.png" alt=""></p>
<br>

<p>🔸 <strong>성능의 세가지 측면</strong></p>
<ul>
<li>최선의 경우</li>
<li>평균의 경우</li>
<li>최악의 경우</li>
</ul>
<p>집에서 학교까지 가는 경우(등교 시간 9시)를 성능으로 간단하게 설명해 보자!
▶ 최선 : 최대한 빨리 도착해! (1시간 전 도착)
▶ 평균 : 학교에 보통 이 시간에 도착해! (30분 전 도착)
▶ 최악 : 아무리 늦어도 지각은 안 한다! (1분 전 도착)</p>
<p><code>최악의 경우</code>는 보장의 의미를 가지고 있다. 그래서 성능을 이야기할 경우 반드시 <code>최악의 경우</code>를 정하고 성능을 말해야 한다.</p>
<br>

<p>🔸 <strong>자원의 두 가지 측면 : 공간과 시간</strong></p>
<ul>
<li>공간 복잡도 : 특정한 프로그램을 수행하는 데 요구되는 메모리</li>
<li>시간 복잡도 : 특정한 프로그램을 수행하는 데 요구되는 시간</li>
</ul>
<p>컴퓨터에서 메모리가 <code>공간 복잡도</code>이면 CPU는 <code>시간 복잡도</code>이다. </p>
<p>메모리의 성능이 뛰어나도 CPU 처리 능력이 뒤처지면 무용지물이다. 마치 로스트 아크를 설치할 공간은 있지만 실행할 능력이 안 되는 것처럼..ㅠㅠ</p>
<p><span style="color: red">즉, 시간이 공간보다 더 소중한 자원이다.</span></p>
<br>

<h3 id="점근적-분석법">점근적 분석법</h3>
<p>🔸 <strong>성능은 입력의 크기에 따라 결정된다.</strong>
입력의 크기는 n, 시간 복잡도를 n의 함수로 표현하면 f(n)으로 작성하면 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/f63e45cf-8fac-4abb-bd5f-ad4e268eceb1/image.png" alt=""></p>
<ul>
<li>입력이 증가하면 시간도 증가 ▶ 일반적</li>
<li>입력이 증가해도 시간은 일정 ▶ 최고</li>
<li>입력이 증가해도 시간은 감소 ▶ 없음</li>
</ul>
<br>

<p>🔸 <strong>점근적 분석법</strong></p>
<ul>
<li>시간 복잡도는 매우 큰 입력에 대해서 측정한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/3257a582-a00c-4d06-aba4-ed1c3b155356/image.png" alt=""></p>
<p>작은 입력에서는 의미가 없기 때문에 점근적인 분석을 하기 위해선 매우 큰 입력을 가정하고 측정해야한다.</p>
<br>

<p>🔸 <strong>g(n)을 이용한 f(n)의 성능 표현</strong></p>
<ul>
<li><code>g(n)</code>은 항상 <code>f(n)</code>보다 커야 한다.</li>
<li><code>g(n)</code>은 <code>f(n)</code>보다 성능이 나쁨</li>
<li>최악의 경우에도 <code>f(n)</code>은 <code>g(n)</code>보다 좋음</li>
<li><code>f(n)</code>의 상한은 <code>g(n)</code></li>
<li><code>f(n)</code> ≤ <code>g(n)</code></li>
<li><code>g(n)</code>은 <code>f(n)</code>의 성능을 나타내는 척도로 사용</li>
<li>많이 사용되는 표준 함수 사용 ▶ 1, n, n^2, 2^n, log n</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React : Component 생성 단축키]]></title>
            <link>https://velog.io/@daymoon_/React-Component-%EC%83%9D%EC%84%B1-%EB%8B%A8%EC%B6%95%ED%82%A4</link>
            <guid>https://velog.io/@daymoon_/React-Component-%EC%83%9D%EC%84%B1-%EB%8B%A8%EC%B6%95%ED%82%A4</guid>
            <pubDate>Wed, 15 Jun 2022 17:29:59 GMT</pubDate>
            <description><![CDATA[<h2 id="✅-운영체제--windows-11">✅ 운영체제 : Windows 11</h2>
<br>

<h2 id="🤔-들어가기-전">🤔 들어가기 전</h2>
<p>왜 나는 일일이 다 작성하고 있었는가..（；´д｀）ゞ</p>
<hr>
<h2 id="class-component">Class Component</h2>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/94a945ff-235f-4248-8b92-3305ce246218/image.png" alt=""></p>
<p>⚙️ <strong>VS Code에 <code>rcc</code> 작성</strong>
<img src="https://velog.velcdn.com/images/daymoon_/post/7597dd17-63bf-4af9-b315-c2c9cefbb778/image.gif" alt=""></p>
<br>

<h2 id="function-component--기본-함수">Function Component : 기본 함수</h2>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/13788be6-4171-4699-81b3-98c5c7faad30/image.png" alt=""></p>
<p>⚙️ <strong>VS Code에 <code>rfc</code> 작성</strong>
<img src="https://velog.velcdn.com/images/daymoon_/post/27d56461-e3e7-48bd-8ca5-a6c555e12945/image.gif" alt=""></p>
<br>

<p>⚙️ <strong>VS Code에 <code>rfce</code> 작성</strong>
<img src="https://velog.velcdn.com/images/daymoon_/post/c9915b33-0122-4338-b999-d2216a860c36/image.gif" alt=""></p>
<br>

<h2 id="function-component--화살표-함수">Function Component : 화살표 함수</h2>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/47c4de30-60c0-41d9-9561-c6f20c87a116/image.png" alt=""></p>
<p>⚙️ <strong>VS Code에 <code>rafc</code> 작성</strong>
<img src="https://velog.velcdn.com/images/daymoon_/post/b08d7da2-c2cf-427d-9584-03c19ed5bd70/image.gif" alt=""></p>
<p>⚙️ <strong>VS Code에 <code>rafce</code> 작성</strong>
<img src="https://velog.velcdn.com/images/daymoon_/post/927ccbed-f136-41f1-a0db-0c71fbfaf478/image.gif" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : React로 사고하기]]></title>
            <link>https://velog.io/@daymoon_/React%EB%A1%9C-%EC%82%AC%EA%B3%A0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@daymoon_/React%EB%A1%9C-%EC%82%AC%EA%B3%A0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 10 Jun 2022 19:58:19 GMT</pubDate>
            <description><![CDATA[<h1 id="react로-사고하기">React로 사고하기</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/thinking-in-react.html">React_React로 사고하기</a></p>
</blockquote>
<p>React는 JavaScript로 규모가 크고 빠른 웹 애플리케이션을 만드는 가장 좋은 방법입니다. React는 Facebook과 Instagram을 통해 확장석을 입증했다.</p>
<p>React의 가장 멋진 점 중 하나는 앱을 설계하는 방식이다.</p>
<br>

<h2 id="목업으로-시작하기">목업으로 시작하기</h2>
<p>JSON API와 목업으로 디자이너로부터 받았다고 가정하자. 목업은 다음과 같다.</p>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/448d212b-18ad-4fa0-8ac2-759be90c13f7/image.png" alt=""></p>
<p>JSON API는 아래와 같은 데이터를 반환한다.</p>
<pre><code class="language-javascript">[
  {category: &quot;Sporting Goods&quot;, price: &quot;$49.99&quot;, stocked: true, name: &quot;Football&quot;},
  {category: &quot;Sporting Goods&quot;, price: &quot;$9.99&quot;, stocked: true, name: &quot;Baseball&quot;},
  {category: &quot;Sporting Goods&quot;, price: &quot;$29.99&quot;, stocked: false, name: &quot;Basketball&quot;},
  {category: &quot;Electronics&quot;, price: &quot;$99.99&quot;, stocked: true, name: &quot;iPod Touch&quot;},
  {category: &quot;Electronics&quot;, price: &quot;$399.99&quot;, stocked: false, name: &quot;iPhone 5&quot;},
  {category: &quot;Electronics&quot;, price: &quot;$199.99&quot;, stocked: true, name: &quot;Nexus 7&quot;}
];</code></pre>
<br>

<h3 id="1단계--ui를-컴포넌트-계층-구조로-나누기">1단계 : UI를 컴포넌트 계층 구조로 나누기</h3>
<p>우리가 할 첫 번째 일은 모든 컴포넌트(와 하위 컴포넌트)의 주변에 박스를 그리고 그 각각에 이름을 붙이는 것이다. 디자이너와 함께 일한다면, 이것들을 이미 정해두었을 수도 있다. 디자이너의 포토샵 레이어 이름이 React 컴포넌트의 이름이 될 수 있다.</p>
<p>하지만 어떤 것이 컴포넌트가 되어야 할지 어떻게 알 수 있을까? 우리가 새로운 함수나 객체를 만들 때 처럼 만들면 된다. 한 가지 테크님은 <strong>단일 책임 원칙</strong>이다. 이는 하나의 컴포넌트는 한 가지 일을 하는게 이상적이라는 원칙이다. 하나의 컴포넌트가 커지게 된다면 이는 보다 작은 하위 컴포넌트로 분리되어야 한다.</p>
<p>✨ <strong>단일 책임 원칙(Single responsibility principle)이란?</strong></p>
<ul>
<li><a href="https://ko.wikipedia.org/wiki/%EB%8B%A8%EC%9D%BC_%EC%B1%85%EC%9E%84_%EC%9B%90%EC%B9%99">wikipedia_단일 책임 원칙</a></li>
<li><a href="https://jaeseongdev.github.io/development/2021/02/14/%EB%8B%A8%EC%9D%BC_%EC%B1%85%EC%9E%84_%EC%9B%90%EC%B9%99_SRP/">jaeseongdev_단일 책임 원칙</a></li>
<li>객체 지향 프로그래밍을 설계할 때 지켜야하는 원칙중 하나이다. (S.O.L.I.D에서 S)</li>
<li>모든 클래스는 각각 하나의 책임만 자겨야 하는 원칙을 말한다.</li>
<li>즉, 관련된 기능들을 묶어주는 것이다.</li>
</ul>
<p>주로 JSON 데이터를 유저에게 보여주기 때문에, 데이터 모델이 적절하게 만들어졌다면, UI(컴포넌트 구조)가 잘 연결될 것이다. 이는 UI와 데이터 모델이 같은 인포메이션 아키텍처(information architecture)를 가지는 경향이 있기 때문이다. 각 컴포넌트가 데이터 모델의 한 조각을 나타내도록 분리해야 한다.</p>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/896be2e2-1f2b-45f8-8be0-882c0a1abcee/image.png" alt=""></p>
<p>다섯개의 컴포넌트로 이루어진 앱을 한 번 살펴보자!</p>
<p>각각의 컴포넌트에 들어간 데이터는 <em>이탤릭체</em> 로 표기했다. 이미지의 숫자는 아래 숫자에 해당된다.</p>
<ol>
<li><p>FilterableProductTable (<span style="color: gold">노란색</span>) : 예시 전체를 포괄한다.</p>
</li>
<li><p>SearchBar (<span style="color: blue">파란색</span>) : 모든 유저의 입력(user input)을 받는다.</p>
</li>
<li><p>ProductTable (<span style="color: green">연두색</span>) : 유저의 입력(user input)을 기반으로 데이터 콜렉션(data collection)을 필터링해서 보여준다.</p>
</li>
<li><p>ProductCategoryRow (<span style="color: cyan">하늘색</span>) : 각 카테고리(category)의 헤더를 보여준다.</p>
</li>
<li><p>ProductRow (<span style="color: red">빨강색</span>) : 각각의 제품(Product)에 해당하는 행을 보여준다.</p>
</li>
</ol>
<br>

<p><code>ProductTable</code>을 보면 &quot;Name&quot;과 &quot;Price&quot; 레이블을 포함한 테이블 헤더만을 가진 컴포넌트는 없다. 이 같은 경우, 데이터를 위한 독립된 컴포넌트를 생성할지 생성하지 않을지는 선택이다. 이 예시에서는 <code>ProductTable</code>의 책임인 데이터 컬렉션(data collection)이 렌더링의 일부이기 때문에 <code>ProductTable</code>을 남겨두었다. 그러나 이 헤더가 복잡해지면 (즉, 정렬을 위한 기능을 추가하는 등) <code>ProductTableHeader</code> 컴포넌트를 만드는 것이 더 합리적이다.</p>
<p>이제 목업에서 컴포넌트를 확인했으니 이를 계층 구조로 나열해 보자!!
모형의 다른 컴포넌트 내부에 나타나는 컴포넌트 계층 구조의 자식으로 나타낸다.</p>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/17a79aeb-23de-4659-a19a-068ad0020a8d/image.png" alt=""></p>
<br>

<h3 id="2단계--react-정적인-버전-만들기">2단계 : React 정적인 버전 만들기</h3>
<p>!codepen[gaearon/embed/BwWzwm?default-tab=js%2Cresult]</p>
<p>이제 컴포넌트 계층구조가 만들어졌으니 앱을 실제로 구현해 보자!!</p>
<p>가장 쉬운 방법은 데이터 모델을 가지고 UI 렌더링은 되지만 아무 동작도 없는 버전을 만들어보는 것이다. 이처럼 과정을 나누는 것이 좋은데 정적 버전을 만드는 것은 생각이 적게 필요하지만 타이핑은 많이 필요로 하고, 상호작용을 만드는 것은 생각은 많이 해야 하지만 타이핑은 정게 필요로 하기 때문이다.</p>
<p>데이터 모델을 렌더링하는 앱의 정적 버전을 만들기 위해 다른 컴포넌트를 재사용하는 컴포넌트를 만들고 props를 이용해 데이터를 전달한다. <strong>props는 부모가 자식에게 데이터를 넘겨줄 때 사용할 수 있는 방법</strong>이다. 정적 버전을 만들기 위해 <strong style="color: red">state를 사용하지 말아야 한다.</strong> state는 오직 상호작용을 위해, 즉 시간이 지남에 따라 데이터가 바뀌는 것에 사용한다. 우리은 앱의 정적 버전을 만들고 있기 때문에 state는 필요 없다.</p>
<p>앱을 만들 때 하향식(top-down)이나 상향식(bottom-up)으로 만들 수 있다. 다시 말해 계층 구조의 상층부에 있는 컴포넌트 (즉, <code>FillterableProductTable</code> 부터 시작하는 것)q부터 만들거나 하층부에 있는 컴포넌트 (<code>ProductRow</code>)부터 만들 수도 있다. 간단한 예시에서는 보통 하향식으로 만드는 게 쉽지만 프로젝트가 커지면 상향식으로 만들고 테스트를 작성하면서 개발하기가 더 쉽다.</p>
<p>이 단계가 끝나면 데이터 렌더링을 위해 만들어진 재사용 가능한 컴포넌트들의 라이브러리를 가지게 된다. 현재는 앱의 정적 버전이기 때문에 컴포넌트는 <code>render()</code> 메서드만 가지고 있을 거이다. 계층구조의 최상단 컴포넌트 (<code>FilterProductTable</code>)는 prop으로 데이터 모델을 받는다. 데이터 모델이 변경되면 <code>ReactDOM.render()</code>를 다시 호출해서 UI가 업데이트 된다. UI가 어떻게 업데이트되고 어디에서 변경해야하는지 알 수 있다. React의 <strong>단방향 데이터 흐름 (one-way data flow) ** 또는 **단방향 바인딩 (one-way binding)</strong>은 모든 것을 모듈화 하고 빠르게 만든어 준다.</p>
<br>

<h3 id="3단계--ui-state에-대한-최소한의-하지만-완전한-표현-찾아내기">3단계 : UI state에 대한 최소한의 (하지만 완전한) 표현 찾아내기</h3>
<p>UI를 사용작용하게 만들려면 기반 데이터 모델을 변경할 수 있는 방법이 있어야 한다. 이를 React는 state를 통해 변경한다.</p>
<p>🔎 <strong>Props vs State : 차이점은??</strong></p>
<ul>
<li><a href="https://ko.reactjs.org/docs/faq-state.html#what-is-the-difference-between-state-and-props">React_state와 props</a></li>
<li>props(properties)와 state는 일반 JavaScript 객체이다.</li>
<li>두 객제 모두 렌더링 결과물에 영향을 주는 정보를 작고 있는데, 방식에 차이가 있다.</li>
<li>props : 부모 컴포넌트가 자식 컴포넌트에게 전달한다. 단, 자식 컴포넌트는 부모 컴포넌트에게 전달할 수 없으며 오로지 읽기만 가능한 값이다.</li>
<li>state : 컴포넌트 안에서 관리한다. 즉, 함수 안에서 선언된 지역 변수처럼 사용되는 값이다.</li>
</ul>
<p>애플리케이션을 올바르게 만들기 위해서는 애플리케이션에서 필요로 하는 변경 가능한 state의 최소 집합으로 생각해야 한다. 여기서 핵심은 <strong>중복 배제 원칙</strong>이다. 애플리케이션이 필요로 하는 가장 최소한의 state를 찾고 이를 통해 나머지 모든 것들이 필요에 따라 그때 그때 계산되도록 만들어야 한다. 예를 들어, TOTO 아이템의 개수를 표현하는 state를 변도로 만들지 말아야 한다. TODO 갯수를 렌더링해야 한다면 TODO 아이템 배열의 길이를 가져오면 된다.</p>
<p>✨ <strong>중복 배제 원칙(Don&#39;t repeat yourself; DRY)</strong></p>
<ul>
<li><a href="https://ko.wikipedia.org/wiki/%EC%A4%91%EB%B3%B5%EB%B0%B0%EC%A0%9C">wikipedia_중복 배제</a></li>
<li>소프트웨어 개발 원리의 하나로, 모든 형태의 정보 중복을 지양하는 원리이다.</li>
<li>특히, 다층 구조 시스템에서 유용하다.</li>
<li>&quot;모든 지식은 시스템 내에서 유일하고 중복이 없으며 권위있는 표상만을 가진다.&quot;</li>
</ul>
<p>예시 애플리케이션 내 데이터들을 생각해 보자!! 애플리케이션은 다음과 같은 데이터를 가지고 있다.</p>
<ul>
<li>제품의 원본 목록</li>
<li>유저가 입력한 검색어</li>
<li>체크박스의 값</li>
<li>필터링 된 제품들의 목록</li>
</ul>
<p>각각 살펴보고 어떤 게 state가 되어야 하는지 살펴보자!! 이는 각 데이터에 대해 아래의 세 가지 질문을 통해 결정할 수 있다.</p>
<ol>
<li><p>부모로부터 props를 통해 전달이 가능한가?</p>
</li>
<li><p>시간이 지나도 변하지 않는가?</p>
</li>
<li><p>컴포넌트 안의 다른 state나 props를 가지고 계산 가능한가?</p>
</li>
</ol>
<br>

<p>제품의 원본 목록은 props를 통해 전달되므로 state가 아니다. 검색어와 체크박스는 state로 볼 수 있는데 시간이 지남에 따라 변하기도 하면서 다른 것들로 부터 계산될 수 없기 때문이다. 그리고 마지막으로 필터링된 목록은 state가 아니다. 제품의 원본 목록과 검색어, 체크박스의 값을 조합해서 도출할 수 있기 때문이다.</p>
<p>결과적으로 애플리케이션은 <code>유저가 입력한 검색어</code>와 <code>체크박스의 값</code>이 state를 가진다.</p>
<br>

<h3 id="4단계--state가-어디에-있어야-할-지-찾기">4단계 : state가 어디에 있어야 할 지 찾기</h3>
<p>다음으로 어떤 컴포넌트가 state를 변경하거나 소유할지 찾아야 한다.</p>
<p>🛑 <strong>주의</strong></p>
<ul>
<li>React는 항상 컴포넌트 계층구조를 따라 아래로 내려가는 단방향 데이터 흐름을 따른다. 그래서 어떤 컴포넌트가 어떤 state를 가져야 하는지 바로 결정하기 어려울 수 있다.</li>
<li>초보자들이 가장 어려워 하는 부분!! 집중! 🙀</li>
</ul>
<br>

<p>애플리케이션이 가지는 각각의 state에 대해서</p>
<ol>
<li><p>state를 기반으로 렌더링하는 모든 컴포넌트를 찾는다.</p>
</li>
<li><p>공통 소유 컴포넌트(common owner component)를 찾는다. → 계층 구조 내에서 특정 state가 있어야 하는 모든 컴포넌트들의 상위에 있는 하나의 컴포넌트</p>
</li>
<li><p>공통 혹은 더 상위에 있는 컴포넌트가 state를 가져야한다.</p>
</li>
<li><p>state를 소유할 적절한 컴포넌트를 찾지 못했다면, state를 소유하는 컴포넌트를 하나 만들어서 공통 오너 컴포넌트의 상위 계층에 추가한다.</p>
</li>
</ol>
<br>

<p>이 전략을 애플리케이션에 적용하면 다음과 같다.</p>
<ul>
<li><p>ProductTable은 state에 의존한 상품 리스트의 필터링해야 하고 SearchBar는 검색어와 체크박스의 상태를 표시해야 한다.</p>
</li>
<li><p>공통 소유 컴포넌트는 FilterableProductTable이다.</p>
</li>
<li><p>의미상으로도 FilterableProductTable이 검색어와 체크박스의 체크 여부를 가지는 것이 타당하다.</p>
</li>
</ul>
<br>

<p>먼저 인스턴스 속성인 <code>this.state = {filterText: &#39;&#39;, inStockOnly: false}</code> 를 FilterableProductTable의 constructor에 추가하여 애플리케이션의 초기 상태를 반영합니다. 그리고 나서 filterText와 inStockOnly를 ProductTable와 SearchBar에 prop으로 전달합니다. 마지막으로 이 props를 사용하여 ProductTable의 행을 정렬하고 SearchBar의 폼 필드 값을 설정하세요.</p>
<br>

<h3 id="5단계--역방향-데이터-흐름-추가하기">5단계 : 역방향 데이터 흐름 추가하기</h3>
<p>!codepen[gaearon/embed/LzWZvb?default-tab=js%2Cresult]</p>
<p>지금까지 우리는 계층 구조 아래로 흐르는 props와 state의 함수로써 앱을 만들었다. 이제 다른 방향의 데이터 흐름을 만들어 보자!!</p>
<p>계층 구조의 하단에 있는 폼 컴포넌트에서 FilterableProductTable의 state를 업데이트할 수 있어야 한다.</p>
<p>React는 전통적인 양방향 데이터 바인딩(two-way data binding)과 비교하면 더 많은 타이핑을 필요로 하지만 데이터 흐름을 명시적으로 보이게 만들어서 프로그램이 어떻게 동작하는지 파악할 수 있게 도와준다.</p>
<p>4단계의 예시에서 체크하거나 키보드를 타이핑할 경우 React가 입력을 무시하는 것을 확인할 수 있다. 이는 input 태그의 value 속성이 항상 FilterableProductTable에서 전달된 state와 동일하도록 설정했기 때문입니다.</p>
<p>우리가 원하는 것이 무엇인지를 한번 생각해 보자..!</p>
<p>우리는 사용자가 폼을 변경할 때마다 사용자의 입력을 반영할 수 있도록 state를 업데이트하기를 원한다. 컴포넌트는 그 자신의 state만 변경할 수 있기 때문에 FilterableProductTable는 SearchBar에 콜백을 넘겨서 state가 업데이트되어야 할 때마다 호출되도록 할 것이다. 우리는 input에 onChange 이벤트를 사용해서 알림을 받을 수 있다. FilterableProductTable에서 전달된 콜백은 setState()를 호출하고 앱이 업데이트될 것이다.</p>
<hr>
<h2 id="👋-comment">👋 Comment</h2>
<p>React를 너무 후다닥 배운 감이 있어서 공식 문서를 보면서 기초를 다시 공부했다..
그리고.. 너무 무지성으로 짠것 같아서 스스로에게 너무 화가 났기도..ㅠㅠ🙀🙀</p>
<p>아직 갈 길이 멀다..!! 기본적인 실습을 하고 고급 안내서로..!!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : 합성 (Composition) vs 상속 (Inheritance)]]></title>
            <link>https://velog.io/@daymoon_/ReactDocs-%ED%95%A9%EC%84%B1-Composition-vs-%EC%83%81%EC%86%8D-Inheritance</link>
            <guid>https://velog.io/@daymoon_/ReactDocs-%ED%95%A9%EC%84%B1-Composition-vs-%EC%83%81%EC%86%8D-Inheritance</guid>
            <pubDate>Wed, 08 Jun 2022 21:55:28 GMT</pubDate>
            <description><![CDATA[<h1 id="합성-composition-vs-상속-inheritance">합성 (Composition) vs 상속 (Inheritance)</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/composition-vs-inheritance.html">React_합성 vs 상속</a></p>
</blockquote>
<p>React는 강력한 합성 모델을 가지고 있으며, 상속 대신 합성을 사용하여 컴포넌트 간에 코드를 재사용하는 것이 좋다.</p>
<br>

<h2 id="컴포넌트에서-다른-컴포넌트를-담기">컴포넌트에서 다른 컴포넌트를 담기</h2>
<p>어떤 컴포넌트들은 어떤 지식 엘리먼트가 들어올지 미리 예상할 수 없는 경우가 있다. 범용적인 &#39;박스&#39; 역할을 하는 <code>Slidebar</code> 혹은 <code>Dialog</code>와 같은 컴포넌트에서 특히 자주 볼 수 있다.</p>
<p>이러한 컴포넌트에서는 특수한 <code>children</code> prop을 사용하며 자식 엘리먼트를 출력에 그대로 전달하는 것이 좋다.</p>
<pre><code class="language-javascript">function FancyBorder(props) {
  return (
    &lt;div className={&#39;FancyBorder FancyBorder-&#39; + props.color}&gt;
      {props.children}
    &lt;/div&gt;
  );
}</code></pre>
<p>이러한 방식으로 다른 컴포넌트에서 JSX를 중첩하여 임의의 자식을 전달할 수 있다.</p>
<pre><code class="language-javascript">function WelcomeDialog() {
  return (
    &lt;FancyBorder color=&quot;blue&quot;&gt;
      &lt;h1 className=&quot;Dialog-title&quot;&gt;
        Welcome
      &lt;/h1&gt;
      &lt;p className=&quot;Dialog-message&quot;&gt;
        Thank you for visiting our spacecraft!
      &lt;/p&gt;
    &lt;/FancyBorder&gt;
  );
}</code></pre>
<p>!codepen[gaearon/embed/ozqNOV?default-tab=js%2Cresult]</p>
<p><code>&lt;FancyBorder&gt;</code> JSX 태그 안에 있는 것들이 <code>FancyBorder</code> 컴포넌트의 <code>children</code> prop으로 전달된다. <code>FancyBorder</code>는 <code>{props.children}</code>을 <code>&lt;div&gt;</code> 안에 렌더링하므로 전달된 엘리먼트틀이 출력된다.</p>
<p>흔하진 않지만 종종 컴포넌트에 여러 개의 &#39;구멍&#39;이 필요할 수도 있다. 이런 경우에는 <code>children</code> 대신 자신만의 고유한 방식을 적용할 수 있다.</p>
<pre><code class="language-javascript">function SplitPane(props) {
  return (
    &lt;div className=&quot;SplitPane&quot;&gt;
      &lt;div className=&quot;SplitPane-left&quot;&gt;
        {props.left}
      &lt;/div&gt;
      &lt;div className=&quot;SplitPane-right&quot;&gt;
        {props.right}
      &lt;/div&gt;
    &lt;/div&gt;
  );
}

function App() {
  return (
    &lt;SplitPane
      left={
        &lt;Contacts /&gt;
      }
      right={
        &lt;Chat /&gt;
      } /&gt;
  );
}</code></pre>
<p>!codepen[gaearon/embed/gweOJp?default-tab=js%2Cresult]</p>
<p><code>&lt;Contacts /&gt;</code>와 <code>&lt;Chat /&gt;</code> 같은 React 엘리먼트는 단지 객체이기 때문에 다른 데이터처럼 prop으로 전달할 수 있다. 이러한 접근은 다른 라이브러리의 슬롯(slot)과 비슷해보이지만 React에서 prop으로 전달할 수 있는 것에는 제한이 없다.</p>
<br>

<h2 id="특수화">특수화</h2>
<p>때로는 어떤 컴포넌트의 &#39;특수한 경우&#39;인 컴포넌트를 고려해야 하는 경우가 있다. 예를 들어, <code>WelcomeDialog</code>는 <code>Dialog</code>의 특수한 경우라고 할 수 있다.</p>
<p>React에서는 이 역시 합성을 통해 해결할 수 있다. 더 구체적인 컴포넌트가 일반적인 컴포넌트를 렌더링하고 props를 통해 내용을 구성한다.</p>
<pre><code class="language-javascript">// ⚙️ 구체적인 컴포넌트
// - 일반적인 컴포넌트를 렌더링
// - prop를 받아서 컴포넌트 내용 구성
function Dialog(props) {
  return (
    &lt;FancyBorder color=&quot;blue&quot;&gt;
      &lt;h1 className=&quot;Dialog-title&quot;&gt;
        {props.title}
      &lt;/h1&gt;
      &lt;p className=&quot;Dialog-message&quot;&gt;
        {props.message}
      &lt;/p&gt;
    &lt;/FancyBorder&gt;
  );
}

// ⚙️ 일반적인 컴포넌트
// - prop를 넘겨줌
function WelcomeDialog() {
  return (
    &lt;Dialog
      title=&quot;Welcome&quot;
      message=&quot;Thank you for visiting our spacecraft!&quot; /&gt;
  );
}</code></pre>
<p>!codepen[gaearon/embed/ZpxEgr?default-tab=js%2Cresult]</p>
<p>합성은 클래스로 정의된 컴포넌트에서도 동일하게 적용된다.</p>
<pre><code class="language-javascript">function Dialog(props) {
  return (
    &lt;FancyBorder color=&quot;blue&quot;&gt;
      &lt;h1 className=&quot;Dialog-title&quot;&gt;
        {props.title}
      &lt;/h1&gt;
      &lt;p className=&quot;Dialog-message&quot;&gt;
        {props.message}
      &lt;/p&gt;
      {props.children}
    &lt;/FancyBorder&gt;
  );
}

class SignUpDialog extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSignUp = this.handleSignUp.bind(this);
    this.state = {login: &#39;&#39;};
  }

  render() {
    return (
      &lt;Dialog title=&quot;Mars Exploration Program&quot;
              message=&quot;How should we refer to you?&quot;&gt;
        &lt;input value={this.state.login}
               onChange={this.handleChange} /&gt;
        &lt;button onClick={this.handleSignUp}&gt;
          Sign Me Up!
        &lt;/button&gt;
      &lt;/Dialog&gt;
    );
  }

  handleChange(e) {
    this.setState({login: e.target.value});
  }

  handleSignUp() {
    alert(`Welcome aboard, ${this.state.login}!`);
  }
}</code></pre>
<p>!codepen[gaearon/embed/gwebYa?default-tab=js%2Cresult]</p>
<br>

<h2 id="그렇다면-상속은">그렇다면 상속은?</h2>
<p>컴포넌를 상속 계층 구조에 대한 예시는 아직 없다.</p>
<p>props와 합성은 명시적이고 안전한 방법으로 컴포넌트의 모양과 동작을 커스터마이징하는데 필요한 모든 유연성을 제공한다. 컴포넌트가 원시 타입의 값, React 엘리먼트 혹은 한수 등 어떠한 props도 받을 수 있다는 것을 기억해야 한다.</p>
<p>UI가 아닌 기능을 여러 컴포넌트에서 재사용하기를 원한다면, 별도의 JavaScript 모듈로 분리하는 것이 좋다. 컴포넌트에서 해당 함수, 객체, 클래스 들을 import하여 사용할 수 있다.</p>
<p><strong>✨ 즉, 상속받을 필요 없다!!! ✨</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : State 끌어올리기]]></title>
            <link>https://velog.io/@daymoon_/ReactDocs-State-%EB%81%8C%EC%96%B4%EC%98%AC%EB%A6%AC%EA%B8%B0</link>
            <guid>https://velog.io/@daymoon_/ReactDocs-State-%EB%81%8C%EC%96%B4%EC%98%AC%EB%A6%AC%EA%B8%B0</guid>
            <pubDate>Mon, 06 Jun 2022 17:44:21 GMT</pubDate>
            <description><![CDATA[<h1 id="state-끌어올리기">State 끌어올리기</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/lifting-state-up.html">React_State 끌어올리기</a></p>
</blockquote>
<p>종종 동일한 데이터에 대한 변경사항을 여러 컴포넌트에 반영해야 할 필요가 있다. 이럴 때는 가장 가까운 공통 조상으로 state를 끌러올리는 것이 좋다. </p>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li><code>BoilingVeridict</code> 컴포넌트 생성</li>
<li>컴포넌트가 <code>celsius</code> prop를 받아서 이 온도가 물이 끓기에 충분하지 여부를 출력<pre><code class="language-javascript">function BoilingVerdict(props) {
if (props.celsius &gt;= 100) {
  // props.celsius가 100 이상인 경우
  return &lt;p&gt;The water would boil.&lt;/p&gt;;
}
// props.celsius가 100 미만인 경우
return &lt;p&gt;The water would not boil.&lt;/p&gt;;
}</code></pre>
</li>
</ul>
<br>

<p>⚙️ <strong>예시 코드 - 2</strong></p>
<ul>
<li><p><code>Calculatro</code> 컴포넌트 생성</p>
</li>
<li><p>온도를 입력할 수 있는 <code>&lt;input&gt;</code>을 렌더링하고 그 값을 <code>this.state.temperature</code>에 저장</p>
</li>
<li><p>현재 입력값에 대한 <code>BoilingVerdict</code> 컴포넌트를 렌더링</p>
<pre><code class="language-javascript">class Calculator extends React.Component {
constructor(props) {
  super(props);
  this.handleChange = this.handleChange.bind(this);
  // ✨ 제어 컴포넌트
  // React 값에 의해 폼 제어
  this.state = {temperature: &#39;&#39;};
}

handleChange(e) {
  // ✨ 제어 컴포넌트
  // setState()로 값을 업데이트
  this.setState({temperature: e.target.value});
}

render() {
  const temperature = this.state.temperature;
  return (
    &lt;fieldset&gt;
      &lt;legend&gt;Enter temperature in Celsius:&lt;/legend&gt;
      &lt;input
        value={temperature}
        onChange={this.handleChange} /&gt;
      // ⚙️ parseFloat
      // 주어진 값을 부동소수점 실수로 파싱해서 반환
      &lt;BoilingVerdict
        celsius={parseFloat(temperature)} /&gt;
    &lt;/fieldset&gt;
  );
}
}</code></pre>
</li>
</ul>
<p>!codepen[gaearon/embed/ZXeOBm?default-tab=js%2Cresult]</p>
<h2 id="두-번째-input-추가하기">두 번째 Input 추가하기</h2>
<p>새 요구사항으로써 섭씨 입력 필드뿐만 아니라 화씨 입력 필드를 추가하고 두 필드 간에 동기화 상태를 유지하도록 해보자!</p>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li><code>Calculator</code>에서 <code>TemperatureInput</code> 컴포넌트를 빼내는 작업</li>
<li><code>&quot;c&quot;</code> 또는 <code>&quot;f&quot;</code>의 값을 가질 수 있는 <code>scale</code> prop를 추가<pre><code class="language-javascript">// 섭씨와 화씨를 가지는 객체 생성
const scaleNames = {
c: &#39;Celsius&#39;,
f: &#39;Fahrenheit&#39;
};
</code></pre>
</li>
</ul>
<p>class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: &#39;&#39;};
  }</p>
<p>  handleChange(e) {
    // 섭씨 또는 화씨로 값을 업데이트
    this.setState({temperature: e.target.value});
  }</p>
<p>  render() {
    const temperature = this.state.temperature;
    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature}
               onChange={this.handleChange} />
      </fieldset>
    );
  }
}</p>
<pre><code>
&lt;br&gt;

⚙️ **예시 코드 - 2**
- `Calculator`가 분리된 두 개의 온도 입력 필드를 렌더링하도록 변경
```javascript
class Calculator extends React.Component {
  render() {
    return (
      &lt;div&gt;
        &lt;TemperatureInput scale=&quot;c&quot; /&gt;
        &lt;TemperatureInput scale=&quot;f&quot; /&gt;
      &lt;/div&gt;
    );
  }
}</code></pre><p>이제 두 개의 입력 필드를 갖게 됐다. 그러나 둘 중 하나에 온도를 입력하더라도 다른 하나는 갱신되지 않는 문제가 발생한다. 이것은 두 입력 필드 간에 동기화 상태를 유지하고자 했던 원래 원래 요구사항과는 맞지 않다.</p>
<p>또한, <code>Calculator</code>에서 <code>BoilingVerdict</code>도 보여줄 수 없는 상황이다. 현재 입력된 온도 정보가 <code>TemperatureInput</code>안에 숨겨져 있으므로 <code>Calculator</code>는 그 값을 알 수 없다.</p>
<br>

<h2 id="변환-함수-작성하기">변환 함수 작성하기</h2>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li>섭씨 → 화씨 &amp; 화씨 → 섭씨로 변환하는 함수 생성<pre><code class="language-javascript">function toCelsius(fahrenheit) {
return (fahrenheit - 32) * 5 / 9;
}
</code></pre>
</li>
</ul>
<p>function toFahrenheit(celsius) {
  return (celsius * 9 / 5) + 32;
}</p>
<pre><code>
이 두 함수는 숫자를 변환한다. 이제 `temperature` 문자열과 변환 함수를 인수로 취해서 문자열을 반환하는 또 다른 함수를 생성한다. 그리고 그것을 한 입력값에 기반해 나머지 입력 값을 계산하는 용도로 사용할 것이다.

⚙️ **예시 코드 - 2**
- 올바르지 않은 `temperature` 값에 대해서는 빈 문자열을 반환하고 값을 소수점 세 번째 자리로 반올림하여 출력
```javascript
// tryConvert는 두 개의 매개변수를 사용
function tryConvert(temperature, convert) {
  const input = parseFloat(temperature);

  // Number.isNaN() 메서드는 전달된 값이 NaN인지 아닌지를 검사
  // 오직 숫자인 값에만 동작, NaN인 경우 동작 X
  if (Number.isNaN(input)) {
    // NaN인 경우 빈 문자열을 반환
    return &#39;&#39;;
  }
  const output = convert(input);

  // Math.round() 메서드는 입력값을 반올림한 수와 가장 가까운 정수 값을 반환
  // 즉, 우리가 수학에서 배운 반올림과 같다!
  const rounded = Math.round(output * 1000) / 1000;

  // toString() 메서드는 문자열을 반환
  return rounded.toString();
}</code></pre><br>

<h2 id="state-끌어올리기-1">State 끌어올리기</h2>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li><p>현재는 두 <code>TemperatureInput</code> 컴포넌트가 각각의 입력값을 각자의 state에 독립적으로 저장</p>
<pre><code class="language-javascript">class TemperatureInput extends React.Component {
constructor(props) {
  super(props);
  this.handleChange = this.handleChange.bind(this);
  this.state = {temperature: &#39;&#39;};
}

handleChange(e) {
  this.setState({temperature: e.target.value});
}

render() {
  const temperature = this.state.temperature;
  // ...</code></pre>
</li>
</ul>
<p>그러나 우리는 두 입력값이 서로의 것과 동기화된 상태로 있길 원한다. 섭씨온도 입력값을 변경할 경우 화씨온도 입력값 역시 반환된 온도를 반영할 수 있어야 한다. (그 반대의 경우에도 마찬가지여야 한다.)</p>
<p>React에서 state를 공유하는 일은 그 값을 필요로 하는 컴포넌트 간의 가장 가까운 공통 조상으로 state를 끌어올림으로써 이뤄낼 수 있다. 이렇게 하는 방법을 <strong>state 끌어올리기</strong>라고 부른다. 이제 <code>TemperatureInput</code>이 개별적으로 가지고 있던 지역 state를 지우는 대신 <code>Calculator</code>로 그 값을 옮겨놓을 것이다.</p>
<p><code>Clculator</code>가 공유될 state를 소유하고 있으면 이 컴포넌트는 두 입력 필드의 현재 온도에 대한 <strong>진리의 원천(source of truth)</strong> 이 된다. 이를 통해 두 입력 필드가 서로 간에 일관된 값을 유지하도록 만들 수 있다. 두 <code>TemperatureInput</code> 컴포넌트의 prop가 같은 부모인 <code>Calculator</code>로 부터 전달되기 때문에 두 입력 필드는 항상 동기화된 상태를 유지할 수 있다.</p>
<p>⚙️ <strong>예시 코드 - 2</strong></p>
<ul>
<li><code>TemperatureInput</code> 컴포넌트에서 <code>this.state.temperature</code>를 <code>this.props.temperature</code>로 대체</li>
<li>나중에 이 값을 <code>Calculator</code>로 부터 보내주어야 함<pre><code class="language-javascript">render() {
  // Before: const temperature = this.state.temperature;
  // ✨ props는 읽기 전용!!!
  const temperature = this.props.temperature;
  // ...</code></pre>
</li>
</ul>
<p><strong style="color:red">props는 읽기 전용</strong>이다.</p>
<p><code>temperature</code>가 지역 state였을 때는 그 값을 변경하기 위해서 그저 <code>TemperatureInput</code>의 <code>this.setState()</code>를 호출하는 걸로 충분했다. 그러나 이제 <code>temperature</code>가 부모로부터 prop로 전달되기 때문에 <code>TemperatureInput</code>은 그 값을 제어할 능력이 없다.</p>
<p>React에서는 보통 이 문제를 컴포넌트를 <strong>제어</strong>가능하게 만드는 방식으로 해결한다. DOM <code>&lt;input&gt;</code>이 <code>value</code>와 <code>onChange</code> prop를 건네받는 것과 비슷한 방식으로, 사용자 정의된 <code>TemperatureInput</code> 역시 <code>temperature</code>와 <code>onTemperatureChange</code> props 자신의 부모인 <code>Calculator</code>로 부터 받을 수 있다.</p>
<p>⚙️ <strong>예시 코드 - 3</strong></p>
<ul>
<li><code>TemperatureInput</code>에서 온도를 갱신하고 싶으면 <code>this.props.onTemperatureChange</code>를 호출<pre><code class="language-javascript">handleChange(e) {
  // Before: this.setState({temperature: e.target.value});
  this.props.onTemperatureChange(e.target.value);
  // ...</code></pre>
</li>
</ul>
<p>🛑 <strong>주의!</strong></p>
<ul>
<li>사용자 정의 컴포넌트에서 <code>temperature</code>와 <code>onTemperatureChange</code> prop의 이름이 특별한 의미를 갖지는 않는다.</li>
<li>일관된 컨벤션으로 <code>value</code>와 <code>onChange</code>을 사용할 수도 있으며, 개발자가 원하는 이름을 사용할 수 있다.</li>
</ul>
<br>

<p><code>onTemperatureChange</code> prop는 부모 컴포넌트인 <code>Calculator</code>로 부터 <code>temperature</code> prop와 함께 제공될 것이다. 이를 이용해 자신의 지역 state를 수정해서 변경사항을 처리하므로, 변경된 새 값을 전달받은 두 입력 필드는 모두 리렌더링될 것이다.</p>
<p><code>Calculator</code>의 변경사항을 보기 전에 <code>TemperatureInput</code> 컴포넌트에 대한 변경사항을 요약하면 다음과 같다. 이 컴포넌트의 지역 state를 제거했으며 <code>this.state.temperature</code> 대신에 <code>this.props.temperature</code>를 읽어오도록 변경했다. state를 변결하고 싶을 경우 <code>this.setState()</code> 대신에 <code>Calculator</code>로부터 받은 <code>this.props.onTemperatureChange()</code>를 호출하도록 만들었다.</p>
<p>⚙️ <strong>예시 코드 - 3</strong></p>
<pre><code class="language-javascript">class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    // input값을 가져옴
    this.props.onTemperatureChange(e.target.value);
  }

  render() {
    const temperature = this.props.temperature;
    const scale = this.props.scale;
    return (
      &lt;fieldset&gt;
        &lt;legend&gt;Enter temperature in {scaleNames[scale]}:&lt;/legend&gt;
        &lt;input value={temperature}
               onChange={this.handleChange} /&gt;
      &lt;/fieldset&gt;
    );
  }
}</code></pre>
<p>이제 다시 <code>Calculator</code> 컴포넌트를 살펴보자!</p>
<p><code>temperature</code>와 <code>scale</code>의 현재 입력값을 이 컴포넌트의 지역 state에 저장한다. 이것은 개발자가 입력 필드들로부터 <strong>끌어올린 state</strong>이며 그들에 대한 <strong>진리의 원천(source of truth)</strong> 으로 작용할 것이다. 또한, 두 입력 필드를 렌더링하기 위해서 알아야 하는 모든 데이터를 최소한으로 표현하는 것이기도 한다.</p>
<br>

<p>⚙️ <strong>예시 코드 - 4</strong></p>
<pre><code class="language-javascript">// 섭씨 입력 필드에 37을 입력하면 `Calculator` 컴포넌트의 sate는 다음과 같다.
{
  temperature: &#39;37&#39;,
  scale: &#39;c&#39;
}

// 이후에 화씨 입력 필드의 값을 212로 수정하면 Calculator의 state는 다음과 같다.
{
  temperature: &#39;212&#39;,
  scale: &#39;f&#39;
}</code></pre>
<br>

<p>두 입력 필드에 모두 값을 저장하는 일도 가능했지만 결국은 불필요한 작업이었다...</p>
<p>가장 최근에 변경된 입력값과 그 값이 나타내는 단위를 저장하는 것만으로도 충분하다. 그러고 나면 현재의 <code>temperature</code>와 <code>scale</code>에 기반해 다른 입력 필드의 값을 추론할 수 있다.</p>
<p>두 입력 필드의 값이 동일한 state로부터 계산되기 때문에 이 둘은 항상 동기화된 상태를 유지하게 된다.</p>
<br>

<p>⚙️ <strong>예시 코드 - 5</strong></p>
<pre><code class="language-javascript">class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
    this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
    this.state = {temperature: &#39;&#39;, scale: &#39;c&#39;};
  }

  handleCelsiusChange(temperature) {
    this.setState({scale: &#39;c&#39;, temperature});
  }

  handleFahrenheitChange(temperature) {
    this.setState({scale: &#39;f&#39;, temperature});
  }

  render() {
    const scale = this.state.scale;
    const temperature = this.state.temperature;

    // 삼항 연산자 이용!
    const celsius = scale === &#39;f&#39; ? tryConvert(temperature, toCelsius) : temperature;
    const fahrenheit = scale === &#39;c&#39; ? tryConvert(temperature, toFahrenheit) : temperature;

    return (
      &lt;div&gt;
        &lt;TemperatureInput
          scale=&quot;c&quot;
          temperature={celsius}
          onTemperatureChange={this.handleCelsiusChange} /&gt;
        &lt;TemperatureInput
          scale=&quot;f&quot;
          temperature={fahrenheit}
          onTemperatureChange={this.handleFahrenheitChange} /&gt;
        &lt;BoilingVerdict
          celsius={parseFloat(celsius)} /&gt;
      &lt;/div&gt;
    );
  }
}</code></pre>
<p>!codepen[gaearon/embed/WZpxpz?default-tab=js%2Cresult]</p>
<p>이제 어떤 입력 필드를 수정하든 간에 <code>Calculator</code>의 <code>this.state.temperature</code>와 <code>this.state.scale</code>이 갱신된다. 입력 필드 중 하나는 있는 그대로의 값을 받으므로 사용자가 입력한 값이 보존되고, 다른 입력 필드의 값은 항상 다른 하나에 기반해 재계산된다.</p>
<p>입력 값을 변경할 경우 일어나는 과정은 다음과 같다.</p>
<ol>
<li><p>React는 DOM <code>&lt;input&gt;</code>의 onChange에 지정된 함수를 호출한다. 위 예시의 경우 <code>TemperatureInput</code>의 <code>hanldeChange</code> 메서드에 해당한다.</p>
</li>
<li><p><code>TemperatureInput</code> 컴포넌트의 <code>handleChange</code> 메서드는 새로 입력된 값고 함께 <code>this.props.onTemperatureChange()</code>를 호출한다. <code>onTemperatureChange</code>를 포함한 이 컴포넌트의 props는 부모 컴포넌트인 <code>Calculator</code>로부터 제공받은 것이다.</p>
</li>
<li><p>이전 렌더링 단계에서, <code>Calculator</code>는 섭씨 <code>TemperatureInput</code>의 <code>onTemperatureChange</code>를 <code>Calculator</code>의 <code>handleCelsiusChange</code> 메서드로, 화씨 <code>TemperatureInput</code>의 <code>onTemperatureChange</code>를 <code>Calculator</code>의 <code>handleFahrenheitChange</code> 메서드로 지정해 놓는다. 따라서 어떤 입력 필드를 수정하느냐에 따라 <code>Calculator</code>의 두 메서드 중 하나가 호출된다.</p>
</li>
<li><p>이들 메서드는 내부적으로 <code>Calculator</code> 컴포넌트가 새 입력값, 그리고 현재 수정한 입력 필드의 입력 단위와 함께 <code>this.setState()</code>를 호출하게 함르호써 React에게 자신을 다시 렌더링하도록 요청한다.</p>
</li>
<li><p>React는 UI가 어떻게 보여야 하는지 알아내기 위해 <code>Calculator</code> 컴포넌트의 <code>render</code> 메서드를 호출한다. 두 입력 필드의 값은 현재 온도와 활성화된 단위를 기반으로 재계산된다. 온도의 변환이 이 단께에서 수행된다.</p>
</li>
<li><p>React는 <code>Calculator</code>가 전달한 새 props와 함께 각 <code>TemperatureInput</code> 컴포넌트의 <code>render</code> 메서드를 호출한다. 그러면서 UI가 어떻게 보여아 할지를 파악한다.</p>
</li>
<li><p>React는 <code>BoilingVerdict</code> 컴포넌트에게 섭씨온도를 props로 건네면서 그 컴포넌트의 <code>render</code> 메서드를 호출한다.</p>
</li>
<li><p>React DOM은 물의 끓는 여부와 올바른 입력값을 일치시키는 작업과 함께 DOM을 갱신한다. 값을 변경한 입력 필드는 현재 입력값을 그대로 받고, 다른 입력 필드는 변환된 온도 값으로 갱신된다.</p>
</li>
</ol>
<p>입력 필드의 값을 변경할 때만다 동일한 정차를 거치고 두 입력 필드는 동기화된 상태로 유지된다.</p>
<br>

<h2 id="교훈">교훈</h2>
<ul>
<li><p>state를 끌어올리는 작업은 양방향 바인딩 접근 방식보다 더 많은 <strong>보일러 플레이트</strong> 코드를 유발하지만, 버그를 찾고 격리하기 더 쉽게 만든다는 장점이 있다.</p>
</li>
<li><p>사용자의 입력을 거부하거나 변경하는 자체 로직을 구현할 수 있다.</p>
</li>
<li><p>어떤 값이 props 또는 state로부터 계산될 수 있다면, 아마도 그 값을 state에 두어서는 안 된다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : 폼]]></title>
            <link>https://velog.io/@daymoon_/ReactDocs-%ED%8F%BC</link>
            <guid>https://velog.io/@daymoon_/ReactDocs-%ED%8F%BC</guid>
            <pubDate>Sun, 05 Jun 2022 20:07:49 GMT</pubDate>
            <description><![CDATA[<h1 id="폼">폼</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/forms.html">React_폼</a></p>
</blockquote>
<p>HTML 폼 엘리먼트는 폼 엘리먼트 자체가 내부 상태를 가지기 때문에, React의 다른 DOM 엘리먼트와 다르게 동작한다. 예를 들어, 순수한 HTML에서 이 폼은 <code>name</code>을 입력받는다.</p>
<pre><code class="language-javascript">&lt;form&gt;
  &lt;label&gt;
    Name:
    &lt;input type=&quot;text&quot; name=&quot;name&quot; /&gt;
  &lt;/label&gt;
  &lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
&lt;/form&gt;</code></pre>
<p>이 폼은 사용자가 폼을 제출하면 새로운 페이지로 이동하는 기본 HTML 폼 동작을 수행한다. React에서 동일한 동작을 원한다면 그대로 사용하면 된다. 그러나 대부분의 경우, JavaScript 함수로 폼의 제출을 처리하고 사용자가 폼에 입력한 데이터에 접근하도록 하는 것이 편리하다.</p>
<p>이를 위한 표준 방식은 제어 컴포넌트(controlled components)라고 불리는 기술을 이용한다.</p>
<br>

<h2 id="제어-컴포넌트-controlled-component">제어 컴포넌트 (Controlled Component)</h2>
<p>HTML에서 <code>&lt;input&gt;</code>, <code>&lt;textarea&gt;</code>, <code>&lt;select&gt;</code>와 같은 폼 엘리먼트는 일반적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트한다. React에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state 속성에 유지되며 <code>setState()</code>에 의해 업데이트 된다.</p>
<p>우리는 React state를 <code>신뢰 가능한 단일 출처(single source of truth)</code>로 만들어 두 요소를 결합할 수 있다. 그러면 폼을 렌더링하는 React 컴포넌트는 폼에 발생하는 사용자 입력값을 제어한다. 이러한 방식으로 <span style="color: red">React에 의해 값이 제어되는 입력 폼 엘리먼트를 <code>제어 컴포넌트(controlled component)</code>라고 한다.</span></p>
<p>⚙️ <strong>예시 코드</strong></p>
<ul>
<li><p>이름이 기록되길 원한다면 폼을 제어 컴포넌트로 작성한다.</p>
<pre><code class="language-javascript">class NameForm extends React.Component {
constructor(props) {
  super(props);
  this.state = {value: &#39;&#39;};

  this.handleChange = this.handleChange.bind(this);
  this.handleSubmit = this.handleSubmit.bind(this);
}

handleChange(event) {
  this.setState({value: event.target.value});
}

handleSubmit(event) {
  alert(&#39;A name was submitted: &#39; + this.state.value);
  // ✨ preventDefault()
  // - 어떤 이벤트를 명시적으로 처리하지 않은 경우,
  // 해당 이벤트에 대한 사용자 에이전트의 기본 동작을 실행하지 않도록 저장
  // - 이벤트 흐름의 어떤 흐름에서 preventDefault()를 실행하면 이벤트 취소
  event.preventDefault();
}

render() {
  return (
    &lt;form onSubmit={this.handleSubmit}&gt;
      &lt;label&gt;
        Name:
        &lt;input type=&quot;text&quot; value={this.state.value} onChange={this.handleChange} /&gt;
      &lt;/label&gt;
      &lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
    &lt;/form&gt;
  );
}
}</code></pre>
</li>
</ul>
<p>!codepen[gaearon/embed/VmmPgp?default-tab=js%2Cresult]</p>
<p><code>value</code> 어트리뷰트는 폼 엘리먼트에 설정되므로 표시되는 값은 항상 <code>this.state.value</code>가 되고 React state는 신뢰 가능한 단일 출처(single source of truth)가 된다. React state를 업데이트하기 위해 모든 키 입력에서 <code>handleChange</code>가 동작하기 때문에 사용자가 입력할 때 보여지는 값이 업데이트된다.</p>
<p>제어 컴포넌트로 사용하면, input의 값은 항상 React state에 의해 결정된다. 코드를 조금 더 작성해야 한다는 의미이지만, 다른 UI 엘리먼트에 input의 값을 전달하거나 다른 이벤트 핸들러에서 값을 재설정할 수 있다.</p>
<br>

<h2 id="textarea-태그">textarea 태그</h2>
<p>HTML에서 <code>&lt;textarea&gt;</code> 엘리먼트는 텍스트를 자식으로 정의한다.</p>
<pre><code class="language-html">&lt;textarea&gt;
  Hello there, this is some text in a text area
&lt;/textarea&gt;</code></pre>
<p>React에서 <code>&lt;textarea&gt;</code>는 <code>value</code> 어트리뷰트를 대신 사용한다. 이렇게 하면 <code>&lt;textarea&gt;</code>를 사용하는 폼은 한 줄 입력을 사용하는 폼과 비슷하게 작성할 수 있다.</p>
<pre><code class="language-javascript">class EssayForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: &#39;Please write an essay about your favorite DOM element.&#39;
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert(&#39;An essay was submitted: &#39; + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      &lt;form onSubmit={this.handleSubmit}&gt;
        &lt;label&gt;
          Essay:
          &lt;textarea value={this.state.value} onChange={this.handleChange} /&gt;
        &lt;/label&gt;
        &lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
      &lt;/form&gt;
    );
  }
}</code></pre>
<p><code>this.state.value</code>를 생성자에서 초기화하므로 textarea는 일부 텍스트를 가진채 시작되는 점을 주의해야 한다.</p>
<br>

<h2 id="select-태그">select 태그</h2>
<p>HTML에서 <code>&lt;select&gt;</code>는 드롭 다운 목록을 만든다. 예를 들어, 이 HTML은 과일 드롭 다운 목록을 만든다.</p>
<pre><code class="language-html">&lt;select&gt;
  &lt;option value=&quot;grapefruit&quot;&gt;Grapefruit&lt;/option&gt;
  &lt;option value=&quot;lime&quot;&gt;Lime&lt;/option&gt;

  &lt;!-- selected ▶ 기본값으로 시작 (선택) --&gt;
  &lt;option selected value=&quot;coconut&quot;&gt;Coconut&lt;/option&gt;
  &lt;option value=&quot;mango&quot;&gt;Mango&lt;/option&gt;
&lt;/select&gt;</code></pre>
<p><code>selected</code> 옵션이 있으므로 Coconut 옵션이 초기값이 되는 점을 주의해야 한다. React에서는 <code>selected</code> 어트리뷰트를 사용하는 대신 최상단 <code>select</code> 태그에 <code>value</code> 어트리뷰트를 사용한다. 한 곳에서 업데이트만 하면 되기 때문에 제어 컴포넌트에서 사용하기 더 편한다.</p>
<pre><code class="language-javascript">class FlavorForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: &#39;coconut&#39;};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert(&#39;Your favorite flavor is: &#39; + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      &lt;form onSubmit={this.handleSubmit}&gt;
        &lt;label&gt;
          Pick your favorite flavor:
          // select ▶ HTML의 selected와 같음 (기본값 선택)
          &lt;select value={this.state.value} onChange={this.handleChange}&gt;
            &lt;option value=&quot;grapefruit&quot;&gt;Grapefruit&lt;/option&gt;
            &lt;option value=&quot;lime&quot;&gt;Lime&lt;/option&gt;
            &lt;option value=&quot;coconut&quot;&gt;Coconut&lt;/option&gt;
            &lt;option value=&quot;mango&quot;&gt;Mango&lt;/option&gt;
          &lt;/select&gt;
        &lt;/label&gt;
        &lt;input type=&quot;submit&quot; value=&quot;Submit&quot; /&gt;
      &lt;/form&gt;
    );
  }
}</code></pre>
<p>!codepen[gaearon/embed/JbbEzX?default-tab=js%2Cresult]</p>
<p>전반적으로 <code>&lt;input type=&quot;text&quot;&gt;</code>, <code>&lt;textarea&gt;</code> 및 <code>&lt;select&gt;</code> 모두 매우 비슷하게 동작한다. 모두 제어 컴포넌트를 구현하는데 <code>value</code> 어트리뷰트를 허용한다.</p>
<p>🛑 <strong>주의</strong></p>
<ul>
<li><code>select</code> 태그에 multiple 옵션을 허용한다면 <code>value</code> 어트리뷰트에 배열을 전달할 수 있다.<pre><code class="language-javascript">// B와 C를 동시에 선택 가능
&lt;select multiple={true} value={[&#39;B&#39;, &#39;C&#39;]}&gt;</code></pre>
</li>
</ul>
<br>

<h2 id="file-input-태그">file input 태그</h2>
<p>HTML에서 <code>&lt;input type=&quot;file&quot;&gt;</code>는 사용자가 하나 이상의 파일을 자신의 장치 저장소에서 서버로 업로드하거나 <code>File API</code>를 통해 JavaScript로 조작할 수 있다.</p>
<pre><code class="language-html">&lt;!-- ⚙️ file--&gt;
&lt;!-- 1. 선택한 모든 파일을 나열하는 FileList 객체 --&gt;
&lt;!-- 2. multiple 특성을 지정하지 않았다면 두 개 이상의 파일을 포함하지 않음 --&gt;
&lt;input type=&quot;file&quot; /&gt;</code></pre>
<p>값이 읽기 전용이기 때문에 React에서는 <code>비제어 컴포넌트</code>이다.</p>
<br>

<h2 id="다중-입력-제어하기">다중 입력 제어하기</h2>
<p>여러 <code>input</code> 엘리먼트를 제어해야할 때, 각 엘리먼트에 <code>name</code> 어트리뷰트를 추가하고 <code>event.target.name</code> 값을 통해 핸들러가 어떤 작업을 할 지 선택할 수 있게 한다.</p>
<pre><code class="language-javascript">class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === &#39;checkbox&#39; ? target.checked : target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }

  render() {
    return (
      &lt;form&gt;
        &lt;label&gt;
          Is going:
          &lt;input
            name=&quot;isGoing&quot;
            type=&quot;checkbox&quot;
            checked={this.state.isGoing}
            onChange={this.handleInputChange} /&gt;
        &lt;/label&gt;
        &lt;br /&gt;
        &lt;label&gt;
          Number of guests:
          &lt;input
            name=&quot;numberOfGuests&quot;
            type=&quot;number&quot;
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} /&gt;
        &lt;/label&gt;
      &lt;/form&gt;
    );
  }
}</code></pre>
<p>주어진 <code>input</code> 태그의 name에 일치하는 state를 업데이트하기 위해 ES6의 <code>computed property name</code>구문을 사용한다.</p>
<pre><code class="language-javascript">this.setState({
  [name]: value
});</code></pre>
<p>ES5 코드는 다음과 같다.</p>
<pre><code class="language-javascript">var partialState = {};
partialState[name] = value;
this.setState(partialState);</code></pre>
<p>또한, <code>setState()</code>는 자동적으로 <span style="color: red">현재 state에 일부 state를 병합</span>하기 때문에 바뀐 부분에 대해서만 호출하면 된다.</p>
<p>✨ <strong>객체 초기자(computed property name)</strong></p>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Object_initializer#%EC%86%8D%EC%84%B1_%EA%B3%84%EC%82%B0%EB%AA%85">MDN_객체 초기자</a></li>
<li><code>{중괄호}</code>로 묶인 0개 이상의 객체의 프로퍼티명과 관련 값의 쌍을 콤마로 구분한 목록이다.</li>
</ul>
<br>

<h2 id="제어되는-input-null-값">제어되는 Input Null 값</h2>
<p>제어 컴포넌트에 <code>value</code> prop을 지정하면 의도하지 않는 한 사용자가 변경할 수 없다. <code>value</code>를 설정했는데 여전히 수정할 수 있다면 실수로 <code>value</code>를 <code>undefined</code>나 <code>null</code>로 설정했을 수 있다.</p>
<pre><code class="language-javascript">ReactDOM.render(&lt;input value=&quot;hi&quot; /&gt;, mountNode);

// 1초 뒤에 입력 가능
setTimeout(function() {
  ReactDOM.render(&lt;input value={null} /&gt;, mountNode);
}, 1000);</code></pre>
<br>

<h2 id="제어-컴포넌트의-대한">제어 컴포넌트의 대한</h2>
<p>데이터를 변경할 수있는 모든 방법에 대해 이벤트 핸들러를 작성하고 React 컴포넌트를 통해 모든 입력 상태를 연결해야 하기 때문에 때로는 제어 컴포넌트를 사용하게 지루할 수 있다.</p>
<p>특히, 기존의 코드 베이스를 React로 변경하고자 할 때나 React가 아닌 라이브러리와 React 애플리케이션을 통합하고자 할 때 짜증날 수 있다.</p>
<p>이러한 경우에 입력 폼을 구현하기 위한 대체 기술인 <code>비제어 컴포넌트</code>를 사용한다.</p>
<br>

<h2 id="완전한-해결책">완전한 해결책</h2>
<p>유효성 검사, 방문한 필드 추적 및 폼 제출 처리와 같은 완벽한 해결을 원한다면 <code>Formik</code>이 대중적인 선택중 하나이다. 그러나 <code>Formik</code>은 제어 컴포넌트 및 state 관리에 기초하기 때문에 공부를 해야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[WSL2 : 비밀번호 재설정]]></title>
            <link>https://velog.io/@daymoon_/WSL2-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EC%9E%AC%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@daymoon_/WSL2-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EC%9E%AC%EC%84%A4%EC%A0%95</guid>
            <pubDate>Sat, 04 Jun 2022 23:51:44 GMT</pubDate>
            <description><![CDATA[<h2 id="✅-운영체제--windows-11">✅ 운영체제 : Windows 11</h2>
<br>

<h2 id="🤔-들어가기-전">🤔 들어가기 전</h2>
<p>WSL2를 실행하고 다른 작업을 하려는 순간..</p>
<p>하..（；´д｀）ゞ</p>
<p>비밀번호를 까먹었다..;; </p>
<p><img src="https://velog.velcdn.com/images/daymoon_/post/e1dbc7ef-b0a5-437d-8d8c-632e3363fece/image.png" alt=""></p>
<hr>
<h2 id="⚙️-해결방법">⚙️ 해결방법</h2>
<blockquote>
<p>✨ 참고자료
<a href="https://see-ro-e.tistory.com/156">SeeRoE 프로그래밍 기록_WSL Ubuntu 비밀번호 초기화</a>
<a href="https://itwiki.kr/w/%EB%A6%AC%EB%88%85%EC%8A%A4_passwd(%EB%AA%85%EB%A0%B9%EC%96%B4)">IT위키_리눅스 passwd(명령어)</a></p>
</blockquote>
<p><strong>1. 명령 프롬프트(cmd)를 실행</strong></p>
<ul>
<li>방법 1 : 윈도우 돋보기를 이용하여 <code>cmd</code>검색 → 실행</li>
<li>방법 2 : 윈도우 + R 단축키 → cmd 입력 → 실행</li>
</ul>
<br>

<p><strong>2. root 설정</strong></p>
<ul>
<li>Ubunut 실행 시 root로 접속하도록 설정한다.
<img src="https://velog.velcdn.com/images/daymoon_/post/af6b4f3a-11e7-4d00-a83a-367bab09b68a/image.png" alt=""><pre><code class="language-shell">ubuntu.exe config --default-user root</code></pre>
</li>
</ul>
<br>

<p><strong>3. Ubuntu 실행</strong></p>
<br>

<p><strong>4. 비밀번호 재설정</strong></p>
<ul>
<li>명령어 <code>passwd</code>를 이용하여 새로운 비밀번호를 설정한다.</li>
<li>&quot;사용자 계정&quot;부분에서 <code>&quot;</code>는 제외하고 작성!!<pre><code class="language-shell">passwd &quot;사용자 계정&quot;</code></pre>
</li>
</ul>
<br>

<p><strong>5. root → 기본 계정으로 접속</strong></p>
<ul>
<li>cmd에서 다시 내 계정으로 접속한다.</li>
<li>&quot;사용자 계정&quot;부분에서 <code>&quot;</code>는 제외하고 작성!!<pre><code class="language-shell">ubuntu.exe config --default-user &quot;사용자 계정&quot;</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : 리스트와 Key]]></title>
            <link>https://velog.io/@daymoon_/ReactDocs-%EB%A6%AC%EC%8A%A4%ED%8A%B8%EC%99%80-Key</link>
            <guid>https://velog.io/@daymoon_/ReactDocs-%EB%A6%AC%EC%8A%A4%ED%8A%B8%EC%99%80-Key</guid>
            <pubDate>Sat, 04 Jun 2022 19:19:05 GMT</pubDate>
            <description><![CDATA[<h1 id="리스트와-key">리스트와 Key</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/lists-and-keys.html">React_리스트와 Key</a></p>
</blockquote>
<p>먼저 Javascript에서 리스트를 어떻게 변환하는지 살펴보자!</p>
<p>⚙️ <strong>예시 코드</strong></p>
<ul>
<li><code>map()</code> 함수를 이용하여 <code>numbers</code> 배열의 값을 두배로 만든 후 <code>map()</code>에서 반환하는 새 배열을 <code>doubled</code> 변수에 할당하고 로그로 확인하는 코드이다.<pre><code class="language-javascript">const numbers = [1, 2, 3, 4, 5];
</code></pre>
</li>
</ul>
<p>// 2를 곱한 값을 변수 doubled에 새로운 배열로 저장
const doubled = numbers.map((number) =&gt; number * 2);</p>
<p>// [2, 4, 6, 8, 10]을 출력
console.log(doubled);</p>
<pre><code>
React에서 배열을 엘리먼트 리스트로 만드는 방식은 이와 거의 동일하다.

&lt;br&gt;

## 여러 개의 컴포넌트 렌더링 하기
엘리먼트 모음을 만들고 중괄호 `{}`를 이용하여 JSX에 포함시킬 수 있다.

⚙️ **예시 코드 - 1**
- `map()` 함수를 이용하여 배열을 반복 실행하면서 `&lt;li&gt;{number}&lt;/li&gt;` 엘리먼트를 반환
- 엘리먼트 배열의 결과는 변수 `listItems`에 저장
```javascript
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =&gt;
  &lt;li&gt;{number}&lt;/li&gt;
);</code></pre><br>

<p>⚙️ <strong>예시 코드 - 2</strong></p>
<ul>
<li><code>listItems</code> 배열을 <code>&lt;ul&gt;</code> 엘리먼트 안에 포함시켜 DOM에 렌더링<pre><code class="language-javascript">ReactDOM.render(
&lt;ul&gt;{listItems}&lt;/ul&gt;,
document.getElementById(&#39;root&#39;)
);</code></pre>
</li>
</ul>
<br>

<p>⚙️ <strong>전체 코드</strong></p>
<p>!codepen[gaearon/embed/GjPyQM?default-tab=html%2Cresult]</p>
<br>

<h2 id="기본-리스트-컴포넌트">기본 리스트 컴포넌트</h2>
<p>일반적으로 컴포넌트 안에서 리스트를 렌더링한다.</p>
<p>🛠️ <strong>리팩토링 - 1</strong></p>
<pre><code class="language-javascript">function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =&gt;
    &lt;li&gt;{number}&lt;/li&gt;
  );
  return (
    &lt;ul&gt;{listItems}&lt;/ul&gt;
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  &lt;NumberList numbers={numbers} /&gt;,
  document.getElementById(&#39;root&#39;)
);</code></pre>
<br>

<p>🛠️ <strong>리팩토링 - 2</strong></p>
<ul>
<li><p>이 코드를 실행하면 리스트의 각 항목에 key를 추가하라는 경고가 표시된다.
<img src="https://velog.velcdn.com/images/daymoon_/post/5fb22913-23ba-4ce8-bd7b-2fffe77da286/image.png" alt=""></p>
</li>
<li><p><code>key</code>는 엘리먼트 리스트를 만들 때 포함해야 하는 특수한 문자열 어트리뷰트이다.</p>
</li>
<li><p><code>numbers.map()</code> 안에서 리스트의 각 항목에 <code>key</code>를 할당하여 키 누락 문제를 해결한다.</p>
<pre><code class="language-javascript">function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =&gt;
  &lt;li key={number.toString()}&gt;
    {number}
  &lt;/li&gt;
);
return (
  &lt;ul&gt;{listItems}&lt;/ul&gt;
);
}
</code></pre>
</li>
</ul>
<p>const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById(&#39;root&#39;)
);</p>
<pre><code>
&lt;br&gt;

🛠️ **리팩토링 - 전체 코드**

!codepen[gaearon/embed/jMXYRR?default-tab=html%2Cresult]

&lt;br&gt;

## key
key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다. key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해야 한다.

⚙️ **예시 코드 - 1**
```javascript
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =&gt;
  &lt;li key={number.toString()}&gt;
    {number}
  &lt;/li&gt;
);</code></pre><p>Key를 성택하는 가장 좋은 방법은 리스트의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것이다. 대부분의 경우 데이터의 ID를 key로 사용한다.</p>
<p>⚙️ <strong>예시 코드 - 2</strong></p>
<pre><code class="language-javascript">const todoItems = todos.map((todo) =&gt;
  &lt;li key={todo.id}&gt;
    {todo.text}
  &lt;/li&gt;
);</code></pre>
<p>렌더링 한 항목에 대한 안정적인 ID가 없다면 최후의 수단으로 항목의 인덱스를 key로 사용할 수 있다.</p>
<p>⚙️ <strong>예시 코드 - 3</strong></p>
<pre><code class="language-javascript">const todoItems = todos.map((todo, index) =&gt;
  // Only do this if items have no stable IDs
  &lt;li key={index}&gt;
    {todo.text}
  &lt;/li&gt;
);</code></pre>
<p>항목의 순서가 바뀔 수 있는 경우 key에 인덱스를 사용하는것은 권장하지 않는 방법이다. 이로 인해 성능이 저하되거나 컴포넌트의 state와 관련된 문제가 발생할 수 있다.</p>
<p>리스트 항목에 명시적으로 key를 지정하지 않으면 React는 기본적으로 인덱스를 key로 사용한다.</p>
<br>

<h2 id="key로-컴포넌트-추출하기">Key로 컴포넌트 추출하기</h2>
<p>key는 주변 배열의 context에서만 의미가 있다.</p>
<p>예를 들어, <code>ListItem</code> 컴포넌트를 추출한 경우 <code>ListItem</code> 안에 있는 <code>&lt;li&gt;</code> 엘리먼트가 아니라 배열의 <code>&lt;ListItem /&gt;</code> 엘리먼트가 key를 가져야 한다.</p>
<table>
<thead>
<tr>
<th><img src="https://velog.velcdn.com/images/daymoon_/post/f6d3397e-717f-4ba0-bf29-459b751254d6/image.png" alt=""></th>
<th><img src="https://velog.velcdn.com/images/daymoon_/post/e39b2b23-dbc0-41b1-8a18-fad08f95cad5/image.png" alt=""></th>
<th><img src="https://velog.velcdn.com/images/daymoon_/post/428f678b-629b-493c-b04d-06a6ce028e21/image.png" alt=""></th>
</tr>
</thead>
</table>
<br>

<p>🛑 <strong>잘못된 Key 사용법</strong></p>
<pre><code class="language-javascript">function ListItem(props) {
  const value = props.value;
  return (
    // 틀렸습니다! 여기에는 key를 지정할 필요가 없습니다.
    &lt;li key={value.toString()}&gt;
      {value}
    &lt;/li&gt;
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =&gt;
    // 틀렸습니다! 여기에 key를 지정해야 합니다.
    &lt;ListItem value={number} /&gt;
  );
  return (
    &lt;ul&gt;
      {listItems}
    &lt;/ul&gt;
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  &lt;NumberList numbers={numbers} /&gt;,
  document.getElementById(&#39;root&#39;)
);</code></pre>
<br>

<p>✅ <strong>올바른 Key 사용법</strong></p>
<pre><code class="language-javascript">function ListItem(props) {
  // 맞습니다! 여기에는 key를 지정할 필요가 없습니다.
  return &lt;li&gt;{props.value}&lt;/li&gt;;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =&gt;
    // 맞습니다! 배열 안에 key를 지정해야 합니다.
    &lt;ListItem key={number.toString()} value={number} /&gt;
  );
  return (
    &lt;ul&gt;
      {listItems}
    &lt;/ul&gt;
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  &lt;NumberList numbers={numbers} /&gt;,
  document.getElementById(&#39;root&#39;)
);</code></pre>
<p>!codepen[gaearon/embed/ZXeOGM?default-tab=js%2Cresult]</p>
<br>

<h2 id="key는-형제-사이에만-고유한-값이어야-함">Key는 형제 사이에만 고유한 값이어야 함</h2>
<p>Key는 배열 안에서 형제 사이에서 고유해야 하고 전체 범위에서 고유할 필요는 없다. 두개의 다른 배열을 만들 때 동일한 key를 사용할 수 있다.</p>
<pre><code class="language-javascript">function Blog(props) {
  const sidebar = (
    &lt;ul&gt;
      {props.posts.map((post) =&gt;
        &lt;li key={post.id}&gt;
          {post.title}
        &lt;/li&gt;
      )}
    &lt;/ul&gt;
  );
  const content = props.posts.map((post) =&gt;
    &lt;div key={post.id}&gt;
      &lt;h3&gt;{post.title}&lt;/h3&gt;
      &lt;p&gt;{post.content}&lt;/p&gt;
    &lt;/div&gt;
  );
  return (
    &lt;div&gt;
      {sidebar}
      &lt;hr /&gt;
      {content}
    &lt;/div&gt;
  );
}

const posts = [
  {id: 1, title: &#39;Hello World&#39;, content: &#39;Welcome to learning React!&#39;},
  {id: 2, title: &#39;Installation&#39;, content: &#39;You can install React from npm.&#39;}
];
ReactDOM.render(
  &lt;Blog posts={posts} /&gt;,
  document.getElementById(&#39;root&#39;)
);</code></pre>
<p>!codepen[gaearon/embed/NReYGN?default-tab=js%2Cresult]</p>
<p>React에서 key는 힌트를 제공하지만 컴포넌트로 전달하지는 않는다. 컴포넌트에서 key와 동일한 값이 필요하면 다른 이름의 prop으로 명시적으로 전달한다.</p>
<pre><code class="language-javascript">const content = posts.map((post) =&gt;
  &lt;Post
    key={post.id}
    id={post.id}
    title={post.title} /&gt;
);</code></pre>
<p>위 예시에서 <code>Post</code> 컴포넌트는 <code>props.id</code>를 읽을 수 있지만 <code>props.key</code>는 읽을 수 없다.</p>
<br>

<h2 id="jsx에-map-포함시키기">JSX에 map() 포함시키기</h2>
<p>위 예시에서 별도의 <code>listItems</code> 변수를 선언하고 이를 JSX에 포함하면 다음과 같다.</p>
<pre><code class="language-javascript">function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =&gt;
    &lt;ListItem key={number.toString()}
              value={number} /&gt;
  );
  return (
    &lt;ul&gt;
      {listItems}
    &lt;/ul&gt;
  );
}</code></pre>
<p>JSX를 사용하면 중괄호 안에 모든 표현식을 포함시킬 수 있으므로 <code>map()</code>함수의 결과를 인라인으로 처리할 수 있다.</p>
<pre><code class="language-javascript">function NumberList(props) {
  const numbers = props.numbers;
  return (
    &lt;ul&gt;
      {numbers.map((number) =&gt;
        &lt;ListItem key={number.toString()}
                  value={number} /&gt;
      )}
    &lt;/ul&gt;
  );
}</code></pre>
<p>!codepen[gaearon/embed/BLvYMB?default-tab=js%2Cresult]</p>
<p>이 방식을 사용하면 코드가 더 깔끔해 지지만, 이 방식을 남발하는 것은 좋지 않다. JavasScript와 마찬가지로 가독성을 위해 변수로 추출해야 할지 아니면 인라인으로 넣을지는 개발자가 직접 판단해야 한다.</p>
<p>✨ <strong><code>map()</code> 함수가 너무 중첩된다면 컴포넌트로 추출하는 것이 좋다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : 조건부 렌더링]]></title>
            <link>https://velog.io/@daymoon_/ReactDocs-%EC%A1%B0%EA%B1%B4%EB%B6%80-%EB%A0%8C%EB%8D%94%EB%A7%81</link>
            <guid>https://velog.io/@daymoon_/ReactDocs-%EC%A1%B0%EA%B1%B4%EB%B6%80-%EB%A0%8C%EB%8D%94%EB%A7%81</guid>
            <pubDate>Thu, 02 Jun 2022 18:35:52 GMT</pubDate>
            <description><![CDATA[<h1 id="조건부-렌더링">조건부 렌더링</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/conditional-rendering.html">React_조건부 렌더링</a></p>
</blockquote>
<p>React에서는 원하는 동작을 캡슐화하는 컴포넌트를 만들 수 있다. 이렇게 하면 애플리케이션의 상태에 따라서 컴포넌트 중 몇 개만을 렌더링할 수 있다.</p>
<p>📖 <strong>캡슐화??</strong></p>
<ul>
<li><a href="http://www.ktword.co.kr/test/view/view.php?m_temp1=379">정보통신기술용어해설_캡슐화</a></li>
<li><a href="https://ko.wikipedia.org/wiki/%EC%BA%A1%EC%8A%90%ED%99%94">wikipedia_캡슐화</a></li>
<li>객체 지향 프로그래밍(OOP; Object-Oriented-Programming)의 특징</li>
<li>데이터(변수) 및 함수(처리방법, 메소드)를 클래스로 묶는 작업</li>
<li>임의의 객체 요소의 접근을 제한 ▶ 메소드나 프로퍼티 앞에 붙여 다른 객체에게 노출시키는 정도로써의 보호수준을 결정하는 제한자</li>
<li>정보 은닉 : 내부 데이터를 캡슐화시켜 변경을 어렵게하고 보호함</li>
</ul>
<br>

<p>React에서 조건부 렌더링은 JavaScript에서의 조건 처리와 같이 동작한다. <code>if</code>나 <code>조건부 연산자</code>와 같은 JavaScript 연산자를 현재 상태를 나타내는 에리먼트를 만드는 데에 사용해야 한다. 그러면 React는 현재 상태에 맞게 UI를 업데이트 한다.</p>
<br>

<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li>props 값을 받아서 상황에 따라 바뀌는 컴포넌트 2개를 생성<pre><code class="language-javascript">function UserGreeting(props) {
return &lt;h1&gt;Welcome back!&lt;/h1&gt;;
}
</code></pre>
</li>
</ul>
<p>function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}</p>
<pre><code>
&lt;br&gt;

⚙️ **예시 코드 - 2**
- true : `UserGreeting` 컴포넌트 렌더링
- false : `GuestGreeting` 컴포넌트 렌더링
```javascript
function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return &lt;UserGreeting /&gt;;
  }
  return &lt;GuestGreeting /&gt;;
}

ReactDOM.render(
  // Try changing to isLoggedIn={true}:
  &lt;Greeting isLoggedIn={false} /&gt;,
  document.getElementById(&#39;root&#39;)
);</code></pre><br>

<h2 id="엘리먼트-변수">엘리먼트 변수</h2>
<p>엘리먼트를 저장하기 위해 변수를 사용할 수 있다. 출력의 다른 부분은 변하지 않은 채로 컴포넌트의 일부를 조건부로 렌더링할 수 있다.</p>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li>로그아웃을 나타내는 <code>LogoutButton</code> 컴포넌트</li>
<li>로그인을 나타내는 <code>LoginButton</code> 컴포넌트<pre><code class="language-javascript">function LoginButton(props) {
return (
  &lt;button onClick={props.onClick}&gt;
    Login
  &lt;/button&gt;
);
}
</code></pre>
</li>
</ul>
<p>function LogoutButton(props) {
  return (
    <button onClick={props.onClick}>
      Logout
    </button>
  );
}</p>
<pre><code>
&lt;br&gt;

⚙️ **예시 코드 - 2**
- 현재 상황에 따라 `&lt;LoginButton /&gt;` 혹은 `&lt;LogoutButton /&gt;` 컴포넌트로 렌더링
- 이전 예시의 `&lt;Greeting /&gt;` 컴포넌트도 함께 렌더링
- 변수를 선언하고 `if`를 사용해서 조건부로 렌더링
```javascript
// ✨ 클래스형 컴포넌트 생성
class LoginControl extends React.Component {
  // 클래스 객체 생성 &amp; 초기화
  constructor(props) {
    // 부모 클래스를 물려받음 (즉, 부모 클래스를 사용하기 위해 super 사용)
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    let button;
    if (isLoggedIn) {
      // true
      button = &lt;LogoutButton onClick={this.handleLogoutClick} /&gt;;
    } else {
      // false
      button = &lt;LoginButton onClick={this.handleLoginClick} /&gt;;
    }

    return (
      &lt;div&gt;
        &lt;Greeting isLoggedIn={isLoggedIn} /&gt;
        {button}
      &lt;/div&gt;
    );
  }
}

ReactDOM.render(
  &lt;LoginControl /&gt;,
  document.getElementById(&#39;root&#39;)
);</code></pre><br>

<h2 id="논리--연산자로-if를-인라인으로-표현하기">논리 &amp;&amp; 연산자로 if를 인라인으로 표현하기</h2>
<p>JSX 안에는 중괄호를 이용해서 표현식을 포함할 수 있다. 그 안에 JavaScript의 논리 연산자 <code>&amp;&amp;</code>를 사용하면 쉽게 엘리먼트를 조건부로 넣을 수 있다.</p>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li>JavaScript에서 <code>true &amp;&amp; expression</code>은 항상 <code>expression</code>으로 평가되고 <code>false &amp;&amp; expression</code>은 항상 <code>flase</code>로 평가된다. 따라서 <code>&amp;&amp;</code> 뒤의 엘리먼트는 조건이 <code>true</code>일 때 출력된다. 조건이 <code>false</code>라면 React는 무시하고 건너뛰게 된다.</li>
<li><code>true &amp;&amp; expression</code>
<img src="https://velog.velcdn.com/images/daymoon_/post/ffc03326-5f03-4ff3-ba54-ed051f8e673e/image.png" alt=""></li>
<li><code>false &amp;&amp; expression</code>
<img src="https://velog.velcdn.com/images/daymoon_/post/dacd7bba-3bf5-4da8-9250-f3109ec40ed1/image.png" alt=""></li>
</ul>
<br>

<p>⚙️ <strong>예시 코드 - 2</strong></p>
<ul>
<li>falsy 표현식을 반환하면 여전히 <code>&amp;&amp;</code> 뒤에 표현식은 건너뛰지만 falsy 표현식이 반환됨다는 것에 주의해야 한다.</li>
<li>아래 코드는 <code>&lt;div&gt;0&lt;/div&gt;</code>이 render 메서드에서 반환된다.<pre><code class="language-javascript">render() {
const count = 0;
return (
  // {0 &amp;&amp; &lt;h1&gt;Messages: {count}&lt;/h1&gt;}
  // 🛑 falsy값 0이 들어가면 falsy값을 반환!!
  &lt;div&gt;
    {count &amp;&amp; &lt;h1&gt;Messages: {count}&lt;/h1&gt;}
  &lt;/div&gt;
);
}</code></pre>
</li>
</ul>
<br>

<h2 id="조건부-연산자로-if-else-구문-인라인으로-표현하기">조건부 연산자로 if-else 구문 인라인으로 표현하기</h2>
<p>엘리먼트를 조건부로 렌더링하는 다른 방법은 조건부 연산자인 <code>condition ? true : false</code>를 사용한다. (<code>삼항 조건 연산자</code>를 사용하자!)</p>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li>삼항 조건 연산자를 이용하면 다음과 같은 코드로 작성할 수 있다.<pre><code class="language-javascript">render() {
const isLoggedIn = this.state.isLoggedIn;
return (
  // true ▶ currently 반환
  // false ▶ not 반환
  &lt;div&gt;
    The user is &lt;b&gt;{isLoggedIn ? &#39;currently&#39; : &#39;not&#39;}&lt;/b&gt; logged in.
  &lt;/div&gt;
);
}</code></pre>
</li>
</ul>
<br>

<p>⚙️ <strong>예시 코드 - 2</strong></p>
<ul>
<li><code>예시 코드 - 1</code>보다 더 큰 표현식을 사용하면 다음과 같은 코드를 작성할 수 있다.<pre><code class="language-javascript">render() {
const isLoggedIn = this.state.isLoggedIn;
return (
  // true ▶ &lt;LogoutButton onClick={this.handleLogoutClick} /&gt; 반환
  // false ▶ &lt;LoginButton onClick={this.handleLoginClick} /&gt; 반환
  &lt;div&gt;
    {isLoggedIn
      ? &lt;LogoutButton onClick={this.handleLogoutClick} /&gt;
      : &lt;LoginButton onClick={this.handleLoginClick} /&gt;
    }
  &lt;/div&gt;
);
}</code></pre>
</li>
</ul>
<p>두 예시 코드 중에서 가독성이 좋다고 생각하는 것을 선택하면 된다. 즉, 본인의 취향이다. 만약 조건이 너무 복잡하다면 <code>컴포넌트 분리</code>를 사용하는 것이 효율적이다.</p>
<br>

<h2 id="컴포넌트가-렌더링하는-것을-막기">컴포넌트가 렌더링하는 것을 막기</h2>
<p>가끔 다른 컴포넌트에 의해 렌더링될 때 컴포넌트 자체를 숨기고 싶을 때가 있다. 이때는 렌더링 결과를 출력하는 대신 <code>null</code>을 반환하면 된다.</p>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li><p><code>&lt;WarningBanner /&gt;</code>가 <code>warn</code> prop의 값에 의해서 렌더링된다.</p>
</li>
<li><p>prop이 <code>false</code>라면 컴포넌트는 렌더링하지 않는다.</p>
<pre><code class="language-javascript">function WarningBanner(props) {
if (!props.warn) {
  return null;
}

return (
  &lt;div className=&quot;warning&quot;&gt;
    Warning!
  &lt;/div&gt;
);
}
</code></pre>
</li>
</ul>
<p>class Page extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showWarning: true};
    this.handleToggleClick = this.handleToggleClick.bind(this);
  }</p>
<p>  handleToggleClick() {
    this.setState(state =&gt; ({
      showWarning: !state.showWarning
    }));
  }</p>
<p>  render() {
    return (
      <div>
        <WarningBanner warn={this.state.showWarning} />
        <button onClick={this.handleToggleClick}>
          {this.state.showWarning ? &#39;Hide&#39; : &#39;Show&#39;}
        </button>
      </div>
    );
  }
}</p>
<p>ReactDOM.render(
  <Page />,
  document.getElementById(&#39;root&#39;)
);</p>
<p>```</p>
<p>!codepen[gaearon/embed/Xjoqwm?default-tab=js%2Cresult]</p>
<p>컴포넌트의 <code>render</code> 메서드로부터 <code>null</code>을 반환하는 것은 생명주기 메서드 호출에 영향을 주지 않는다. 그 예로 <code>componentDidUpdate</code>는 계속해서 호출되게 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : 이벤트 처리하기]]></title>
            <link>https://velog.io/@daymoon_/ReactDocs-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@daymoon_/ReactDocs-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 01 Jun 2022 16:35:50 GMT</pubDate>
            <description><![CDATA[<h1 id="이벤트-처리하기">이벤트 처리하기</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/handling-events.html">React_이벤트 처리하기</a></p>
</blockquote>
<p>React 엘리먼트에서 이벤트를 처리하는 방식은 DOM 엘리먼트에서 이벤트를 처리하는 방식과 매우 유사하다. 몇 가지 문법 차이는 다음과 같다.</p>
<ul>
<li>React의 이벤트는 소문자 대신 <code>카멜 케이스(camelCase)</code>를 사용한다.</li>
<li>JSX를 사용하여 문자열이 아닌 함수로 이벤트 핸들러를 전달한다.</li>
</ul>
<p>⚙️ *<em>HTML 코드 *</em></p>
<pre><code class="language-html">&lt;button onclick=&quot;activateLasers()&quot;&gt;
  Activate Lasers
&lt;/button&gt;</code></pre>
<br>

<p>⚙️ <strong>React 코드</strong></p>
<pre><code class="language-javascript">&lt;button onClick={activateLasers}&gt;
  Activate Lasers
&lt;/button&gt;</code></pre>
<p>또 다른 차이점으로, React에서는 <code>false</code>를 반환해도 기본 동작을 방지할 수 없다. 반드시 <code>preventDefault</code>를 명시적으로 호출해야 한다. 예를 들어, 일반 HTML에서 폼을 제출할 때 가지고 있는 기본 동작을 방지하기 위해 다음과 같은 코드를 작성할 수 있다.</p>
<p>⚙️ <strong>HTML 코드</strong></p>
<pre><code class="language-html">&lt;form onsubmit=&quot;console.log(&#39;You clicked submit.&#39;); return false&quot;&gt;
  &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;</code></pre>
<br>

<p>⚙️ <strong>React 코드</strong></p>
<pre><code class="language-javascript">function Form() {
  function handleSubmit(e) {
    e.preventDefault();
    console.log(&#39;You clicked submit.&#39;);
  }

  return (
    &lt;form onSubmit={handleSubmit}&gt;
      &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
    &lt;/form&gt;
  );
}</code></pre>
<p>여기서 <code>e</code>는 합성 이벤트이다. React는 W3 명세에 따라 합성 이벤트를 정의하기 때문에 브라우저 호환성에 대해 걱정할 필요가 없다. React 이벤트는 브라우저 고유 이벤트와 정확히 동일하게 동작하지는 않는다.</p>
<p>React를 사용할 때 DOM 엘리먼트가 생성된 후 리스너를 추가하기 위해 <code>addEventListener</code>를 호출할 필요가 없다. 대신, 엘리먼트가 처음 렌더링될 때 리스너를 제공하면 된다.</p>
<p>ES6 클래스를 사용하여 컴포넌트를 정의할 깨, 일반적인 패턴은 이벤트 핸들러를 클래스의 메서드로 만드는 것이다. 예를 들어, 다음 <code>Toggle</code> 컴포넌트는 사용자가 <code>ON</code>과 <code>OFF</code> 상태를 토글할 수 있는 버튼을 렌더링한다.</p>
<p>!codepen[gaearon/embed/xEmzGg?default-tab=js%2Cresult]</p>
<p>✨ <strong>bind?</strong></p>
<ul>
<li><code>bind()</code> 메소드가 호출되면 새로운 함수를 생성</li>
<li>받게 되는 첫 인자의 value로는 <code>this</code> 키워드를 설정하고, 이어지는 인자들은 바인드된 함수의 인수에 제공</li>
</ul>
<p>JSX 콜백 안에서 <code>this</code>의 의미에 대해 쥐의해야 한다. JavaScript에서 클래스 메서드는 기본적으로 바인딩되어 있지 않다. <code>this.handleClick</code>을 바인딩하지 않고 <code>onClick</code>에 전달하였다면, 함수가 실제 호출될 때 <code>this</code>는 <code>undefined</code>가 된다.</p>
<p>이는 React만의 특수한 동작이 아니며, JavaScript에서 함수가 작동하는 방식의 일부이다. 일반적으로 <code>onClick={this.handleClick}</code>과 같이 뒤에 <code>()</code>를 사용하지 않고 메서드를 참조할 경우, 해당 메서드를 바인딩 해야 한다.</p>
<p><code>bind</code>를 호출하는 것이 불편하다면, 이를 해결할 수 있는 두 가지 방법이 존재한다.</p>
<p>🔎 <strong>퍼블릭 클래스 필드 문법 ⭕</strong></p>
<ul>
<li><p>클래스 필드를 사용하여 콜백을 올바르게 바인딩할 수 있다.</p>
</li>
<li><p><code>Create-React-App</code>에서는 이 문법이 기본적으로 설정되어 있다.</p>
<pre><code class="language-javascript">class LoggingButton extends React.Component {
// 이 문법은 `this`가 handleClick 내에서 바인딩되도록 합니다.
// 주의: 이 문법은 *실험적인* 문법입니다.
handleClick = () =&gt; {
  console.log(&#39;this is:&#39;, this);
}

render() {
  return (
    &lt;button onClick={this.handleClick}&gt;
      Click me
    &lt;/button&gt;
  );
}
}</code></pre>
</li>
</ul>
<br>

<p>🔎 <strong>퍼블릭 클래스 필드 문법 ❌</strong></p>
<ul>
<li><p>클래스 필드 문법을 사용하고 있지 않다면, 콜백에 화살표 함수를 사용한다.</p>
<pre><code class="language-javascript">class LoggingButton extends React.Component {
handleClick() {
  console.log(&#39;this is:&#39;, this);
}

render() {
  // 이 문법은 `this`가 handleClick 내에서 바인딩되도록 합니다.
  return (
    &lt;button onClick={() =&gt; this.handleClick()}&gt;
      Click me
    &lt;/button&gt;
  );
}
}</code></pre>
</li>
</ul>
<p>이 문법의 문제점은 <code>LogginButton</code>이 렌더링될 때마다 다른 콜백이 생성된다. 대부분의 경우 문제가 되지 않으나, 콜백이 하위 컴포넌트에 props로서 전달된다면 그 컴포넌트들은 추가로 다시 렌더링을 수행할 수 도 있다. 이러한 종류의 성능 문제를 피하고자, 생성자 안에서 바인딩하거나 클래스 문법을 사용하는 것을 권장한다.</p>
<br>

<h2 id="이벤트-핸들러에-인자-전달하기">이벤트 핸들러에 인자 전달하기</h2>
<p>루프 내부에서는 이벤트 핸들러에 추가적인 매개변수를 전달하는 것이 일반적이다. 예를 들어, <code>id</code>가 행의 ID일 경우 다음 코드가 모두 작동한다.</p>
<pre><code class="language-javascript">// ▶ 두 코드는 서로 동등함!
// ⚙️ 화살표 함수 코드
&lt;button onClick={(e) =&gt; this.deleteRow(id, e)}&gt;Delete Row&lt;/button&gt;

// ⚙️ Funtion.porototype.bind 코드
&lt;button onClick={this.deleteRow.bind(this, id)}&gt;Delete Row&lt;/button&gt;</code></pre>
<p>두 경우 모두 React 이벤트를 나타내는 <code>e</code> 인자가 ID 뒤에 두 번째 인자로 전달된다. 화살표 함수를 사용하면 명시적으로 인자를 전달해야 하지만 <code>bind</code>를 사용할 경우 추가 인자가 자동으로 전달된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : State와 생명주기]]></title>
            <link>https://velog.io/@daymoon_/ReactDocs-State%EC%99%80-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0</link>
            <guid>https://velog.io/@daymoon_/ReactDocs-State%EC%99%80-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0</guid>
            <pubDate>Tue, 31 May 2022 14:24:37 GMT</pubDate>
            <description><![CDATA[<h1 id="state-and-lifecycle">State and Lifecycle</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/state-and-lifecycle.html">React_State and Lifecycle</a></p>
</blockquote>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li>엘리먼트 렌더링에서 UI를 업데이트</li>
<li>렌더링 된 출력값을 변경하기 위해 <code>ReactDOM.render()</code>를 호출<pre><code class="language-javascript">function tick() {
const element = (
  &lt;div&gt;
    &lt;h1&gt;Hello, world!&lt;/h1&gt;
    &lt;h2&gt;It is {new Date().toLocaleTimeString()}.&lt;/h2&gt;
  &lt;/div&gt;
);
ReactDOM.render(
  element,
  document.getElementById(&#39;root&#39;)
);
}
</code></pre>
</li>
</ul>
<p>setInterval(tick, 1000);</p>
<pre><code>
&lt;br&gt;

⚙️ **예시 코드 - 2**
- `Clock` 컴포넌트를 완전히 재사용하고 캡슐화
- 컴포넌트가 스스로 타이머를 설정하고 매초 스스로 업데이트
```javascript
function Clock(props) {
  return (
    &lt;div&gt;
      &lt;h1&gt;Hello, world!&lt;/h1&gt;
      &lt;h2&gt;It is {props.date.toLocaleTimeString()}.&lt;/h2&gt;
    &lt;/div&gt;
  );
}

function tick() {
  ReactDOM.render(
    &lt;Clock date={new Date()} /&gt;,
    document.getElementById(&#39;root&#39;)
  );
}

setInterval(tick, 1000);</code></pre><br>

<p>⚙️ <strong>예시 코드 - 3</strong></p>
<ul>
<li><code>예시코드 - 2</code>에는 중요한 요건이 누락되어 있다. <code>Clock</code>이 타이머를 설정하고 매초 UI를 업데이트하는 것이 <code>Clock</code>의 구면 세부사항이 되여야 한다.</li>
<li>이상적으로 한 번만 코드를 작성하고 <code>Clock</code>이 스스로 업데이트 업데이트하도록 만들려면 <code>state</code>를 추가해야 한다.</li>
<li><code>state</code>는 <code>props</code> 와 유사하지만, 비공개이며 컴포넌트에 위해 완전히 제어된다.<pre><code class="language-javascript">ReactDOM.render(
&lt;Clock /&gt;,
document.getElementById(&#39;root&#39;)
);</code></pre>
</li>
</ul>
<br>

<h2 id="함수에서-클래스로-변환하기">함수에서 클래스로 변환하기</h2>
<p>✨ <strong>함수 컴포넌트 ▶ 클래스 컴포넌트 변환 과정</strong></p>
<ol>
<li><code>React.Component</code>를 확장하는 동일한 이름의 ES6 class를 생성</li>
<li><code>render()</code>라고 불리는 빈 메서드 추가</li>
<li>함수의 내용을 <code>render()</code> 메서드 안으로 옮김</li>
<li><code>render()</code> 내용 안에 있는 <code>props</code>를 <code>this.props</code>로 변경</li>
<li>남아있는 빈 함수 선언을 삭제</li>
</ol>
<p>!codepen[gaearon/embed/zKRGpo?default-tab=js%2Cresult]</p>
<br>

<p>⚙️ <strong>클래스 컴포넌트로 정의된 코드</strong></p>
<ul>
<li><code>Clock</code>은 클래스 컴포넌트로 정의!!</li>
<li><code>render</code>메서드는 업데이트가 발생할 때마다 호출되지만, 같은 DOM노드로 <code>&lt;Click /&gt;</code>을 렌더링하는 경우 <code>Clock</code>클래스의 단일 인스턴스만 사용된다. 이것은 로컬 state와 생명주기 메서드와 같은 부가적인 기능ㄹ 사용할 수 있게 해준다.<pre><code class="language-javascript">class Clock extends React.Component {
render() {
  return (
    &lt;div&gt;
      &lt;h1&gt;Hello, world!&lt;/h1&gt;
      &lt;h2&gt;It is {this.props.date.toLocaleTimeString()}.&lt;/h2&gt;
    &lt;/div&gt;
  );
}
}</code></pre>
</li>
</ul>
<br>

<h2 id="클래스에-로컬-state-추가하기">클래스에 로컬 State 추가하기</h2>
<p>✨ <strong>props ▶ state 변환 과정</strong></p>
<ol>
<li><code>render()</code> 메서드 안에 있는 <code>this.props.date</code>를 <code>this.state.date</code>로 변경<pre><code class="language-javascript">class Clock extends React.Component {
render() {
 return (
   &lt;div&gt;
     &lt;h1&gt;Hello, world!&lt;/h1&gt;
       // props ▶ state
     &lt;h2&gt;It is {this.state.date.toLocaleTimeString()}.&lt;/h2&gt;
   &lt;/div&gt;
 );
}
}</code></pre>
</li>
</ol>
<br>

<ol start="2">
<li><p>초기 <code>this.state</code>를 지정하는 <code>class constructor</code>를 추가</p>
<pre><code class="language-javascript">// class 키워드 추가
class Clock extends React.Component {
// 🔎 constructor
// - class로 생성된 객체를 생성하고 초기화하기 위한 특수한 메서드
// - class 안에 단 1개만 존재 ▶ 여러 개가 존재하면 문법오류(SyntaxError)
// - 부모 클래스의 constructor를 호출하기 위해 super 키워드를 사용

// 🛑 클래스 컴포넌트는 항상 props로 기본 constructor를 호출
constructor(props) {
 super(props);
 this.state = {date: new Date()};
}

render() {
 return (
   &lt;div&gt;
     &lt;h1&gt;Hello, world!&lt;/h1&gt;
     &lt;h2&gt;It is {this.state.date.toLocaleTimeString()}.&lt;/h2&gt;
   &lt;/div&gt;
 );
}
}</code></pre>
</li>
</ol>
<br>

<ol start="3">
<li><code>&lt;Clock /&gt;</code> 요소에서 <code>date</code> props을 삭제<pre><code class="language-javascript">ReactDOM.render(
&lt;Clock /&gt;,
document.getElementById(&#39;root&#39;)
);</code></pre>
</li>
</ol>
<br>

<p>⚙️ <strong>완성 코드</strong></p>
<ul>
<li><code>clock</code>이 스스로 타이머를 설정하고 매초 스스로 업데이트하도록 코드를 수정</li>
</ul>
<p>!codepen[gaearon/embed/KgQpJd?default-tab=js%2Cresult]</p>
<br>

<h2 id="생명주기-메서드를-클래스에-추가하기">생명주기 메서드를 클래스에 추가하기</h2>
<p>많은 컴포넌트가 있는 애플리케이션에서 컴포넌트가 삭제될 때 해당 컴포넌트가 사용 중이던 리소스를 확보하는 것이 중요하다.</p>
<br>

<p>⚙️ <strong>생명주기 메서드</strong></p>
<ul>
<li><p><code>Clock</code>이 처음 DOM에 렌더링 될 때마다 타이머를 설정 ▶ 마운팅(Mountimg)</p>
</li>
<li><p><code>Clock</code>에 의해 생성된 DOM이 삭제될 때마다 타이머를 해제 ▶ 언마운팅(Unmounting)</p>
<pre><code class="language-javascript">class Clock extends React.Component {
constructor(props) {
  super(props);
  this.state = {date: new Date()};
}

componentDidMount() {
}

componentWillUnmount() {
}

render() {
  return (
    &lt;div&gt;
      &lt;h1&gt;Hello, world!&lt;/h1&gt;
      &lt;h2&gt;It is {this.state.date.toLocaleTimeString()}.&lt;/h2&gt;
    &lt;/div&gt;
  );
}
}</code></pre>
</li>
</ul>
<br>

<p>✅ <strong>ComponentDidMount()</strong></p>
<ul>
<li>컴포넌트 출력물이 DOM에 렌더링 된 후에 실행</li>
<li>즉, 컴포넌트 업데이트가 끝나면 호출<pre><code class="language-javascript">// 타이머 설정
componentDidMount() {
  this.timerID = setInterval(
    () =&gt; this.tick(),
    1000
  );
}</code></pre>
</li>
</ul>
<br>

<p>✅ <strong>componentWillUnmount()</strong></p>
<ul>
<li>컴포넌트가 사라지기 전에 호출<pre><code class="language-javascript">componentWillUnmount() {
  clearInterval(this.timerID);
}</code></pre>
</li>
</ul>
<br>

<p><code>this.timerID</code> 사용을 주의해야한다.</p>
<p><code>this.props</code>가 React에 의해 스스로 설정되고 <code>this.state</code>가 특수한 의미가 있지만, 타이머 ID와 같이 데이터 흐름안에 포함되지 않는 어떤 항목을 보관할 필요가 있다면 자유롭게 클래스에 수동으로 부가적으로 필드를 추가해도 된다.</p>
<br>

<p>⚙️ <strong>최종 코드</strong></p>
<ul>
<li>컴포넌트 로컬 state를 업데이트하기 위해 <code>this.setState()</code>를 사용</li>
</ul>
<p>!codepen[gaearon/embed/amqdNr?default-tab=js%2Cresult]</p>
<br>

<p>✨ <strong>최종 코드 : 호출 순서</strong></p>
<ol>
<li><p><code>&lt;Clock /&gt;</code>가 <code>ReactDOM.render()</code>로 전달되었을 때 React는 <code>Clock</code> 컴포넌트의 constructor를 호출 → <code>Clock</code>이 현재 시각을 표시해야 하기 때문에 현재 시각이 포함된 객체로 <code>this.state</code>를 초기화 &amp; 나중에 state를 업데이트</p>
</li>
<li><p>React <code>Clock</code> 컴포넌트의 <code>render()</code> 메서드 호출 → React는 화면에 표시되어야 할 내용을 확인 → React는 <code>Clock</code>의 렌더링 출력값을 일치시키기 위해 DOM 업데이트</p>
</li>
<li><p><code>Clock</code> 출력값이 DOM에 삽입 → React는 <code>componentDidMount()</code> 생명 주기 메서드 호출 → <code>Clock</code> 컴포넌트는 매초 컴포넌트의 <code>tick()</code> 메서드를 호출하기 위한 타이머를 설정하도록 브라우저 요청</p>
</li>
<li><p>매초 브라우저가 <code>tick()</code> 메서드를 호출 → <code>Clock</code> 컴포넌트는 <code>setState()</code>에 현재 시각을 포함하는 객체를 호출 &amp; UI 업데이트 → <code>setState()</code>호출 덕분에 React는 변경을 감지 &amp; 화면에 표시될 내용을 알아내기 위해 <code>render()</code> 메서드를 재호출 → <code>render()</code> 메서드 안의 <code>this.state.date</code>가 달라지고 렌더링 출력값은 업데이트된 시작을 포함 → React는 이에 따라 DOM을 업데이트</p>
</li>
<li><p><code>Clock</code> 컴포넌트가 DOM으로부터 한 번이라도 삭제된 적이 딨으면 React는 타이머를 멈추기 위해 <code>componentWillUnmount()</code> 생명주기 메서드 호출</p>
</li>
</ol>
<br>

<h2 id="state를-올바르게-사용하기">State를 올바르게 사용하기</h2>
<p><code>setState()</code>를 사용하기 위해 알아야할 세 가지가 있다.</p>
<p>✨ <strong>직접 State를 수정하지 않는다.</strong></p>
<pre><code class="language-javascript">// Wrong ▶ 컴포넌트를 다시 렌더링 하지 않음
this.state.comment = &#39;Hello&#39;;

// Correct ▶ this.state를 지정할 수 있는 유일한 공간은 constructor
this.setState({comment: &#39;Hello&#39;});</code></pre>
<br>

<p>✨ <strong>state 업데이트는 비동기적일 수도 있다.</strong>
React는 성능을 위해 여러 <code>setState()</code> 호출을 단일 업데이트로 한꺼번에 처리할 수 있다.</p>
<p><code>this.props</code>와 <code>this.state</code>가 비동기적으로 업데이트될 수 있기 때문에 다음 state를 계산할 때 해당 값에 의존해서는 안 된다.</p>
<p>다음 코드는 카운터 업데이트에 실패한 경우이다.</p>
<pre><code class="language-javascript">// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});</code></pre>
<p>위 코드를 수정하기 위해 객체보다는 함수를 인자로 사용하는 다른 형태의 <code>setState()</code>를 사용해야 한다. 그 함수는 이전 state를 첫 번째 인자로 받아들일 것이고, 업데이트가 적용된 시점의 props를 두 번째 인자로 받아들일 것이다</p>
<pre><code class="language-javascript">// ▶ 화살표 함수 (arrow function)
// Correct
this.setState((state, props) =&gt; ({
  counter: state.counter + props.increment
}));

// ▶ 일반 함수 (function)
// Correct
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});
</code></pre>
<br>

<p>✨ <strong>state 업데이트는 병합된다.</strong>
<code>setState()</code>를 호출할 때 React는 제공한 객체를 현재 state로 병합한다.</p>
<p>state는 다양한 독립적인 변수를 포함할 수 있다.</p>
<pre><code class="language-javascript">  constructor(props) {
    super(props);
    this.state = {
      posts: [],
      comments: []
    };
  }</code></pre>
<p>별도의 <code>setState()</code> 이러한 변수를 독립적으로 업데이트할 수 있다.</p>
<pre><code class="language-javascript">componentDidMount() {
    fetchPosts().then(response =&gt; {
      this.setState({
        posts: response.posts
      });
    });

    fetchComments().then(response =&gt; {
      this.setState({
        comments: response.comments
      });
    });
  }</code></pre>
<p>병합은 얕게 이루어지기 때문에 <code>this.setState({comments})</code>는 <code>this.state.posts</code>에 영향을 주진 않지만 <code>this.state.comments</code>는 새로운 값으로 대체된다.</p>
<br>

<p>✨ <strong>데이터는 아래로 흐른다.</strong>
부모 컴포넌트나 자식 컴포넌트 모두 측정 컴포넌트가 유 상태인지 또는 무 상태인지 알수 없고, 그들이 함수나 클래스로 정의되었는지에 대해 관심을 가질 필요가 없다.</p>
<p>이 때문에 state는 종종 로컬 또는 캡슐화라고 불린다. state가 소유하고 설정한 컴포넌트 이외에는 어떠한 컴포넌트에도 접근할 수 없다.</p>
<p>컴포넌트는 자신의 state를 자식 컴포넌트에 props로 전달할 수 있다.</p>
<pre><code class="language-javascript">&lt;FormattedDate date={this.state.date} /&gt;</code></pre>
<p><code>FormatteedDate</code> 컴포넌트는 <code>date</code>를 자신의 props로 받을 것이고 이것이 <code>Clock</code>의 state로부터 왔는지, <code>Clock</code>의 props에서 왔는지, 수통으로 입력한 것인지 알지 못한다.</p>
<pre><code class="language-javascript">function FormattedDate(props) {
  return &lt;h2&gt;It is {props.date.toLocaleTimeString()}.&lt;/h2&gt;;
}</code></pre>
<p>일반적으로 이를 하향식(top-dwon) 또는 단방향식 데이터 프흠이라고 한다. 모든 state는 항상 특정한 컴포넌트가 소유하고 있으며 그 state로 부터 파생된 UI 또는 데이터는 오직 트리구조에서 자신의 아래에 있는 컴포넌트에만 영향을 미친다.</p>
<p>트리구조가 props들의 폭포라고 상상하면 각 컴포넌트의 state는 임의의 점에서 만나지만 동시에 아래로 흐르는 부가적인 수원(water source)이라고 할 수 있다.</p>
<p>모든 컴포넌트가 완전히 독립적이라는 것을 보여주기 위해 <code>App</code> 렌더링 하는 세 개의 <code>&lt;Clock&gt;</code> 예시 코드이다.</p>
<pre><code class="language-javascript">function App() {
  return (
    &lt;div&gt;
      &lt;Clock /&gt;
      &lt;Clock /&gt;
      &lt;Clock /&gt;
    &lt;/div&gt;
  );
}

ReactDOM.render(
  &lt;App /&gt;,
  document.getElementById(&#39;root&#39;)
);</code></pre>
<p>각 <code>Clock</code>은 자신만의 타이머를 설정하고 독립적으로 업데이트를 한다.</p>
<p>React 앱에서 컴포넌트가 유상태 또는 무상태에 대한 것은 시간이 지남에 따라 변경될 수 있는 구현 세부 사항으로 간주한다. 유상태 컴포넌트 안에서 무상태 컴포넌트를 사용할 수 있으며, 그 반대 경우도 마찬가지로 사용할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : Components와 Props]]></title>
            <link>https://velog.io/@daymoon_/ReactDocs-Components%EC%99%80-Props</link>
            <guid>https://velog.io/@daymoon_/ReactDocs-Components%EC%99%80-Props</guid>
            <pubDate>Mon, 30 May 2022 17:01:57 GMT</pubDate>
            <description><![CDATA[<h1 id="components와-props">Components와 Props</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/components-and-props.html">React_Components와 Props</a></p>
</blockquote>
<p>컴포넌트를 통해 UI를 재사용 가능한 개별적인 여러 조각으로 나누고, 각 조각을 개별적으로 살펴볼 수 있다.</p>
<p>개념적으로 컴포넌트는 JavaScript 함수와 유사하다. <code>props</code>라고 하는 임의의 입력을 받은 후, 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환한다.</p>
<br>

<h2 id="함수-컴포넌트와-클래스-컴포넌트">함수 컴포넌트와 클래스 컴포넌트</h2>
<blockquote>
<p>📑 <strong>참고자료</strong>
<a href="https://velog.io/@daymoon_/React-Components">React : Components</a>
<a href="https://devowen.com/298">devowen_[React] 클래스형 컴포넌트 vs 함수형 컴포넌트</a></p>
</blockquote>
<p>⚙️ <strong>함수형 컴포넌트</strong></p>
<ul>
<li>ES6 화살표 함수(arrow function)로 컴포넌트 정의 가능</li>
<li>클래스형 컴포넌트보다 선언하기 쉽고, 메모리 자원을 덜 사용</li>
<li><code>return</code>을 이용하여 JSX 반환</li>
<li>Hook을 이용하면 클래스 컴포넌트의 기능을 사용할 수 있음 ▶ state, life cycle, render()함수, ...<pre><code class="language-javascript">// ✨ 일반 function 정의
// 자신이 종속된 객체를 this로 가리킴
function Welcome(props) {
return &lt;h1&gt;Hello, {props.name}&lt;/h1&gt;;
}
</code></pre>
</li>
</ul>
<p>// ✨ arrow function정의
// 자신이 종속된 인스턴스를 가리킴
const Welcome = (props) =&gt; {
  return <h1>Hello, {props.name}</h1>;
}</p>
<pre><code>
&lt;br&gt;

⚙️ **클래스 컴포넌트**
- ES6 class를 이용하여 컴포넌트를 정의
- `extends React.Component` 속성 포함 ▶ 컴포넌트를 상속 받음
- `render()`함수를 이용하여 JSX 반환
- `props` 접근 시 `this` 키워드 사용
```javascript
class Welcome extends React.Component {
  render() {
    return &lt;h1&gt;Hello, {this.props.name}&lt;/h1&gt;;
  }
}</code></pre><br>

<p>🛑 <strong>React 관점</strong></p>
<ul>
<li>React 관점으로 볼 때 <code>함수형</code>과 <code>클래스</code> 유형은 동일하다.</li>
</ul>
<br>

<h2 id="컴포넌트-렌더링">컴포넌트 렌더링</h2>
<p>⚙️ <strong>DOM 태그만 사용한 React 엘리먼트</strong></p>
<pre><code class="language-javascript">const element = &lt;div /&gt;;</code></pre>
<br>

<p>⚙️ <strong>사용자 정의 컴포넌트를 사용한 React 엘리먼트</strong></p>
<ul>
<li>React가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX 어트리뷰트와 자식을 해당 컴포넌트에 단일 객체로 전달</li>
<li>이 객체를 <code>props</code>라고 함<pre><code class="language-javascript">const element = &lt;Welcome name=&quot;Sara&quot; /&gt;;</code></pre>
</li>
</ul>
<p>⚙️ <strong>코드 예시</strong></p>
<ol>
<li><code>&lt;Welcome name=&quot;Sara&quot; /&gt;</code> 엘리먼트로 <code>ReactDOM.render()</code>를 호출</li>
<li>React는 <code>{name: &#39;Sara&#39;}</code>를 props로 하여 사용자 정의 <code>Welcome</code> 컴포넌트를 호출</li>
<li><code>Welcome</code> 컴포넌트는 props를 받아 <code>&lt;h1&gt;Hello, Sara&lt;/h1&gt;</code>를 반환</li>
<li>ReactDOM은 <code>&lt;h1&gt;Hello, Sara&lt;/h1&gt;</code>엘리먼트와 일치하도록 DOM을 효율적으로 업데이트</li>
</ol>
<p>!codepen[gaearon/embed/YGYmEG?default-tab=js%2Cresult]</p>
<br>

<p>🛑 <strong>컴포넌트의 이름</strong></p>
<ul>
<li>컴포넌트의 첫 문자는 항상 대문자로 시작</li>
<li>ex) Welcome ⭕, welcome ❌</li>
</ul>
<br>

<h2 id="컴포넌트-합성">컴포넌트 합성</h2>
<p>컴포넌트는 자심의 출력에 다른 컴포넌트를 참조할 수 있다. 이는 모든 세부 단계에서 동일한 추상 컴포넌트를 사용할 수 있음을 의미한다. React 앱에서는 버튼, 폼, 다이얼로그, 화면 등의 모든 것들이 흔히 컴포넌트로 표현된다.</p>
<p>⚙️ <strong>예시 코드</strong></p>
<ul>
<li><code>Welcome</code>컴포넌트를 여러 번 렌더링하는 <code>App</code>컴포넌트</li>
</ul>
<p>!codepen[gaearon/embed/KgQKPM?default-tab=js%2Cresult]</p>
<br>

<h2 id="컴포넌트-추출">컴포넌트 추출</h2>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li>컴포넌트를 여러 개의 작은 컴포넌트로 나눔</li>
<li>props 반영 : author, text, date</li>
<li>중첩 구조 : 변형과 재사용이 어려움
!codepen[gaearon/embed/VKQwEo?default-tab=js%2Cresult]</li>
</ul>
<br>

<p>⚙️ <strong>예시 코드 - 2</strong></p>
<ul>
<li><code>Avatar</code> 컴포넌트<pre><code class="language-javascript">function Avatar(props) {
return (
  &lt;img className=&quot;Avatar&quot;
    src={props.user.avatarUrl}
    alt={props.user.name}
  /&gt;
);
}</code></pre>
</li>
</ul>
<br>

<ul>
<li><code>UserInfo</code> 컴포넌트<pre><code class="language-javascript">function UserInfo(props) {
return (
 &lt;div className=&quot;UserInfo&quot;&gt;
   &lt;Avatar user={props.user} /&gt;
   &lt;div className=&quot;UserInfo-name&quot;&gt;
     {props.user.name}
   &lt;/div&gt;
 &lt;/div&gt;
);
}</code></pre>
</li>
</ul>
<br>

<p>⚙️ <strong>예시 코드 - 3</strong></p>
<ul>
<li>컴포넌트 추출 → 재사용 가능한 컴포넌트 생성</li>
<li>UI가 여러 번 사용되거나, UI 일부가 자체적으로 복잡한 경우 별도의 컴포넌트를 생성하는게 좋음</li>
<li>규모가 큰 작업을 할 때 두각을 나타냄</li>
</ul>
<p>!codepen[gaearon/embed/MjQWQO?default-tab=js%2Cresult]</p>
<br>

<h2 id="props는-읽기-전용">props는 읽기 전용</h2>
<p><code>함수 컴포넌트</code>나 <code>클래스 컴포넌트</code> 모두 컴포넌트 자체에서 <code>props</code>를 수정할 수 없다.</p>
<p>⚙️ <strong>예시 코드 - 1</strong></p>
<ul>
<li>순수 함수 ⭕</li>
<li>입력값을 바꾸려 하지 않고 항상 동일한 입력값에 대해 동일한 결과를 반환<pre><code class="language-javascript">function sum(a, b) {
return a + b;
}</code></pre>
</li>
</ul>
<br>

<p>⚙️ <strong>예시 코드 - 2</strong></p>
<ul>
<li>순수 함수 ❌</li>
<li>자신의 입력값을 변경하기 때문에 순수 함수가 아님<pre><code class="language-javascript">function withdraw(account, amount) {
account.total -= amount;
}</code></pre>
</li>
</ul>
<br>

<p>✨ <strong>props를 사용할 경우 주의 사항</strong></p>
<ul>
<li><strong>모든 React 컴포넌트는 자신의 <code>props</code>를 다룰 때 반드시 순수 함수처럼 동작해야 함!!</strong></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : 엘리먼트 렌더링]]></title>
            <link>https://velog.io/@daymoon_/ReactDocs-%EC%97%98%EB%A6%AC%EB%A8%BC%ED%8A%B8-%EB%A0%8C%EB%8D%94%EB%A7%81</link>
            <guid>https://velog.io/@daymoon_/ReactDocs-%EC%97%98%EB%A6%AC%EB%A8%BC%ED%8A%B8-%EB%A0%8C%EB%8D%94%EB%A7%81</guid>
            <pubDate>Mon, 30 May 2022 15:03:53 GMT</pubDate>
            <description><![CDATA[<h1 id="엘리먼트-렌더링">엘리먼트 렌더링</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/rendering-elements.html">React_엘리먼트 렌더링</a></p>
</blockquote>
<p>엘리먼트는 React 앱의 가장 작은 단위를 말하며, 화면에 표시할 내용을 기술한다.</p>
<pre><code class="language-javascript">const element = &lt;h1&gt;Hello, world&lt;/h1&gt;;</code></pre>
<p>브라우저 DOM 엘리먼트와 달리 React 엘리먼트는 일반 객체(plain object)이며 쉽게 생성할 수 있다. React DOM은 React 엘리먼트와 일치하도록 DOM을 업데이트한다.</p>
<br>

<h2 id="dom에-엘리먼트-렌더링하기">DOM에 엘리먼트 렌더링하기</h2>
<p>⚙️ <strong>루트 노드</strong></p>
<pre><code class="language-javascript">&lt;div id=&quot;root&quot;&gt;&lt;/div&gt;</code></pre>
<ul>
<li>root DOM 노드라고 부른다.</li>
<li>이 안에 들어가는 모든 엘리먼트를 React DOM에서 관리한다.</li>
</ul>
<br>

<p>⚙️ <strong>엘리먼트</strong></p>
<pre><code class="language-javascript">const element = &lt;h1&gt;Hello, world&lt;/h1&gt;;</code></pre>
<br>

<p>⚙️ <strong>루트 노트에 렌더링</strong></p>
<pre><code class="language-javascript">const element = &lt;h1&gt;Hello, world&lt;/h1&gt;;
ReactDOM.render(element, document.getElementById(&#39;root&#39;));</code></pre>
<ul>
<li>React 엘리먼트를 루트 DOM노드에 렌더링하려면 <code>ReactDOM.render()</code>로 전달한다.</li>
</ul>
<br>

<p>🔎 <strong>코드 예시</strong></p>
<p>!codepen[gaearon/embed/edyBaE?default-tab=js%2Cresult]</p>
<br>

<h2 id="렌더링-된-엘리먼트-업데이트하기">렌더링 된 엘리먼트 업데이트하기</h2>
<p>React 엘리먼트는 <code>불변 객체</code>이다. 엘리먼트를 생성한 이후에는 해당 엘리먼트의 자식이나 속성을 변경할 수 없다. 즉, 하나의 프레임과 같이 특정 시점의 UI만 보여준다.</p>
<p>UI를 업데이트하는 유일한 방법은 새로운 엘리먼트를 생성하고 <code>ReactDOM.render()</code>로 전달하면 된다.</p>
<br>

<p>🔎 <strong>코드 예시</strong></p>
<ul>
<li><code>setInterval()</code>콜백을 이용해 초마다 <code>ReactDOM.render()</code>를 호출한다.
!codepen[gaearon/embed/gwoJeZ?default-tab=js%2Cresult]</li>
</ul>
<br>

<h2 id="변경된-부분만-업데이트하기">변경된 부분만 업데이트하기</h2>
<p>React DOM은 해당 엘리먼트와 그 자식 엘리먼트를 이전의 엘리먼트와 비교하고 DOM을 원하는 상태로 만드는데 필요한 경우에만 DOM을 업데이트한다.</p>
<p>즉, 매번 똑같은 것을 업데이트하는 것이 아닌 엘리먼트를 서로 비교하여 변경된 부분만 업데이트를 한다.</p>
<p><img src="https://ko.reactjs.org/c158617ed7cc0eac8f58330e49e48224/granular-dom-updates.gif" alt=""></p>
<p>⚙️ <strong><code>&lt;h2&gt;It is {new Date().toLocaleTimeString()}.&lt;/h2&gt;</code></strong></p>
<ul>
<li>React DOM은 내용이 변경된 텍스트 노드만 업데이트 한다.</li>
<li>이 태그에서는 <code>{new Date().toLocaleTimeString()}</code>부분이 <code>setInterval()</code>함수로 계속 바뀌고 있다. ▶ 이 부분만 업데이트!!</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React_Docs : JSX 소개]]></title>
            <link>https://velog.io/@daymoon_/ReactDocs-JSX-%EC%86%8C%EA%B0%9C</link>
            <guid>https://velog.io/@daymoon_/ReactDocs-JSX-%EC%86%8C%EA%B0%9C</guid>
            <pubDate>Sat, 28 May 2022 18:24:09 GMT</pubDate>
            <description><![CDATA[<h1 id="jsx-소개">JSX 소개</h1>
<blockquote>
<p>🔎 <strong>React 공식문서 자료</strong>
<a href="https://ko.reactjs.org/docs/introducing-jsx.html">React_JSX 소개</a></p>
</blockquote>
<p>🔷 <strong>소개</strong></p>
<pre><code class="language-javascript">const element = &lt;h1&gt;Hello, world!&lt;/h1&gt;;</code></pre>
<ul>
<li>Javascript를 확장한 문법</li>
<li>Javascript의 모든 기능 포함</li>
<li>UI가 어떻게 생겨야 하는지 설명하기 위해 React와 함께 사용할 것을 권장</li>
</ul>
<br>

<h2 id="jsx란">JSX란?</h2>
<blockquote>
<p>📖 <strong>참고자료</strong>
<a href="https://thebook.io/080203/ch02/02/">더북_리액트를 다루는 기술 [개정판]</a></p>
</blockquote>
<p>JSX는 자바스크립트의 확장 문법으로 XML과 매우 비슷하게 생겼다.</p>
<p>아래와 같이 작성한 코드는 브라우저에서 실행되기 전에 코드가 번들링되는 과정에서 바벨을 사용하여 일반 자바스크립트 형태로 코드를 변환한다.</p>
<p>⚙️ <strong>JSX</strong></p>
<pre><code class="language-javascript">function App() {
  return (
    &lt;div&gt;
      Hello &lt;b&gt;react&lt;/b&gt;
    &lt;/div&gt;
  );
}</code></pre>
<p>⚙️ <strong>JSX 코드 변환</strong></p>
<pre><code class="language-javascript">function App() {
return React.createElement(“div“, null, “Hello “, React.createElement(“b“, null, “react“));
}</code></pre>
<p>컴포넌트를 렌더링할 때마다 JSX코드로 작성하는 것이 아니라 <code>React.createElement</code>처럼 작성하면 불편하고 번거롭다.</p>
<p>JSX를 사용하면 매우 편하게 UI를 렌더링할 수 있다. 또한, React가 에러 및 경고 메시지를 표시할 수 있게 한다.</p>
<br>

<h3 id="jsx에-표현식-포함하기">JSX에 표현식 포함하기</h3>
<p>⚙️ <strong>코드 예시 - 1</strong></p>
<pre><code class="language-javascript">// name 변수 선언
const name = &#39;Josh Perez&#39;;

// {중괄호}로 변수 name을 감싸 JSX안에 코드 작성
const element = &lt;h1&gt;Hello, {name}&lt;/h1&gt;;

ReactDOM.render(
  element,
  document.getElementById(&#39;root&#39;)
);</code></pre>
<br>

<p>⚙️ <strong>코드 예시 - 2</strong></p>
<pre><code class="language-javascript">// formatName 함수 생성 → user 객체를 받아서 값을 반환
function formatName(user) {
  return user.firstName + &#39; &#39; + user.lastName;
}

// user 객체 생성
const user = {
  firstName: &#39;Harper&#39;,
  lastName: &#39;Perez&#39;
};

// {중괄호}로 감싸서 JSX안에 작성
const element = (
  &lt;h1&gt;
    Hello, {formatName(user)}!
  &lt;/h1&gt;
);

// ✨ 출력값
// Hello, Harper Perez!
ReactDOM.render(
  element,
  document.getElementById(&#39;root&#39;)
);</code></pre>
<br>

<p>✨ <strong>JSX도 javascript 문법인가요?!</strong></p>
<ul>
<li>JSX는 리액트로 프로젝트를 개발할 때 사용되므로 공식적인 자바스크립트 문법은 아니다.</li>
<li>Babel을 이용하면 개발자들이 임의로 만든 문법 또는 차기 자바스크립트 문법들을 사용할 수 있다.</li>
</ul>
<br>

<h3 id="jsx-표현식">JSX 표현식</h3>
<p>컴파일이 끝나면, JSX 표현식이 정규 Javascript를 호출하고 Javascript 객체를 인식한다.</p>
<p>즉, JSX도 <code>if</code>문 및 <code>for loop</code>, 변수 할당, 인자값 받기, 함수 반환을 할 수 있다.</p>
<pre><code class="language-javascript">function getGreeting(user) {
  if (user) {
    return &lt;h1&gt;Hello, {formatName(user)}!&lt;/h1&gt;;
  }
  return &lt;h1&gt;Hello, Stranger.&lt;/h1&gt;;
}</code></pre>
<br>

<h3 id="jsx-속성-정의">JSX 속성 정의</h3>
<p>⚙️ <strong>코드 예시</strong></p>
<pre><code class="language-javascript">// 어트리뷰트에 &quot;따옴표&quot;를 이용해 문자열 리터럴 정의 가능
const element = &lt;a href=&quot;https://www.reactjs.org&quot;&gt; link &lt;/a&gt;;

//  {중괄호}를 사용하여 어트리뷰트에 Javascript 표현식 사용 가능
const element = &lt;img src={user.avatarUrl}&gt;&lt;/img&gt;;</code></pre>
<br>

<p>🛑 <strong>주의</strong></p>
<ul>
<li>JSX는 HTML보다 Javascript에 가깝기 때문에, React DOM은 HTML 어트리뷰트 이름 대신 <code>camelCase(카멜 케이스)</code>규칙을 사용한다.</li>
<li>예를 들어, JSX에서 class는 <code>className</code>으로 작성한다.</li>
</ul>
<br>

<h3 id="jsx-자식-정의">JSX 자식 정의</h3>
<p>⚙️ <strong>코드 예시</strong></p>
<pre><code class="language-javascript">// 태그가 비어있다면 XML처럼 /를 이용하여 태그를 닫아줌 ▶ 닫힌 태그
const element = &lt;img src={user.avatarUrl} /&gt;;

// JSX 태그는 자식 포함 가능
const element = (
  &lt;div&gt;
    &lt;h1&gt;Hello!&lt;/h1&gt;
    &lt;h2&gt;Good to see you here.&lt;/h2&gt;
  &lt;/div&gt;
)</code></pre>
<br>

<h3 id="jsx-주입-공격-방지">JSX 주입 공격 방지</h3>
<p>애플리케이션에서 명시적으로 작성되지 않은 내용은 주입하지 않는다. 모든 항목은 렌더링 되기 전에 문자열로 변환된다. 이러한 특성으로 <code>XSS(Cross-Site-Scripting)</code>공격을 방지할 수 있다.</p>
<pre><code class="language-javascript">const title = response.potentiallyMaliciousInput;
const element = &lt;h1&gt;{title}&lt;/h1&gt;;</code></pre>
<br>

<p>✨ <strong>XSS(Cross-Site-Scripting)</strong></p>
<ul>
<li>사이트 간 스크립팅 or 크로스 사이트 스크립팅이라고 한다.</li>
<li>웹 애플리케이션의 취약점 ▶ 관리자가 아닌 사람이 웹 페이지에 악성 스크립트를 삽입</li>
<li>이 취약점으로 해커가 사용자의 정보(쿠키, 세션 등)을 탈취, 자동으로 비정상적인 기능을 수행하게 한다.</li>
<li>공격 유형 : 비 지속적(Non-pesistent) &amp; 지속적(persistent) 기법</li>
</ul>
<table>
<thead>
<tr>
<th>Non-persistent</th>
<th>persistent</th>
</tr>
</thead>
<tbody><tr>
<td>가장 일반적인 유형, 반사 XSS라고 함</td>
<td>더 치명적인 기법</td>
</tr>
<tr>
<td>웹 클라이언트가 제공하는 HTTP 쿼리 매개 변수에서 적절하지 않고, 구문 분석 및 해당 사용자에 대한 결과의 페이지를 표시하는 공격</td>
<td>공격자가 제공한 데이터가 서버에 저장된 다음 지속적으로 <code>정상적인 페이지</code>에서 다른 사용자에게 노출</td>
</tr>
</tbody></table>
<br>

<h3 id="jsx는-객체를-표현">JSX는 객체를 표현</h3>
<p>Babel은 JSX를 <code>React.createElement()</code>호출로 컴파일한다.</p>
<pre><code class="language-javascript">// ✨ 모두 동일한 코드!
// ex1
const element = (
  &lt;h1 className=&quot;greeting&quot;&gt;
    Hello, world!
  &lt;/h1&gt;
);

// ex2
const element = React.createElement(
  &#39;h1&#39;,
  {className: &#39;greeting&#39;},
  &#39;Hello, world!&#39;
);</code></pre>
<p><code>React.createElement()</code>는 버그가 없는 코드를 작성하는데 도움이 되도록 몇 가지 검사를 수행하며, 기본적으로 아래와 같은 객체를 생성한다.</p>
<pre><code class="language-javascript">// 🛑 주의 : 단순화된 구조
const element = {
  type: &#39;h1&#39;,
  props: {
    className: &#39;greeting&#39;,
    children: &#39;Hello, world!&#39;
  }
};</code></pre>
<p>이러한 객체를 <strong>React 엘리먼트</strong>라고 하며, 화면에서 보고 싶은 것을 나타내는 표현한다. React는 이 객체를 읽어서, DOM을 구성하고 최신 상태로 유지하는 데 사용한다.</p>
<br>

<p>🛑 <strong>주의</strong></p>
<ul>
<li>ES6 및 JSX 코드가 올바르게 표시되도록 편집기에 <code>Babel</code>언어 설정을 사용하는 것을 권장</li>
</ul>
<br>

<p>✨ <strong>Babel</strong></p>
<blockquote>
<p>📖 <strong>참고자료</strong>
<a href="https://babeljs.io/docs/en/">BABEL 공식문서_What is Babel?</a></p>
</blockquote>
<p>Babel은 Javascript Compiler이다.</p>
<p>즉, 최신 사양의 자바스크립트 코드를 IE나 구형 브라우저에서도 동작하는 ES5 이하의 코드로 변환(트랜스파일링)할 수 있다.</p>
<pre><code class="language-javascript">// Babel Input: ES2015 arrow function
[1, 2, 3].map(n =&gt; n + 1);

// Babel Output: ES5 equivalent
[1, 2, 3].map(function(n) {
  return n + 1;
});</code></pre>
<br>

<h2 id="정리">정리</h2>
<p>⚙️ <strong>JSX 장점</strong></p>
<ul>
<li>보기 쉽고 익숙하다.</li>
<li>활용도가 높다.
  1.&nbsp;HTML 태그에서 사용 가능
  2.&nbsp;컴포넌트 안에서 JSX 사용 가능</li>
</ul>
<hr>
<h2 id="🌺-comment">🌺 Comment</h2>
<p>리액트 공식 문서를 보면서 기초를 탄탄하게 만들어 보자..!! ╰(<em>°▽°</em>)╯</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DS : 자료구조의 소개]]></title>
            <link>https://velog.io/@daymoon_/DS-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%9D%98-%EC%86%8C%EA%B0%9C</link>
            <guid>https://velog.io/@daymoon_/DS-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%9D%98-%EC%86%8C%EA%B0%9C</guid>
            <pubDate>Sat, 28 May 2022 02:32:47 GMT</pubDate>
            <description><![CDATA[<h2 id="자료구조의-소개">자료구조의 소개</h2>
<blockquote>
<p>🗃️ <strong>강의</strong>
<a href="http://www.kmooc.kr/courses/course-v1:SMUk+SMU2018_01+2021_1_T1/course/">K-MOOC 자료구조</a></p>
</blockquote>
<h3 id="개요">개요</h3>
<p>🔶 <strong>Data structure</strong></p>
<ul>
<li>자료구조 : 자료를 효율적으로 관리하는 기법</li>
<li>자료(data), 관리(manipulation), 기법(technique), 효율적(efficiency)</li>
<li>리스트(list)/트리(tree) + 그래프(graph)</li>
</ul>
<br>

<h3 id="자료와-관리">자료와 관리</h3>
<h4 id="자료data는-무엇인가">자료(data)는 무엇인가?</h4>
<p>⚙️ <strong>자료(data)</strong></p>
<ul>
<li>컴퓨터에 저장할 수 있는 모든 값</li>
<li>컴퓨터에서 허용하는 형태의 값만 저장할 수 있음 ▶ 자료형</li>
</ul>
<br>

<p>⚙️ <strong>자료형(data type)</strong></p>
<ul>
<li>컴퓨터에 저장할 수 있도록 프로그래밍 언어에서 <code>미리 정의된 값</code>들의 집합
  1.&nbsp;시스템에서 제공하는 자료형
  2.&nbsp;사용자가 정의하는 자료형</li>
</ul>
<br>

<p>⚙️ <strong>시스템에서 제공하는 자료형(system-defined data type)</strong></p>
<ul>
<li>자료의 단위</li>
</ul>
<table>
<thead>
<tr>
<th>비트(bit)</th>
<th>바이트(byte)</th>
<th>워드(word)</th>
</tr>
</thead>
<tbody><tr>
<td>0 또는 1을 기록할 수 있는 최소 단위</td>
<td>1byte = 8bit</td>
<td>4bytes(32bit) 또는 8bytes(64bit)</td>
</tr>
<tr>
<td>ON/OFF, TRUE/FALSE</td>
<td>8개의 비트로 구성된 데이터의 양을 나타내는 단위</td>
<td>컴퓨터 내부에서 한 번에 전송하거나 처리하는 단위</td>
</tr>
</tbody></table>
<br>

<ul>
<li>자료의 구성
  1.&nbsp;세상의 모든 자료는 문자와 숫자로 구성
  2.&nbsp;문자 → char
  3.&nbsp;숫자 → 정수(int) or 실수(float)</li>
</ul>
<br>

<ul>
<li>char(문자 표현)</li>
</ul>
<table>
<thead>
<tr>
<th>ASCII CODE(아스키 코드)</th>
<th>uni-code(유니코드)</th>
</tr>
</thead>
<tbody><tr>
<td>8bit로 영어, 숫자, 특수 문자를 표현</td>
<td>16bit로 세상의 모든 문자를 표현(2^16)</td>
</tr>
<tr>
<td>7bits + 1bit(parity 검사)</td>
<td>한글까지 완벽하게 표현 가능</td>
</tr>
<tr>
<td>표현할 수 있는 문자에 한계가 존재(ex_한글)</td>
<td></td>
</tr>
</tbody></table>
<br>

<ul>
<li>int(정수 표현)
  1.&nbsp;4 byte를 사용 (시스템에 따라서 다름)
  2.&nbsp;short(2 bytes), long(4 bytes), unsigned int(4 bytes)등과 같은 다양한 정수 자료형이 존재함
  3.&nbsp;음수표현 ▶ 부호비트(sign bit), 1의 보수, 2의 보수    </li>
</ul>
<br>

<ul>
<li>float(실수 표현) : 부동 소수점(floating point)</li>
</ul>
<table>
<thead>
<tr>
<th>부호(sign)</th>
<th>지수(exponent)</th>
<th>가수(value)</th>
</tr>
</thead>
<tbody><tr>
<td>1 bit</td>
<td>8 bits</td>
<td>23 bits</td>
</tr>
</tbody></table>
<br>

<p>⚙️ <strong>사용자 정의 자료형(user-defined data type)</strong></p>
<ul>
<li>하나의 자료는 다양한 자료형을 가진 요소들의 집합으로 표현될 수 있음</li>
<li>즉, 새로운 자료응 정의하기 위한 자료형으로 사용할 수 있도록 하는게 사용자 정의 자료형</li>
</ul>
<table>
<thead>
<tr>
<th>sctruct</th>
<th>class</th>
</tr>
</thead>
<tbody><tr>
<td>C</td>
<td>C++, JAVA, Python</td>
</tr>
</tbody></table>
<br>

<h4 id="관리란-무엇인가">관리란 무엇인가?</h4>
<p>⚙️ <strong>자료의 관리</strong></p>
<ul>
<li>추가(insert), 삭제(delete), 검색(search), 갱신(modify) 등 많은 관리 작업이 가능</li>
<li>가장 중요한 연산 : 추가, 삭제, 검색</li>
<li>추가와 삭제는 1번만 사용 가능</li>
<li>검색은 매우 빈번하게 사용 : 가장 중요한 관리 작업은 ✨<code>검색</code>✨</li>
</ul>
<br>

<p>⚙️ <strong>검색의 3가지 종류</strong></p>
<ul>
<li>주어진 집합에서 임의의 원소를 찾아라 ▶ find arbitrary</li>
<li>주어진 집합에서 가장 먼저/즙게 온 원소를 찾아라 ▶ find earliest/last</li>
<li>주어진 집합에서 최대/최소인 원소를 찾아라 ▶ find top</li>
</ul>
<hr>
<h2 id="🌺-comment">🌺 Comment</h2>
<p>자료구조도 다시 복습..
달려달려..! ╰(<em>°▽°</em>)╯</p>
<p>✨<strong>단원 기준 : KMOOC 기준으로 작성</strong>✨</p>
]]></description>
        </item>
    </channel>
</rss>