<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev_chae.log</title>
        <link>https://velog.io/</link>
        <description>반반무마니</description>
        <lastBuildDate>Sat, 22 Oct 2022 06:34:11 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev_chae.log</title>
            <url>https://velog.velcdn.com/images/dev_eunchae/profile/112acca3-6970-441a-b26d-5fc0e966f44c/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev_chae.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev_eunchae" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[git] LF will be replaced by CRLF in .editorconfig.]]></title>
            <link>https://velog.io/@dev_eunchae/git-LF-will-be-replaced-by-CRLF-in-.editorconfig</link>
            <guid>https://velog.io/@dev_eunchae/git-LF-will-be-replaced-by-CRLF-in-.editorconfig</guid>
            <pubDate>Sat, 22 Oct 2022 06:34:11 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/fbc4e99a-912f-424f-91d6-bc7dc890a9e0/image.png" alt=""></p>
<p>git add를 하다가 깜짝 놀람..</p>
<p>OS마다 줄 바꿈에 대한 문자열이 다르기 때문에 git에서 어느 쪽을 선택해야 할지 경고 메시지를 띄운 것!</p>
<p>core.autocrlf라는 기능을 켜주어야 한다.</p>
<blockquote>
<p>window </p>
</blockquote>
<p>git config --global core.autocrlf true</p>
<blockquote>
<p>Linux, MAC</p>
</blockquote>
<p>git config --global core.autocrlf input</p>
]]></description>
        </item>
        <item>
            <title><![CDATA['ERR_PACKAGE_PATH_NOT_EXPORTED']]></title>
            <link>https://velog.io/@dev_eunchae/ERRPACKAGEPATHNOTEXPORTED</link>
            <guid>https://velog.io/@dev_eunchae/ERRPACKAGEPATHNOTEXPORTED</guid>
            <pubDate>Sat, 22 Oct 2022 06:15:13 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/e8f7e9d8-5728-4162-af53-6d581c32abed/image.png" alt=""></p>
<p>yarn start!!!가 안된다구!</p>
<p>현재 나의 윈도우에 적용된 node 버전은 17
17버전에서 어떤 모듈과 충돌이 있는 듯 하여 16으로 내려보자</p>
<p>맥북이 고장나는 바람에 급하게 윈도우로 작업을 하던 중에 node를 17로 깔았나 보다. </p>
<p>nvm을 이용해서 버전을 바꿀 수 있다고 한다. </p>
<p><a href="https://codepathfinder.com/entry/NVM-Nodejs-%EB%B2%84%EC%A0%84-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0">node 버전변경하기</a></p>
<p>nvm 활용해서 노드 버전을 변경하려고 하는데 계속 글자가 깨지는 에러가 발생했다.</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/a21b6543-2fd5-4e5e-861e-727a6d92d77a/image.png" alt=""></p>
<p>cmd 프롬포트를 관리자로 열어주면 이 문제는 발생하지 않음</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/098cf735-384c-4f52-afa8-326e711ca003/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/690de78a-535d-4ef8-9392-fe50dae9407d/image.png" alt=""></p>
<p>이제 16으로 바꾸었으니 다 지워보고 node 모듈도 재설치해보고 </p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/7e18cfaa-383f-4d97-98bf-9aaa8022b551/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/e8392ee8-3ad1-4609-8121-91c8db9a7f03/image.png" alt=""></p>
<p>하 열렷다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[오늘난에러] rendered HTML error]]></title>
            <link>https://velog.io/@dev_eunchae/%EC%98%A4%EB%8A%98%EB%82%9C%EC%97%90%EB%9F%AC-rendered-HTML-error</link>
            <guid>https://velog.io/@dev_eunchae/%EC%98%A4%EB%8A%98%EB%82%9C%EC%97%90%EB%9F%AC-rendered-HTML-error</guid>
            <pubDate>Wed, 19 Oct 2022 11:46:34 GMT</pubDate>
            <description><![CDATA[<pre><code>const UserIds = [&quot;eun&quot;, &quot;chae&quot;];
const getRandomUserId = () =&gt; UserIds[Math.round(Math.random())];

const Data = Array(50)
  .fill(0)
  .map((_, i) =&gt; ({
    id: i + 1,
    userId: getRandomUserId(),
    timestamp: 123456780123 + i * 1000 * 60,
    text: `${i + 1} mock data`,
  }))</code></pre><p>Error: Text content does not match server-rendered HTML.</p>
<p>Error : Hydration failed because the initial UI does not match what was rendered on the server.</p>
<p> Error: Hydration failed because the initial UI does not match what was rendered on the server.</p>
<p>  Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.</p>
<hr>
<p>eun / chae 를 랜덤으로 얻기위한 const getRandomUserId = () =&gt; UserIds[Math.round(Math.random())] 함수에서 에러가 발생</p>
<p>함수를 사용하지 않고 userId에 하드 코딩 시에는 에러가 발생하지 않는다. </p>
<p>함수 실행 결과가 랜덤이라 매 번 값이 달라지기 때문에 &quot;서버와 클라이언트의 text content가 같지 않다&quot;는 오류가 발생하게 된다. 서버와 클라이언트에서 같은 값을 사용할 수 있도록 정식 데이터를 사용하여 해결하자. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Recoil]]></title>
            <link>https://velog.io/@dev_eunchae/Recoil</link>
            <guid>https://velog.io/@dev_eunchae/Recoil</guid>
            <pubDate>Tue, 27 Sep 2022 19:35:13 GMT</pubDate>
            <description><![CDATA[<h1 id="recoil-vs-redux">Recoil vs Redux</h1>
<h2 id="redux">Redux</h2>
<ul>
<li>액션, 리듀서, 미들웨어 등 boilerplate 코드가 많이 발생함</li>
<li>Redux 의 상태 구조는 트리 구조를 따름</li>
<li>Redux 에서는 reselect 같은 3rd-party 라이브러리가 필요</li>
</ul>
<h2 id="recoil">Recoil</h2>
<ul>
<li>Recoil 은 boilerplate-free API 를 제공함. </li>
<li>React 의 useState 처럼 간단한 게터(get) / 세터(set) 인터페이스로 사용 가능</li>
<li>Recoil 은 방향 그래프(directed graph, digraph) 를 따름</li>
<li>Recoil 은 상태를 사용하는 컴포넌트를 수정하지 않고 파생 데이터(derived data)를 대체할 수 있음<ul>
<li>기본적으로 아톰(atom)의 데이터가 변경되면 해당 atom 을 구독하는 모든 컴포넌트들은 갱신</li>
</ul>
</li>
<li>AtomEffect 를 사용해서 특정 상태의 갱신 이후의 사이드 이펙트를 자체적으로 정의 가능</li>
<li>상태 갱신 이후에 영향받는 컴포넌트에서 직접 useEffect를 사용할 필요가 없음</li>
</ul>
<h1 id="atom--selector">Atom / Selector</h1>
<h2 id="atom">Atom</h2>
<ul>
<li>recoil 의 상태 단위</li>
<li>store에 저장되고 갱신되는 데이터는 모두 Atom을 기반</li>
<li>아톰이 갱신될 때 그 상태를 구독(subscribe) 하고 있는 컴포넌트는 새로운 값으로 리렌더</li>
<li>아톰은 atom() 함수에 key 와 default 을 전달해서 작성</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/c96c0b92-a9ce-4f6b-a537-1df353e1b347/image.png" alt=""></p>
<ul>
<li>활용 사례 : 최초 로그인 시, accessToken을 atom에 저장하여, 다른 컴포넌트(사이드 바, 마이페이지 등)에서 사용할 수 있었다. </li>
</ul>
<h2 id="selector">Selector</h2>
<ul>
<li>Selector 는 상태를 기반으로 전달된 데이터를 가공할 때 사용</li>
<li>selector() 함수에 key 와 <strong>get</strong> 와 <strong>set</strong> 를 전달하여 작성</li>
</ul>
<pre><code>import { selector } from &#39;recoil&#39;;
...

const fontSizeLabelState = selector({
  key: &#39;fontSizeLabelState&#39;,
  get: ({get}) =&gt; {
    const fontSize = get(fontSizeState);
    const unit = &#39;px&#39;;

    return `${fontSize}${unit}`;
  },
});</code></pre><ul>
<li>get 프로퍼티 : 계산에 사용되는 함수</li>
<li>전달된 get 인수를 사용해서 아톰(Atom)이나 다른 셀렉터(Selector)에 접근</li>
<li>접근한 아톰이나 셀렉터가 업데이트 되면 다시 계산</li>
<li>fontSizeState 상태를 가져와 폰트 사이즈를 출력하는 순수 함수처럼 동작.</li>
<li>셀렉터는 쓸 수(write)없기 때문에 useRecoilState를 사용하지 않고 useRecoilValue를 사용</li>
</ul>
<pre><code>import { useRecoilState, useRecoilValue } from &#39;recoil&#39;;


function FontButton() {
  const [fontSize, setFontSize] = useRecoilState(fontSizeState);
  const fontSizeLabel = useRecoilValue(fontSizeLabelState);

  return (
    &lt;&gt;
      &lt;div&gt;Current font size: ${fontSizeLabel}&lt;/div&gt;

      &lt;button onClick={setFontSize(fontSize + 1)} style={{fontSize}}&gt;
        Click to Enlarge
      &lt;/button&gt;
    &lt;/&gt;
  );
}</code></pre><p><img src="https://velog.velcdn.com/images/dev_eunchae/post/f73b753d-e118-41b7-a857-b36a15eda4e5/image.png" alt=""></p>
<ul>
<li>활용 사례 : 유저의 accesstoken이 만료된 것을 파악하고, restore하며 새로운 accesstoken을 발급받을 때, 활용했었다. </li>
</ul>
<h1 id="비동기-데이터-쿼리">비동기 데이터 쿼리</h1>
<h2 id="redux-1">Redux</h2>
<ul>
<li>redux-thunk, redux-observable, redux-saga 등의 Middleware 사용</li>
<li>Middleware : action 을 dispatch 하고 reducer 에서 상태 업데이트를 하기 전 비동기 처리(예: 네트워크 요청, setTimeout)를 하는 중간자 역할</li>
<li>Redux Middleware를 위해 추가되는 boilerplate 코드가 많아짐 + 앱의 규모가 커질 수록 복잡도가 늘어나고 코드 양이 더욱 방대해짐</li>
</ul>
<h2 id="recoil-1">Recoil</h2>
<ul>
<li>동기 / 비동기 함수 모두 selector 에서 처리</li>
<li>render() 함수가 동기이기 때문에 promise 가 resolve 되기 전에 렌더링 할 수가 없음</li>
<li>이때 대기중인 데이터를 처리하기 위해 Recoil 은 React Suspense 와 함께 사용</li>
<li>컴포넌트를 Suspense 로 감싸서 대기중인 하위 항목들을 잡아내고 fallback UI 를 대신 렌더링</li>
</ul>
<pre><code>/ store.js
export const todoIdState = atom({
  key: &quot;todoIdState&quot;,
  default: 1
});

export const todoItemQuery = selector({
  key: &quot;todoItemQuery&quot;,
  get: async ({ get }) =&gt; {
    const id = get(todoIdState);

    const response = await axios.get(
        `https://jsonplaceholder.typicode.com/todos/${id}`
    );

    return response.data;
  }
});

// App.js
import { RecoilRoot } from &quot;recoil&quot;;
import { Suspense } from &quot;react&quot;;

import Container from &quot;./container&quot;;

export default function App() {
  return (
      &lt;RecoilRoot&gt;
        &lt;Suspense fallback={() =&gt; &lt;p&gt;Loading...&lt;/p&gt;}&gt;
          &lt;Container /&gt;
        &lt;/Suspense&gt;
      &lt;/RecoilRoot&gt;
  );
}

// container/index.js
import { todoItemQuery } from &quot;../store&quot;;
import { useRecoilValue } from &quot;recoil&quot;;

const Container = () =&gt; {
  const data = useRecoilValue(todoItemQuery);

  return &lt;div&gt;{data.title}&lt;/div&gt;;
};

export default Container;</code></pre><h1 id="파라미터에-따라-비동기-데이터-요청">파라미터에 따라 비동기 데이터 요청</h1>
<ul>
<li>파라미터를 기반으로 쿼리하고 싶을 땐 selectorFamily 를 사용</li>
</ul>
<pre><code>// store.js
import axios from &#39;axios&#39;;
import { selectorFamily } from &#39;recoil&#39;;

export const todoItemQuery = selectorFamily({
  key: &quot;todoItemQuery&quot;,
  get: (id) =&gt; async () =&gt; {
    const response = await axios.get(
        `https://jsonplaceholder.typicode.com/todos/${id}`
    );

    return response.data;
  }
});


// App.js
import { RecoilRoot } from &quot;recoil&quot;;
import { Suspense } from &quot;react&quot;;

import Container from &quot;./container&quot;;

export default function App() {
  return (
      &lt;RecoilRoot&gt;
        &lt;Suspense fallback={&lt;div&gt;Loading...&lt;/div&gt;}&gt;
          &lt;Container id={1} /&gt;
        &lt;/Suspense&gt;
      &lt;/RecoilRoot&gt;
  );
}


// container/index.js
import { todoItemQuery } from &quot;../store&quot;;
import { useRecoilValue } from &quot;recoil&quot;;

const Container = ({ id }) =&gt; {
  const data = useRecoilValue(todoItemQuery(id));

  return &lt;div&gt;{data.title}&lt;/div&gt;;
};

export default Container;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[백준 시작하기]]></title>
            <link>https://velog.io/@dev_eunchae/%EB%B0%B1%EC%A4%80-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@dev_eunchae/%EB%B0%B1%EC%A4%80-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 26 Sep 2022 18:08:37 GMT</pubDate>
            <description><![CDATA[<p>node.js로 알고리즘 문제 풀이를 해봐야겠다고 생각했다. </p>
<p>나는 보통 프로그래머스로 문제를 풀고 -&gt; github에 문제 풀이 과정을 업로드 해두었는데, 
백준이 node.js 라고 해서 이쪽으로 알고리즘 공부를 섞어서 해야겠다고 생각했다. </p>
<ol>
<li><p>node.js 설치</p>
<ul>
<li>이미 node.js는 설치 되어있음! </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/6e9c124c-9451-4eb1-8cf5-fb2fb8750700/image.png" alt=""></p>
</li>
</ol>
<ol start="2">
<li><p>vs code Code Runner 설치
<img src="https://velog.velcdn.com/images/dev_eunchae/post/c6be330c-a1e8-40e1-9977-903639fc4fac/image.png" alt=""></p>
</li>
<li><p>파일구조 만들기</p>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/0b5662da-d0f1-4e4f-b78f-ecbe569fbef0/image.png" alt=""></p>
<p>실행 JS : index.js
예시 담길 txt파일 : example.txt
백준문제 풀이 파일 저장 폴더 : Baekjoon/Q</p>
<ol start="4">
<li>문제 풀기</li>
</ol>
<p>1) 예제를 txt 파일에 저장한다.  ( 문제의 예제 복사, 붙여넣기 )</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/7eb55211-7395-4b07-9596-99ef2eb83530/image.png" alt=""></p>
<p>2) 실행 JS 파일 : index.js ( example.txt의 내용을 받아서 실행 )</p>
<pre><code>let fs = require(&#39;fs&#39;);
let input = fs.readFileSync(&#39;example.txt&#39;).toString().split(&#39; &#39;);
let a = parseInt(input[0]);
let b = parseInt(input[1]);
console.log(a+b);</code></pre><p>3) index.js를 실행해서 통과가 되면 백준에 업로드할 코드로 만들기</p>
<ul>
<li>readFileSync 안의 파일 이름 바꾸고 백준에 제출</li>
</ul>
<pre><code>let fs = require(&#39;fs&#39;);
let input = fs.readFileSync(&#39;/dev/stdin&#39;).toString().split(&#39; &#39;);
let a = parseInt(input[0]);
let b = parseInt(input[1]);
console.log(a+b);</code></pre><p>4) fs 모듈 이용하기 </p>
<p>1) 한 줄로 입력을 받을 때 </p>
<pre><code>let fs = require(&#39;fs&#39;);
let input = fs.readFileSync(&#39;/dev/stdin&#39;).toString().split(&#39; &#39;);</code></pre><p>2) 여러 줄로 입력을 받을 때 </p>
<pre><code>let fs = require(&#39;fs&#39;);
let input = fs.readFileSync(&#39;/dev/stdin&#39;).toString().split(&#39;\n&#39;);</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Inefficient Regular Expression Complexity in nth-check]]></title>
            <link>https://velog.io/@dev_eunchae/Inefficient-Regular-Expression-Complexity-in-nth-check</link>
            <guid>https://velog.io/@dev_eunchae/Inefficient-Regular-Expression-Complexity-in-nth-check</guid>
            <pubDate>Sat, 24 Sep 2022 21:18:10 GMT</pubDate>
            <description><![CDATA[<p>또 뭔데????ㅜㅡㅜ
스타워즈 관련 부분을 새 프로젝트에서 다시 만들고, 깃에 푸시하니 여기서도 보안 봇이 울린다. 지난 번과 같은 문제같아</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/cbe097af-dd1e-47e9-a059-4bf34b921ad1/image.png" alt=""></p>
<p>지난 번에 70개 보다는 적군...
오늘은 nth-check 이녀석이 문제인가 보다</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/64f510c7-3775-46ce-9ad5-693694bd011c/image.png" alt=""></p>
<p>음..버전은 똑같은데요?</p>
<p>그래서 그냥 에러 메세지를 들고 구글링을 하기로 했다</p>
<p><a href="https://github.com/facebook/create-react-app/issues/11174">누군간 있겠지 이 에러 해결한 사람</a></p>
<p>오 ... 깃허브 이슈까지 있는 문제인가보다. </p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/73a5d06b-2c39-4e54-92cf-f39eb36a69b1/image.png" alt=""></p>
<p>중요한 것은 이 부분인듯하다. 꽤 상세한 글이군요. 이 해결 방식은 문제를 무시하는 해결방식이 아니라고 한다. </p>
<p>아무튼 갑분 react-scripts 이사
nth-check 너는 어떤 넘이냐구,, 
우선 시키는대로 옮겨서 다시 npm install을 해봐야겠다. </p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/dd34b1da-6bea-4338-b793-891178916b8e/image.png" alt=""></p>
<p>좋아. 나도 devDependencies 로 옮길게. 그리고 깃에 푸시하면 되겠다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TS 4.0~ 4.5]]></title>
            <link>https://velog.io/@dev_eunchae/TS-4.0-4.5</link>
            <guid>https://velog.io/@dev_eunchae/TS-4.0-4.5</guid>
            <pubDate>Sat, 24 Sep 2022 18:26:04 GMT</pubDate>
            <description><![CDATA[<h1 id="classes">Classes</h1>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/d0e948c9-b91b-463d-84d4-71b98cb5ab12/image.png" alt=""></p>
<ul>
<li>Player 클래스를 만들 때, <ul>
<li>JS =&gt; constructor 안에 this 형식으로 만들어준다</li>
<li>TS =&gt; 파라미터를 작성하면, constructor 를 자동으로 만들어준다</li>
<li>TS =&gt; private 혹은 public property를 만들 수 있다 (자바스크립트로 컴파일 되지 않음)<ul>
<li>nickname 만 사용할 수 있게 만들어준다</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="추상클래스">추상클래스</h2>
<ul>
<li>다른 클래스가 상속받을 수만 있는 클래스</li>
<li>직접 새로운 인스턴스를 만들 수는 없음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/4f03db56-2e6c-41a9-bf32-359bba65adae/image.png" alt=""></p>
<ul>
<li>추상클래스 안의 메서드<ul>
<li>pivate, public 도 작동 가능 ( 자바스크립트에서는 무시되고 실행되니 문제가 됨 )
<img src="https://velog.velcdn.com/images/dev_eunchae/post/80d7cc3f-75ef-4ee1-9ae2-f108641b7580/image.png" alt=""></li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/6fa0d103-0861-449d-9f0a-795c2b518346/image.png" alt=""></p>
<h2 id="추상메소드">추상메소드</h2>
<ul>
<li>메소드 : 클래스 안에 존재하는 함수</li>
<li>메소드를 클래스 안에서 구현하지 않고 메소드의 call signature 만 적는 것</li>
<li>구현 부분 : <img src="https://velog.velcdn.com/images/dev_eunchae/post/7ad75d89-4bde-40ae-869c-ad1f6b095128/image.png" alt=""></li>
</ul>
<ul>
<li>해보기 <ul>
<li>User 추상 클래스가 getNickName 이라는 추상 메소드를 갖는다</li>
<li>이 메소드의 리턴값은 void </li>
<li>call signature 만 작성</li>
<li>이를 상속받은 Player 클래스에서는 getNickName을 구현해야 함</li>
<li>즉, 추상 메소드는 추상 클래스를 상속받는 모든 것들이 구현을 해야 하는 메소드</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/7fb2822a-7d4e-477e-924a-32c3cc34d06a/image.png" alt=""></p>
<h2 id="protected">Protected</h2>
<ul>
<li><p>private </p>
<ul>
<li>해당 클래스의 인스턴스, 메소드에서는 접근이 가능하지만 추상 클래스의 경우 인스턴스화 할 수 없음</li>
<li>필드가 외부로부터는 보호되지만, 다른 자식 클래스에서는 사용되기를 원한다면 사용 할 수 없음</li>
<li>아예 밖에서는 사용 할 수 없지만, 상속받은 클래스 안에서는 사용 할 수 있음
<img src="https://velog.velcdn.com/images/dev_eunchae/post/dca46017-6a1f-4db2-ba92-79180f81aa8f/image.png" alt=""></li>
</ul>
</li>
</ul>
<ul>
<li>public 프로퍼티를 보여주고는 싶지만, 수정을 할 수 없게 만드려면?<ul>
<li>readonly 사용하기</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ab43cee4-964a-4c28-8e2e-09ea9e9079b6/image.png" alt=""></p>
<h1 id="interface">Interface</h1>
<h2 id="type-vs-interface">type vs interface</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/d23ff17e-d83e-4e18-944d-10fb015ed420/image.png" alt=""></p>
<ul>
<li>type 의 경우 단일한 타입 / 배열 / 객체의 형태를 가질 수 있다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/89e550cc-8f85-494b-9540-b5d7a2ed3ea5/image.png" alt=""></p>
<ul>
<li>interface 의 경우 객체 형태만 가능하다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/290b6505-d594-45b3-93de-36afbc8b41da/image.png" alt=""></p>
<ul>
<li>typed의 상속, 연산자를 사용함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/8eae4217-27a7-4d8d-b580-dfc267b4a479/image.png" alt=""></p>
<ul>
<li>interface의 상속, 클래스와 비슷함</li>
<li>객체지향 프로그램의 개념을 활용해서 디자인되었기 때문에 비슷</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/c8b3ebb6-0aaf-46a4-81b2-5871a1ad1832/image.png" alt=""></p>
<ul>
<li>interface는 property 축적이 가능</li>
<li>같은 이름으로 3개의 인터페이스를 만들었지만, 타입스크립트가 하나로 합쳤다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/9f38fb98-dcc5-4156-accf-f693e3ec7111/image.png" alt=""></p>
<ul>
<li><p>type 에서는 불가능</p>
</li>
<li><p>interface 는 컴파일 시 js로 바뀌지 않고 사라진다.</p>
</li>
</ul>
<h2 id="추상클래스-인터페이스로-바꾸기">추상클래스 인터페이스로 바꾸기</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/d56c5df7-f603-4037-9629-0bf9d19ffa8a/image.png" alt=""></p>
<ul>
<li>implements 를 사용한다!</li>
<li>JS로 컴파일 시 User 인터페이스가 컴파일 되지 않아 매우 가벼워짐 ~</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/d2e9ee0b-9659-4c54-9883-43e50c6227c8/image.png" alt=""></p>
<ul>
<li>User 인터페이스를 상속받은 Player 클래스 </li>
<li>에러가 계속 발생 =&gt; 인터페이스를 상속할 때는 property를 private/protected 로 만들지 못함 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/cbb47570-5d31-4ea5-a61d-f0da5f64d2bb/image.png" alt=""></p>
<ul>
<li>public 으로만 사용할 수 있음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/4467dd78-fa4c-4702-a1b7-c68aad3cb7da/image.png" alt=""></p>
<ul>
<li>여러 인터페이스 동시에 사용하기 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/5d9247da-5574-4d0b-a8a4-f4a546ff85a0/image.png" alt=""></p>
<ul>
<li>함수에서 사용해보기</li>
<li>argument에 인터페이스를 사용하여, argument의 객체 모양을 지정하기</li>
<li>return 에도 인터페이스를 사용할 수 있음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/73136f89-4d79-41ec-a263-317f8061f509/image.png" alt=""></p>
<ul>
<li>new 형식이 아닌, interface 내의 내용을 그대로 작성해주면 됨!</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Your repository has dependencies with security vulnerabilities]]></title>
            <link>https://velog.io/@dev_eunchae/Your-repository-has-dependencies-with-security-vulnerabilities</link>
            <guid>https://velog.io/@dev_eunchae/Your-repository-has-dependencies-with-security-vulnerabilities</guid>
            <pubDate>Thu, 22 Sep 2022 17:21:32 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/e893f05e-ab57-4b6c-875f-64b045e18c3e/image.png" alt=""></p>
<p>github 에서 메일이 왔는데, 로그인했다는 메일인 줄 알고... 최근에는 깃허브 계정으로 회원 가입한게 없는데 ??? 하고 생각했었다. 그런데 레파지토리 이름과 함께 보안????</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/3ed322eb-2753-4f6d-9f51-bd284aebb00c/image.png" alt=""></p>
<p>보안이 취약하므로 package.json이나 yarn.lock의 패키지를 최신 버젼으로 업데이트 해주어야 안전하다는 이야기 같다!!!</p>
<p>git hub에서 문제라고 알려주었던 파일에 가서 npm audit</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/7a4a9bb5-a995-4944-9a69-754d07fa0c86/image.png" alt=""></p>
<p>그리고 나면 ... 결과가 나온다</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/8397b8b5-123f-4632-9953-c454888f878f/image.png" alt=""></p>
<p>npm audit fix 를 하라고 하니 해본다</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/3051f7f7-dfef-4536-a71b-5c61669569bb/image.png" alt=""></p>
<p>엄청나게 많은 것들이 바뀐 것 같은...?</p>
<p>혹시 안된것이 있을까봐 강제로도 한 번 해봤다 <strong>npm audit fix --force</strong></p>
<p>잘 되었나?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[바인딩 요소 'children'에 암시적으로 'any' 형식이 있습니다.]]></title>
            <link>https://velog.io/@dev_eunchae/%EB%B0%94%EC%9D%B8%EB%94%A9-%EC%9A%94%EC%86%8C-children%EC%97%90-%EC%95%94%EC%8B%9C%EC%A0%81%EC%9C%BC%EB%A1%9C-any-%ED%98%95%EC%8B%9D%EC%9D%B4-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4</link>
            <guid>https://velog.io/@dev_eunchae/%EB%B0%94%EC%9D%B8%EB%94%A9-%EC%9A%94%EC%86%8C-children%EC%97%90-%EC%95%94%EC%8B%9C%EC%A0%81%EC%9C%BC%EB%A1%9C-any-%ED%98%95%EC%8B%9D%EC%9D%B4-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4</guid>
            <pubDate>Thu, 22 Sep 2022 16:24:10 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/26f7990e-2216-442d-a6c3-daabe3e4c263/image.png" alt=""></p>
<ul>
<li>slider 컴포넌트를 만들던 중, 발생한 타입스크립트 에러</li>
<li>암시적인 형식이 아닌 명시적인 형식을 선언</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/f3c86cd9-bec1-4c4b-92e0-010a88c45755/image.png" alt=""></p>
<ul>
<li>Paramter에 들어가는 인자들에 대한 타입도 작성해서 걸어준다. </li>
<li>위치 { } : 타입 !!</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Query] Section 03 ]]></title>
            <link>https://velog.io/@dev_eunchae/Section-03</link>
            <guid>https://velog.io/@dev_eunchae/Section-03</guid>
            <pubDate>Wed, 21 Sep 2022 18:12:51 GMT</pubDate>
            <description><![CDATA[<h1 id="infinite-scroll">Infinite Scroll</h1>
<ul>
<li>사용자가 스크롤 할 때마다 새로운 데이터를 가져온다</li>
<li>모든 데이터를 한 번에 가져오는 것보다 효율적
ex. 트위터 </li>
<li>언제 새로운 데이터를 가져오는가? <ul>
<li>사용자가 버튼을 눌렀을 때</li>
<li>페이지의 특정 지점을 스크롤 했을 때</li>
</ul>
</li>
</ul>
<h2 id="useinfinitequery">useInfiniteQuery</h2>
<ul>
<li><p>페이지네이션과는 다른 api 사용</p>
</li>
<li><p>페이지네이션</p>
<ul>
<li>현재 페이지를 컴포넌트 상태에서 추적</li>
<li>사용자가 새 페이지를 열기 위해 버튼을 클릭했을 때, 업데이트 된 상태가 쿼리 키를 업데이트하고 쿼리 키가 데이터를 업데이트 하는 방식</li>
</ul>
</li>
<li><p>useInfiniteQuery</p>
<ul>
<li>다음 쿼리가 무엇인지 추적함</li>
<li>다음 쿼리가 데이터의 일부로 반환</li>
<li>사용할 api에서는 result 라는 데이터 배열을 가진 객체를 프로퍼티로 갖는다. </li>
<li>또한, api에서는 다음에 사용할 쿼리와 이전 쿼리, 총 페이지 수를 알려준다.</li>
</ul>
</li>
</ul>
<h3 id="usequery-vs-useinfinitequery">useQuery vs useInfiniteQuery</h3>
<ol>
<li>반환된 데이터의 형태가 다르다.</li>
</ol>
<ul>
<li>useQuery : 단순히 쿼리 함수에서 반환되는 데이터 형태</li>
<li>useInfiniteQuery : 두 개의 프로퍼티를 갖는다 
1) pages : 배열 형태
: 페이지에 있는 각 요소가 useQuery에서의 데이터와 같은 형태
2) pageParams
: 각 페이지의 매개변수 기록 (많이 사용되는 편은 아니다!)
: 모든 쿼리는 페이지 배열에 고유한 요소를 가지고 있고 그 요소는 해당 쿼리에 대한 데이터에 해당한다 =&gt; 페이지가 진행되며 쿼리도 변경됨
: pageParams는 검색된 쿼리의 키를 추적</li>
</ul>
<ol start="2">
<li>구문이 다르다.</li>
</ol>
<ul>
<li>pageParams :  쿼리 함수에 전달되는 매게 변수</li>
</ul>
<pre><code>useInfiniteQuert(&quot;sw-people(쿼리 키)&quot;, ({ pageParam = 
defalutUrl (첫번째로 정의한 Url을 기본값으로 사용) }) =&gt; fetchUrl(pageParma)</code></pre><ul>
<li><p>React-Query가 pageParam의 현재 값을 유지</p>
</li>
<li><p>컴포넌트 상태 값의 일부 XX</p>
</li>
<li><p>useInfiniteQuery에 옵션을 사용</p>
<ul>
<li><p>getNextPageParam : (lastPage, allPages) &gt;&gt; 다음페이지로</p>
<ul>
<li><p>마지막 페이지의 데이터, 모든 데이터에서 다음 페이지의 url 획득</p>
</li>
<li><p>pageParam을 업데이트 (next 프로퍼티 사용)</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/3b0e4fb6-c1ab-4409-99fb-adf5b81045c8/image.png" alt=""></p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<ol start="3">
<li>반환 객체의 특수한 프로퍼티</li>
</ol>
<ul>
<li>fetchNextPage : 사용자가 더 많은 데이터를 요청할 때 호출 
ex. 더 많은 데이터가 필요하여 버튼을 누를 때 / 스크린에서 데이터가 소진되는 지점을 누를 때</li>
<li>hasNextPage : getNextPageParam의 반환 값을 기반으로 하는 함수<ul>
<li>이 프로퍼티를 useInfiniteQuery에 전달하여 마지막 쿼리의 데이터를 어떻게 사용할 것인지 지정</li>
<li>undefined 인 경우 =&gt; 더 이상 데이터 없음</li>
<li>useInfiniteQuery에서 반환 객체와 함께 반환 된 경우 hasNextPage는 거짓</li>
</ul>
</li>
<li>isFetchingNextPage : 다음 페이지를 가져오는 지 ? 아니면 일반적인 페칭인지 구별 가능</li>
</ul>
<h1 id="flow">Flow</h1>
<ol>
<li>컴포넌트가 마운트 되다</li>
<li>이 시점에서 useInfiniteScroll이 반환된 객체의 <strong>data : undefined</strong> 
프로퍼티가 정의되어 있지 않다. (쿼리를 만들지 않았기 때문에) </li>
<li>useInfiniteScroll이 쿼리 함수를 사용하여 1페이지를 가져온다</li>
</ol>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/eafd8ea7-ee56-4d97-b2cd-7a2f03c1e526/image.png" alt=""></p>
<ol start="4">
<li>쿼리 함수는 useInfiniteScroll의 첫 번째 인수 
그리고 pageParam을 인수로 받음 
첫 pageParam은 우리가 기본 값으로 정의한 것이 지정</li>
</ol>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/50b3416d-8022-4e18-8d79-e288252e576a/image.png" alt=""></p>
<ol start="5">
<li><p>pageParam을 사용하여 첫 번째 페이지를 가져오고 반환 객체 데이터의 페이지 프로퍼티를 설정한다. 
=&gt; 인덱스가 0인 배열의 첫 번째 요소 설정 
=&gt; { .. } 쿼리 함수가 반환 하는 값</p>
</li>
<li><p>데이터가 반환된 후 react-query가 getNextPageParam (useInfiniteScroll의 옵션)을 실행
=&gt; lastPage, allPages를 사용해서 받아온 내용을 바탕으로, 
pageParam을 업데이트 =&gt; 다음페이지 링크가 업데이트 된다</p>
</li>
</ol>
<ol start="7">
<li><p>다음 페이지? 
hasNextPage 값을 정의하는 방식 =&gt; pageParam이 정의되어있는가 여부</p>
</li>
<li><p>다음페이가 있는 상태에서
1) 다음페이지 버튼 누르기 2) 스크롤 하기 등을 통해 fetchNextPage 함수를 호출 할 때, useQuery가 useInfiniteScroll을 실행한다</p>
</li>
<li><p>이를 사용해서 또 다음 요소를 업데이트하거나, 데이터의 프로퍼티인 페이지 배열에 다음 요소를 추가</p>
</li>
<li><p>새 데이터를 가지고 getNextPageParam 실행하여 NextPageParam을 설정</p>
</li>
<li><p>더이상 페이지가 없다면?
pageParam : undefined</p>
</li>
<li><p>hasNextPage 도 거짓이 된다 =&gt; 작업 완료, 더이상 데이터 없음</p>
</li>
</ol>
<h2 id="사용하기">사용하기</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/78799614-b488-4fda-8baa-7aed1871cc9b/image.png" alt=""></p>
<p>   <img src="https://velog.velcdn.com/images/dev_eunchae/post/be5929f4-72c7-424b-9597-d7f0d7433941/image.png" alt=""></p>
<h3 id="react-infinite-scroller">React-Infinite-Scroller</h3>
<ul>
<li><p>loadMore = {fetchNextPage}
: 데이터가 더 필요할 때 불러오는 함수</p>
</li>
<li><p>hasMore = {hasNextPage}
: hasNextPage는 useInfiniteQuery 에서 반환된 내용을 해체하여 사용</p>
</li>
<li><p>무한 스크롤 컴포넌트 부분</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/6963b8c6-84e8-4e8a-9867-876ad63d7048/image.png" alt=""></p>
<ul>
<li><p>pages 배열 -&gt; result 배열 로 넘어가기 </p>
</li>
<li><p>현재 사용하고 있는 api의 구조</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/d68098d3-9dd2-4882-ac78-6146f9eb9386/image.png" alt=""></p>
<ul>
<li>console.log 확인해보면?</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/bb885279-9398-4ab2-82f9-311262b81e30/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/e79a0644-e08a-48d4-8995-594866d17ba1/image.png" alt=""></p>
<ul>
<li>데이터가 정의되지 않는 오류가 발생함</li>
</ul>
<h3 id="페칭과-에러">페칭과 에러</h3>
<ul>
<li>useQuery 처럼 isLoading 사용하기 =&gt; 캐시된 데이터가 없을 때의 데이터 정의 </li>
<li>isError, error =&gt; 에러 발생 시 화면 정의</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/7d333eaa-a3db-49b1-8352-4e8bf3ad6991/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/67741c8b-6948-42d9-949b-b10909686bbe/image.gif" alt=""></p>
<ul>
<li>더이상 에러가 발생하지 않는다 ㅎㅎ</li>
<li>그런데 정해진 위치에 도달해서 새로 데이터를 가져 올 때 사용자에게 피드백을 주지 않는다 =&gt; 데이터 수집하는 피드백을 줘보자. </li>
</ul>
<h4 id="isloading-을-isfetching-으로-바꾼다면">isLoading 을 isFetching 으로 바꾼다면?</h4>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/a6ab21e7-d0bb-4ddb-98bb-4672cc486bb5/image.gif" alt=""></p>
<ul>
<li>최초 데이터 패칭은 잘 되지만, 새로운 페이지가 열릴 경우 스크롤이 위로 돌아간다 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/7f62e8e9-3def-4189-91b5-34b9c0d0db64/image.png" alt=""></p>
<ul>
<li>왜? 데이터는 더 있지만 새로운 페이지가 열릴 때마다 바로 조기 retrun 이 되어버리기 때문이다. </li>
</ul>
<h4 id="isloading과-isfetching-을-함께-사용하기">isLoading과 isFetching 을 함께 사용하기</h4>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/69ca9057-cae1-408c-b4e5-13fa64f8461c/image.png" alt=""></p>
<ul>
<li>loading 중 일 때, </li>
<li>isFetching 중 일때를 각각 지정해준다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/1f7d428c-8cd5-4149-8975-cccb6a005599/image.gif" alt=""></p>
<ul>
<li>스크롤도 끊기지 않고, 데이터를 새로 가져오는 것도 보인다. </li>
</ul>
<h2 id="양방향-스크롤-bi-directional-scrolling">양방향 스크롤 (Bi-directional Scrolling)</h2>
<ul>
<li>데이터의 중간부터 시작할 때 유용 (시작점 + 이전 데이터  + 이후 데이터)</li>
<li>next 메서드처럼 previous 메서드도 존재 </li>
<li>둘 다 수행하면 양방향 스크롤이 가능함</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TS 3.0 ~ 3.4]]></title>
            <link>https://velog.io/@dev_eunchae/TS-3.0-3.4</link>
            <guid>https://velog.io/@dev_eunchae/TS-3.0-3.4</guid>
            <pubDate>Wed, 21 Sep 2022 16:47:45 GMT</pubDate>
            <description><![CDATA[<h1 id="call-signatures">Call Signatures</h1>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/aad2b887-c44f-447b-a85b-4465bdb15922/image.png" alt=""></p>
<ul>
<li>함수 위에 마우스를 올렸을 때 확인할 수 있는 것</li>
<li>함수를 어떻게 호출해야 하는지 알려주는 역할</li>
<li>함수의 인자 타입과 반환 타입을 알려줌</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/382488d1-023d-409a-b493-6165e651fd70/image.png" alt=""></p>
<ul>
<li>직접 Add 타입을 만들어서, add 함수에 적용시키면</li>
<li>a,b의 타입을 직접 알려주지 않아도 타입스크립트는 추론이 가능하다</li>
</ul>
<h1 id="오버로딩-overloading">오버로딩 Overloading</h1>
<ul>
<li>패키지나 라이브러리에서는 오버 로딩을 많이 사용함</li>
<li>오버로딩은 함수가 서로 다른 여러개의 call signatures를 가지고 있을 때 발생</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/3d98ee0b-fd10-40d0-b9ec-451b3fc0a8a9/image.png" alt=""></p>
<ul>
<li>b의 타입이 string | number 으로 두 가지 형태의 call Signatures 를 가지고 있어서 오류가 발생</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/f082e5c1-5c8e-4f88-90a8-9d5abaad63ce/image.png" alt=""></p>
<ul>
<li>b의 타입을 구분해서 사용해야 함</li>
</ul>
<h2 id="사용-예시">사용 예시</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/16bea012-b073-4f94-9bc8-5a2a4e3c5325/image.png" alt=""></p>
<ul>
<li>push 함수 인자 config 는 string 혹은 Config(객체) 타입이 될 것</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/9606c712-6b1c-403b-a2e5-5a06a30eed12/image.png" alt=""></p>
<ul>
<li>typeof 를 통해 config의 타입이 string 일 경우 =&gt; console.log 의 config 역시 string</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/d856c5a8-e33d-4ecc-a112-f6b6009e10be/image.png" alt=""></p>
<ul>
<li>string이 아니라면 Config 타입이기 때문에, 객체 안의 key 에 접근할 수 있어진다</li>
</ul>
<h2 id="파라미터의-개수가-다를-때">파라미터의 개수가 다를 때</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/be5f4bb4-6970-46f3-bde1-9298636f8c0f/image.png" alt=""></p>
<ul>
<li>call Signatures 에 따라 c가 있을 때도 있고, 없을 때도 있다</li>
<li>c가 <strong>옵션으로</strong> 존재하여 에러 발생</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ad7de90c-11ac-4ba1-a2bf-d6e899a5d13e/image.png" alt=""></p>
<ul>
<li>c 의 타입이 number 일 것이라고 알려주어야 한다</li>
</ul>
<h1 id="다형성-polymorphism">다형성 Polymorphism</h1>
<ul>
<li>poly : many, several, much, multi</li>
<li>morphism : form(형태), structure(구조)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/953631e8-5499-4151-93e4-c1326249e92c/image.png" alt=""></p>
<ul>
<li>작동은 하지만, 다형성을 활용하지는 못했음</li>
<li>number[], boolean[], string[] 등의 concrete 타입을 사용하지 말고 Generics 타입을 사용해보자</li>
<li>concrete type : number, string, boolean, void, unknown 등 지금까지 배운 타입들 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/1e80a220-7fec-4f60-8909-49d31521a239/image.png" alt=""></p>
<ul>
<li>이렇게 여러 타입이 섞여있는 배열일 경우는?</li>
</ul>
<h1 id="제네릭-generics">제네릭 Generics</h1>
<ul>
<li><p>타입의 placeholder 같은 역할. 타입을 유추하게 만들어주는 역할</p>
</li>
<li><p>사용하는 이유는?</p>
<ul>
<li>call signaure을 작성할 때, 들어올 데이터의 타입을 확실하게 알지 못할 때 사용</li>
<li>concrete 타입도 알지 못할 때</li>
</ul>
</li>
<li><p>사용 방법</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/9f74d090-a4eb-4984-aeee-c8599a510c58/image.png" alt=""></p>
<ul>
<li>타입스크립트가 직접 타입을 유추한다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/49f0a8ff-6115-4518-b3bd-ab608b39d9a4/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/dc257dab-e014-4cf0-a354-877eee78e182/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ea9a91e1-0d9e-4276-84f8-dfaed2a7abb3/image.png" alt=""></p>
<ul>
<li>return 의 타입도 제네릭으로 표현하면</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/785a8856-386a-46e5-84f5-a78d09798261/image.png" alt=""></p>
<ul>
<li>a,b,c 의 타입이 자동으로 유추되고 있다</li>
</ul>
<h3 id="any와의-차이">any와의 차이?</h3>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/2ffd785c-7c18-4ba6-847e-4a0adb4942cd/image.png" alt=""></p>
<ul>
<li>any일 때</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/c583d8d4-c0d4-4e7a-b21b-27ced54718b7/image.png" alt=""></p>
<ul>
<li><p>generic일 때</p>
</li>
<li><p>에러를 미리 방지하지 못한다 </p>
</li>
</ul>
<h3 id="여러개의-제네릭-타입">여러개의 제네릭 타입</h3>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/63537bc2-0a6a-49fa-9067-79e235bb9994/image.png" alt=""></p>
<ul>
<li>새로운 제네릭 타입을 추가할 수 있다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/a8304c0e-fe6d-4d65-a881-45598ea01d7f/image.png" alt=""></p>
<ul>
<li>중첩해서 사용할 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] part.1 리액트 기초 - (5)]]></title>
            <link>https://velog.io/@dev_eunchae/React-part.1-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B8%B0%EC%B4%88-5</link>
            <guid>https://velog.io/@dev_eunchae/React-part.1-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B8%B0%EC%B4%88-5</guid>
            <pubDate>Tue, 20 Sep 2022 19:06:33 GMT</pubDate>
            <description><![CDATA[<h1 id="25-key와-리렌더링">25 Key와 리렌더링</h1>
<h2 id="key">key</h2>
<ul>
<li>Value를 특정하는 이름</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/7bbfe47e-b73a-4843-9006-6eaf67ed5956/image.png" alt=""></p>
<ul>
<li>배열에 map을 사용할 경우 key를 지정해주어야 한다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/4b312fbc-c257-4c9f-81a9-6df7881f5ba6/image.png" alt=""></p>
<ul>
<li><p>키가 중요한 이유는? map에서 컴포넌트 재사용을 위해서</p>
</li>
<li><p>키를 통해서 기존 트리와 이후 트리의 자식들이 일치한지 확인</p>
</li>
<li><p>key 값으로 줄 수 있는 것 : id, index(배열의)</p>
</li>
<li><p>index의 경우 항목들이 재배열되지 않는다면 동작이 가능하나, 그 배열의 순서가 재배열 되는 경우 비효율적으로 동작 할 수 있으니 유의할 것</p>
</li>
<li><p>제대로 key 값을 주려면 중복이 없고, 바뀌지 않는 값으로 주자 </p>
</li>
</ul>
<h1 id="26-상태-끌어올리기">26 상태 끌어올리기</h1>
<ul>
<li>자식 컴포넌트에 있던 함수, 변수 등을 부모 컴포넌트에서 관리를 할 수 있게 lifiting up</li>
<li>자식(형제) 컴포넌트로 내려준다</li>
<li>props drilling : 과도한 liftingdms drilling을 야기할 수 있다
=&gt; 너무 많은 컴포넌트 들이 props를 알게 되고, 이를 변경시킬 수 있는 위험 요소가 존재할 수 있음!!
=&gt; context api 등과 같은 상태관리 라이브러리를 이용해 해결할 수 있음</li>
</ul>
<h1 id="data-fetch">Data Fetch</h1>
<h2 id="fetch-api"><a href="https://developer.mozilla.org/ko/docs/Web/API/Fetch_API">fetch api</a></h2>
<ul>
<li>네트워크 통신</li>
</ul>
<pre><code>import React from &quot;react&quot;;
import &quot;./styles.css&quot;;

export default function App() {
  const [data, setData] = React.useState(null);
  const [errorMessage, setErrorMessage] = React.useState(null);

  React.useEffect(() =&gt; {
    fetch(
      &quot;https://raw.githubusercontent.com/techoi/raw-data-api/main/simple-api.json&quot;
    )
      .then(function (response) {
        return response.json();
      })
      .then(function (myJson) {
        setData(myJson.data);
      })
      .catch((error) =&gt; setErrorMessage(error));
  }, []);

  if (errorMessage != null) {
    return &lt;p&gt;error&lt;/p&gt;;
  }

  if (data == null) {
    return &lt;p&gt;loading&lt;/p&gt;;
  }

  return (
    &lt;div&gt;
      {data.people.map((el, index) =&gt; (
        &lt;div key={index}&gt;
          &lt;div&gt; {el.name}&lt;/div&gt;
          &lt;div&gt; {el.age}&lt;/div&gt;
        &lt;/div&gt;
      ))}
    &lt;/div&gt;
  );
}</code></pre><ol>
<li><p>fetch를 이용해서 데이터를 불러온다 </p>
</li>
<li><p>then =&gt; 성공 했을 때 상황</p>
</li>
<li><p>error =&gt; 에러가 났을 때 상황 </p>
</li>
<li><p>loading =&gt; 데이터가 오기 전, 에러가 발생하지 않은 상황</p>
<p>= &gt; 각 상태에서의 화면을 보여주자!!!!</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[TS 2.0 ~ 2.4]]></title>
            <link>https://velog.io/@dev_eunchae/TS-2.0-2.4</link>
            <guid>https://velog.io/@dev_eunchae/TS-2.0-2.4</guid>
            <pubDate>Mon, 19 Sep 2022 09:55:22 GMT</pubDate>
            <description><![CDATA[<h1 id="타입을-사용하는-이유">타입을 사용하는 이유</h1>
<h2 id="타입-안정성">타입 안정성</h2>
<ul>
<li>개발자 경험을 누릴 수 있다.</li>
<li>코드에 버그가 줄어든다</li>
<li>런타임 에러가 줄어든다</li>
<li>생산성이 증가된다</li>
</ul>
<h2 id="자바스크립트의-유연성">자바스크립트의 유연성</h2>
<ul>
<li>배열과 boolean 의 계산에서..(유효하지 않아야하는데...)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/cbdea617-fe01-44a1-b6d5-d2079c0bcd17/image.png" alt=""></p>
<ul>
<li><p>문제점 1 : 배열이 사라지고, string 타입으로 변했다</p>
</li>
<li><p>문제점 2 : boolean이 사라지고 string 타입으로 변했다</p>
</li>
<li><p>함수를 만들어서 실행해보면..</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/53bc7910-447c-4284-9a49-20de4413ea57/image.png" alt=""></p>
<ul>
<li>숫자만 들어와야하는데, string이 들어와 있을 때 이 함수를 실행시키면 안된다.</li>
<li>하지만 자바스크립트는 잘못된 타입이 들어와도 실행을 막지 못한다</li>
<li>입력값이 2개가 들어와야 하는 함수지만, 1개가 들어와도 실행이 된다.</li>
<li>에러 혹은 에러 메세지를 발생 시키거나, 예외처리를 하지 않고 NaN을 반환한다</li>
<li>자바스크립트가 a, b가 필수값인지 선택값인지 알지 못하고 있음</li>
</ul>
<p>=&gt; 다른 언어에서는 이와 같은 문제가 발생하지 않는다.</p>
<ul>
<li>런타임 에러 : 콘솔 안에서 발생하는 에러. 유저의 컴퓨터에서 코드가 실행될 때만 일어나는 에러</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/a0d5555a-4f56-4af1-97b5-1336f55f94d4/image.png" alt=""></p>
<ul>
<li>은채 변수에 객체를 설정 후, hello() 함수를 실행해 보았을 때 에러 발생 
=&gt; 에러가 날 줄 모르고 자바스크립트는 실행한 후 에러를 보여줌 (유저의 컴퓨터에서 코드가 실행되면 나타나는 에러)
=&gt; 코드가 실행 되기 전에 언어 자체적으로 eunchae 객체에는 hello()라는 함수가 없다는 것을 보여주어야 함</li>
</ul>
<h1 id="타입스크립트-작동-방식">타입스크립트 작동 방식</h1>
<ul>
<li>컴파일 : 작성한 타입스크립트를 -&gt; 자바스크립트로 변환</li>
<li>타입스크립트가 먼저 코드를 확인하여 변환 후 오류가 나지 않게 확인</li>
<li>타입스크립트가 성공적으로 컴파일 되어 자바스크립트 코드로 변환</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/27868565-53f8-4a62-913a-07f4f4072129/image.png" alt=""></p>
<ul>
<li>자바스크립트에서는 hello() 함수에서 에러를 발견하지 못한다</li>
<li>타입스크립트에서는 hello() 함수가 존재하지 않는다는 에러를 발생시킨다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ffdf3f70-e6b2-4a77-84b7-82b20cee41de/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/e29c9ce0-5924-46ed-be65-0cf3f2e3bec1/image.png" alt=""></p>
<ul>
<li>타입스크립트에서는 a,b 가 무엇인지 알려주지 않으면 에러 발생한다</li>
<li>2개의 인자가 필요한 데 1개만 작성했을 때 에러를 발생시켜준다</li>
</ul>
<h1 id="암시적-유형-vs-명시적-유형">암시적 유형 vs 명시적 유형</h1>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/8043ecfe-a28c-424f-a320-56263b0ba8dc/image.png" alt=""></p>
<ul>
<li>타입스크립트는 타입을 추론한다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/fd9ef6b5-7741-4431-8b50-74bd73195b79/image.png" alt=""></p>
<ul>
<li>a의 타입을 변경할 수 없다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/0780a086-459c-40a7-80ee-0701028d3057/image.png" alt=""></p>
<ul>
<li>b의 타입을 지정하는 것 =&gt; 타입체커와의 소통!</li>
<li>boolean이 아닌 string을 지정하여 오류 발생</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/76f7a367-8a97-4c7a-9bff-acd95db8b4b4/image.png" alt=""></p>
<ul>
<li><p>숫자로 이루어진 배열
<img src="https://velog.velcdn.com/images/dev_eunchae/post/776dfe16-0d5c-43b6-af29-45ec62a0851b/image.png" alt=""></p>
</li>
<li><p>문자열을 push 하려 할 경우 에러가 발생</p>
</li>
<li><p>다른 타입끼리는 섞지 않는다 </p>
</li>
<li><p>만약 c가 빈 배열인데, 숫자만 들어가게 될 배열이라면? number[]</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/1e727e33-6276-4bb4-8c52-7b8bcd847c45/image.png" alt=""></p>
<ul>
<li>타입스크립트가 추론하기 어려울 경우에는, 명시적으로도 적어주자</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/8104fc81-9630-46e2-9a87-0d19ec6a452a/image.png" alt=""></p>
<ul>
<li>객체 안 name은 string 이기 때문에 불가능함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/3b85e394-bb6f-457b-a4e2-8375dc3f5e1f/image.png" alt=""></p>
<ul>
<li>타입을 명시적으로 적어주지 않았을 때 , any 가 등장한다</li>
</ul>
<h1 id="ts-유형">TS 유형</h1>
<h2 id="선택적-변수-">선택적 변수 &#39;?&#39;</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/df29b1d1-dfdf-4ee9-94c1-afe55ecf7223/image.png" alt=""></p>
<ul>
<li>player 객체에 age가 있지만, age를 사용하지 않을 때는 오류가 발생한다.</li>
<li>age가 있기도하고, 없기도 할 경우에는 &#39; ? &#39;을 사용한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/f282a93f-ae6c-4d32-a9f8-6b97ec01d0f9/image.png" alt=""></p>
<h2 id="타입-별칭-type-aliases">타입 별칭 (Type Aliases)</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/0405ab57-bff1-4b78-a5bc-73e6912b5ec3/image.png" alt=""></p>
<ul>
<li>같은 타입을 여러번 반복해서 사용하는 것은 비효율적이다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/819fc183-9604-468b-8a20-376f2db30378/image.png" alt=""></p>
<ul>
<li>상단에 Type을 적어두고 , 사용한다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/45b5a650-6354-4695-89c4-d9b86c11ec69/image.png" alt=""></p>
<ul>
<li>중첩 가능</li>
</ul>
<h2 id="인자와-retrun의-type">인자와 retrun의 Type</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/2443b369-1fc7-417c-8cf9-7f0522af81fb/image.png" alt=""></p>
<ul>
<li>함수에서 (인수 : 타입)</li>
<li>해당 함수에서 반환하는 객체에는 age가 없기 때문에 오류 발생</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/b848fcf2-8cf8-4bd5-83af-7b66f3ffbd19/image.png" alt=""></p>
<ul>
<li><p>() 뒤에서 return 의 타입을 지정해주면, age를 사용할 수 있게 된다. </p>
</li>
<li><p>화살표 함수에서 사용하기
<img src="https://velog.velcdn.com/images/dev_eunchae/post/ae0b8269-ef11-4dcc-958f-3720b515f0eb/image.png" alt=""></p>
</li>
</ul>
<h2 id="readonly">readonly</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/9587d753-e0b1-441f-bdc0-e8786ed01624/image.png" alt=""></p>
<ul>
<li>name을 변경하려고 할 경우 에러 발생</li>
<li>eunchae의 타입은 Player 라는 것을 알고 있는 타입스크립트는, readonly 속성이 붙은 name의 변경을 허용하지 않는다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ee1db9f2-9231-48f8-8184-037c13c2f5b5/image.png" alt=""></p>
<ul>
<li>자바스크립트에서는 에러가 발생하지 않지만, 타입스크립트에서는 readonly가 붙은 배열에 변형을 가할 때 에러를 발생시킨다. </li>
</ul>
<h2 id="tuple">Tuple</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/111146b5-20ba-45d3-bcf2-a1d4cda13711/image.png" alt=""></p>
<ul>
<li>player에는 최소 3개의 데이터가 배열에 들어가도록 지정해두었는데, 현재 빈 배열 상태라는 에러</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ed81c128-9e4d-4bc1-ad22-d69ab0115c50/image.png" alt=""></p>
<ul>
<li>항상 정해진 갯수의 요소를 가진 배열을 만들 때 사용</li>
<li>미리 배열에 들어갈 요소들의 타입을 지정해두는 것</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/b653ef0a-17e3-43a7-bd4e-c3caa9cec82f/image.png" alt=""></p>
<ul>
<li>readonly와 함께 사용할 경우 배열의 인덱스로 접근하여 변경 불가능</li>
</ul>
<h2 id="undefined">undefined</h2>
<ul>
<li>JS와 TS에서 볼 수 있는 undefined 타입</li>
<li>주로 선택적 변수를 사용할 때 확인할 수 있다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/354ae028-613f-4088-a549-6cc92fc9529c/image.png" alt=""></p>
<h2 id="any">any</h2>
<ul>
<li>비어있는 값을 쓰면 나타나는 any</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/dfd8cae3-9921-43a4-ae27-6839fdc98e25/image.png" alt=""></p>
<ul>
<li>타입스크립트의 보호장치들로부터 빠져나오는 any </li>
<li>모든 보호 장치들을 비활성화시키는 any</li>
<li>any를 사용하지 않는 최소화 해야한다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/69702627-fdff-4035-ad7d-17523496ed89/image.png" alt=""></p>
<ul>
<li>any를 사용할 경우 타입스크립트에서도 이 코드가 실행되어버린다.</li>
</ul>
<h2 id="unknown">unknown</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/03397189-1734-4a5a-aeda-338c82033562/image.png" alt=""></p>
<ul>
<li>a를 unknown 타입으로 설정할 경우, number 데이터와의 계산이 실행되지 않는다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/424bc245-4934-4588-8261-e91f2e0fdcd0/image.png" alt="">
<img src="https://velog.velcdn.com/images/dev_eunchae/post/751f9225-2031-41e5-8ab1-a5745fe9273c/image.png" alt="">
<img src="https://velog.velcdn.com/images/dev_eunchae/post/0cb3be4a-b1d4-4fde-afd9-0b14f1844224/image.png" alt=""></p>
<ul>
<li><p>a가 unkonown 이지만, number/string 일 때를 확인하는 과정을 거치고 나면 a의 타입이 number/string 으로 정해져 오류가 실행되지 않는다. </p>
</li>
<li><p>변수의 타입을 미리 알지 못할 때 unknown을 사용한다</p>
</li>
<li><p>typescript가 강제로 타입 체크 과정을 거친다</p>
</li>
</ul>
<h2 id="void">void</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/a42e2854-752a-4148-bda4-dc58010d5967/image.png" alt=""></p>
<ul>
<li>void는 아무것도 retrun 하지 않는 함수를 대상으로 사용한다</li>
<li>void를 따로 지정할 필요 없이 자동으로 인식</li>
<li>void는 비어있는 것을 의미</li>
</ul>
<h2 id="never">never</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/c0f5b6e2-4df5-44c2-a11a-b419b94bcb72/image.png" alt=""></p>
<ul>
<li>함수가 절대 return 하지 않을 때 발생</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/02db6564-90ba-4b8a-b19a-baf02d23370b/image.png" alt=""></p>
<ul>
<li><p>return 이 있는 경우 에러가 발생한다.</p>
</li>
<li><p>타입이 두 가지 일 수도 있는 상황에 발생가능</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/cd3f0d26-2ce1-48aa-9255-598184e45a87/image.png" alt=""></p>
<ul>
<li>첫 번째 name은 string</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/e43aef5e-2b15-4a8a-8921-43799ea3de20/image.png" alt=""></p>
<ul>
<li>두 번째 name은 number</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/69e1ab9e-2d72-4772-8cef-82f0f763515d/image.png" alt=""></p>
<ul>
<li>세 번째 name은 never</li>
<li>절대 실행되지 않아야 할 코드, 올바른 타입의 데이터가 들어왔다면 실행될 수 없다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] part.1 리액트 기초 - (4)]]></title>
            <link>https://velog.io/@dev_eunchae/React-part.1-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B8%B0%EC%B4%88-4</link>
            <guid>https://velog.io/@dev_eunchae/React-part.1-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B8%B0%EC%B4%88-4</guid>
            <pubDate>Fri, 16 Sep 2022 17:14:42 GMT</pubDate>
            <description><![CDATA[<h1 id="19-리액트-element-스타일링">19 리액트 element 스타일링</h1>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/101fd896-ae71-44ce-a706-268db34fade2/image.png" alt=""></p>
<ul>
<li>리액트는 html에서 사용하는 class 대신 className 을 </li>
<li>style : 객체, 카멜케이스, className보다 먼저 적용됨</li>
</ul>
<h1 id="20-ref로-dom-다루기">20 Ref로 Dom 다루기</h1>
<h2 id="dom-조작하기"><a href="https://developer.mozilla.org/ko/docs/Web/API/Document">Dom</a> 조작하기</h2>
<ul>
<li>input Element 가 있고 화면이 뜨자마자 focus를 주고 싶다면?</li>
</ul>
<blockquote>
<p>JS =&gt;  ?.focus()</p>
</blockquote>
<ul>
<li>DOM 트리는 body와 여러 다른 요소를 포함. Document는 페이지의 URL을 얻거나 문서에 새로운 요소를 생성하는 등의 기능을 전역적으로 제공</li>
</ul>
<pre><code>const inputRef = React.useRef()
const divRef = React.useRef()

React.useEffect(()=&gt;{
    input.current.focus()

    setTimeout(()=&gt;{
        divRef.current.style.backgroundColor = &quot;pink&quot;
   }, 3000)
},[])

retrun (
&lt;&gt;
    &lt;input ref={inputRef} /&gt;
    &lt;div
        ref = {divRef}
        style ={{height : 100 , width: 100, backgroundColor : &quot;red&quot;}}&gt;
    &lt;/div&gt;
&lt;/&gt;
)</code></pre><ul>
<li>1) 화면이 뜨자마자 input 에 focus 주기</li>
<li>2) 3초 뒤 배경 색 바꾸기 </li>
</ul>
<h2 id="왜-useref">왜 useRef?</h2>
<ul>
<li>내 생각 ? 가상돔을 사용하여 최적의 렌더링을 하고 있는데 진짜 Dom을 조작해버리면 안될 것 같아</li>
</ul>
<h1 id="21-22-form">21-22 Form</h1>
<h2 id="기본-구조">기본 구조</h2>
<ul>
<li>label</li>
<li>input</li>
<li>select (option)</li>
<li>submit</li>
</ul>
<h3 id="consoledir"><a href="https://developer.mozilla.org/en-US/docs/Web/API/console/dir">console.dir()</a></h3>
<ul>
<li>콘솔에서 지정된 JavaScript 객체의 모든 속성을 볼 수 있는 방법</li>
</ul>
<h3 id="react에서만-사용하는-속성">react에서만 사용하는 속성</h3>
<ul>
<li>label의 htmlFor : input과 연결 시킬 때 ( JS에서는 for )</li>
<li>input의 defaultValue : 변하지 않는 경우일 때 </li>
</ul>
<h2 id="validattion">validattion</h2>
<ul>
<li><p><a href="String.prototype.startsWith()"> startsWith()</a>
: 어떤 문자열이 특정 문자로 시작하는지 확인하여 결과를 true 혹은 false로 반환</p>
</li>
<li><p>disabled ={true} 혹은, true 대신 상세 조건 설정하기 </p>
</li>
<li><p>onSubmit 혹은 onChange 할 때도 검증 가능 =&gt; state와 event.target.value 등을 적절히 사용해보자</p>
</li>
</ul>
<h1 id="23-error">23 Error</h1>
<h2 id="catch-error">Catch Error</h2>
<pre><code>try {
...
} catch (error) {
...
}</code></pre><ul>
<li>ErrorBoundary : 감싸고 있는 컴포넌트에서 에러가 발생할 경우, 특정 화면을 보여줄 수 있게하는 컴포넌트</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/79ac5a42-4516-4d79-b301-94946a69fe2b/image.png" alt=""></p>
<ul>
<li>class 컴포넌트로 작성해야 함</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/19f72388-42a9-4196-8080-4389c1130859/image.png" alt=""></p>
<ul>
<li>fallback 을 사용할 수도 있다. 에러가 발생했을 때 보여줄 수 있는 컴포넌트를 만들어 활용할 수 있음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/3d0cd0f1-8ff6-49e9-a922-c130530ba3a0/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[react-router-dom] Failed prop type: The prop `history` is marked as required in `Router`, but its value is `undefined`.]]></title>
            <link>https://velog.io/@dev_eunchae/react-router-dom-Failed-prop-type-The-prop-history-is-marked-as-required-in-Router-but-its-value-is-undefined</link>
            <guid>https://velog.io/@dev_eunchae/react-router-dom-Failed-prop-type-The-prop-history-is-marked-as-required-in-Router-but-its-value-is-undefined</guid>
            <pubDate>Fri, 16 Sep 2022 15:17:24 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/8b458c4c-cf27-413c-9bcc-d725339c4539/image.png" alt=""></p>
<p>react-router-dom을 5 버전으로 설치하고 처음 사용하려고 하자마자 발생한 오류이다.
next.js 없이 react 로만 초기 셋팅을 하는게 이렇게 어려울 줄이야
react router 셋팅하고, /project 로 왔는데 시작부터 이렇게 에러를 !</p>
<pre><code>import &#39;./App.css&#39;;
import { Router, Switch, Route } from &#39;react-router-dom&#39;;
import ProjectPage from &#39;./components/project&#39;;

function App() {
  return (
    &lt;Router&gt;
      &lt;Switch&gt;
        &lt;Route exact path={&#39;/project&#39;} component={ProjectPage}&gt;&lt;/Route&gt;
      &lt;/Switch&gt;
    &lt;/Router&gt;
  );
}

export default App;</code></pre><p>코드에서는 history, location을 사용한 적도 없는데!??</p>
<pre><code>import { BrowserRouter as Router, Route, Switch } from &quot;react-router-dom&quot;;</code></pre><p><a href="https://stackoverflow.com/questions/42892488/react-router-v4-0-0-uncaught-typeerror-cannot-read-property-location-of-unde">Router를 살짝 바꿔주었다.</a> 이렇게 처음부터 어이없게 헤매다니..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] DocumentFragment]]></title>
            <link>https://velog.io/@dev_eunchae/JS-DocumentFragment</link>
            <guid>https://velog.io/@dev_eunchae/JS-DocumentFragment</guid>
            <pubDate>Fri, 16 Sep 2022 08:38:40 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p>자바스크립트로 DOM을 만들고 추가하는 방법</p>
<ul>
<li><p>document.createElement() 생성 -&gt; appendChild() -&gt; DOM 등록</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ad653e54-4370-4028-bc32-13be15445718/image.png" alt=""></p>
<pre><code>&lt;script&gt;
 for (let i = 0; i &lt; 10; i++) {
   let divEl = document.createElement(&#39;div&#39;);
   divEl.innerText = &#39;hello~ this is &#39; + i;
   document.body.appendChild(divEl);
 }
&lt;/script&gt;

</code></pre></li>
</ul>
</li>
</ul>
<h1 id="documentfragment">DocumentFragment</h1>
<ul>
<li>DocumentFragment 노드를 사용하면 오직 메모리 상에만 존재하는 경량화된 DOM을 만들 수 있다</li>
</ul>
<pre><code>    &lt;script&gt;
      const docFrag = document.createDocumentFragment();
      // const docFrag = document.createElement(&#39;div&#39;);

      for (let i = 0; i &lt; 10; i++) {
        let divEl = document.createElement(&#39;div&#39;);
        divEl.innerText = &#39;hello~ this is &#39; + i;
        docFrag.appendChild(divEl);
      }

      document.body.appendChild(docFrag);
    &lt;/script&gt;</code></pre><ul>
<li>DocumentFragment 를 만든 후, </li>
<li>body에 바로 appendChild 하는 것이 아닌, 이 DocumentFragment 노드에 appendChild 한 후,</li>
<li>body에는 DocumentFragment 노드를 붙이는 것!</li>
<li>결과는 똑같다!</li>
</ul>
<h2 id="왜-해">왜 해???</h2>
<ul>
<li><p>DocumentFragment 만들고 하는 것과 , div를 하나 만들어서 하는 것과 무엇이 다른가?</p>
</li>
<li><p>div 태그로 만들었다면
<img src="https://velog.velcdn.com/images/dev_eunchae/post/dbc34750-56c2-486c-8707-d94db430900d/image.png" alt=""></p>
</li>
<li><p>자식 요소들을 만들기 위해 어쩔수 없이 같이 생겨난 부모 div</p>
</li>
<li><p>DocumentFragment로 만들었다면
<img src="https://velog.velcdn.com/images/dev_eunchae/post/0f96e35f-8a7f-4e24-99e7-b2d0278fe44f/image.png" alt=""></p>
</li>
<li><p>부모 요소 없이, 만들고자 했던 부분들만 생겨났다. </p>
</li>
</ul>
<h3 id="documentfragment-의-특징">DocumentFragment 의 특징</h3>
<ul>
<li><p>DocumentFragment를 DOM 노드에 추가한다고 해도 DocumentFragment 노드는 등록되지 않는다
그 자식 노드들만 추가 된다</p>
</li>
<li><p>DocumentFragment DOM에 추가하면 DocumentFragment 노드의 자식 요소들은 더이상 메모리 상에 존재하지 않는다 </p>
<ul>
<li><p>확인하기 : body에 붙이기 전, 후를 비교해보자 
<img src="https://velog.velcdn.com/images/dev_eunchae/post/7a61ac64-6ee8-4eac-8985-55234f3d70a4/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/87eaad40-217d-4f8d-93e6-aea710a40e21/image.png" alt=""></p>
</li>
<li><p>자동으로 자식 요소들이 삭제 되어 메모리 상에 존재하지 않는다!</p>
</li>
<li><p>div 였다면?
<img src="https://velog.velcdn.com/images/dev_eunchae/post/6fd95d1b-8682-4cb5-a5fd-d2852841919a/image.png" alt=""></p>
</li>
<li><p>자식 요소들이 그대로 남아 메모리 상에 존재한다. </p>
</li>
</ul>
</li>
</ul>
<ul>
<li>여러개의 각기 다른 부모 요소에 요소를 집어 넣을 때 효율적</li>
</ul>
<p>   <img src="https://velog.velcdn.com/images/dev_eunchae/post/6cac3a26-23b3-47d8-89d1-e12f7b1513c7/image.png" alt=""></p>
<ul>
<li><p>1번</p>
<ul>
<li>for문을 이용해서 100개의 div 요소를 만든다</li>
<li>만들어진 요소를 부모 요소(container) 에 각각 집어넣는다</li>
<li>부모요소의 갯수만큼 실행하는데 -&gt; 각 부모 요소에 appenChild를 이용해서 elements의 요소들을 하나씩 순서대로 집어넣는다&#39;</li>
<li>j번째 요소를 집어넣을 때 배열은 <strong>참조타입</strong>이기 때문에 값 자체가 복사되지 않는다</li>
<li>cloneNode() 안했을 때 : 마지막 div에만 요소가 들어감</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/5f01d3ac-6c39-4b88-a88f-6612ecbcd229/image.png" alt=""></p>
<ul>
<li><strong>cloneNode()</strong> 메서드를 활용하여 요소 자체를 복사하자</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ea4cafcb-cafd-4d56-b391-7c89d72d7e1c/image.png" alt=""></p>
<ul>
<li><p>각 div 마다  100개의 요소가 생긴다. </p>
</li>
<li><p>2번 document.createDocumentFragment() 사용해보기</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/80f2aa68-b69b-489e-b055-ea511a3e7333/image.png" alt=""></p>
<ul>
<li>el 요소들을 바로 frag에 등록한다 (빈 배열 필요 없음)</li>
<li>부모 요소에 바로 frag를 등록한다 (이중 for문 필요 없음)</li>
<li>farg도 참조타입이기 때문에 clone해서 값 자체를 붙여주자</li>
</ul>
</li>
</ul>
<h3 id="clonenode">cloneNode</h3>
<ul>
<li><p>DocumentFragment를 DOM에 추가할 때, DocumentFragment의 자식 노드는 더 이상 생성한 메모리 상의 위치에 존재하지 않기 때문에 유지하고 싶다면 사용할 것</p>
</li>
<li><p>cloneNode를 하지 않으면 appendChild 이후 최종적으로 아무것도 남지 않지만</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/8d19ba82-3704-4194-9683-d71b6b03ab95/image.png" alt=""></p>
<ul>
<li>cloneNode를 하면 100개의 요소를 마지막에도 확인할 수 있다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/46d7729e-c57a-4a35-b5ef-8918247db27c/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 이벤트 흐름 / 이벤트 위임]]></title>
            <link>https://velog.io/@dev_eunchae/JS-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%ED%9D%90%EB%A6%84</link>
            <guid>https://velog.io/@dev_eunchae/JS-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%ED%9D%90%EB%A6%84</guid>
            <pubDate>Fri, 16 Sep 2022 05:42:03 GMT</pubDate>
            <description><![CDATA[<h1 id="이벤트-흐름">이벤트 흐름</h1>
<h2 id="브라우저가-사용자의-입력을-받았을-때">브라우저가 사용자의 입력을 받았을 때</h2>
<h3 id="브라우저-화면에서-이벤트-발생">브라우저 화면에서 이벤트 발생</h3>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/7aeba02a-a0bd-41c4-be95-304e7064d1cc/image.png" alt=""></p>
<ul>
<li>이벤트 : 마우스 클릭, 휠 움직임, 마우스 포인터 이동, 화면 터치 등 모든 종류의 사용자 제스처</li>
</ul>
<h3 id="이벤트-대상-찾기">이벤트 대상 찾기</h3>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/4b27f42d-3342-4fff-af0f-2adc26646aa3/image.png" alt=""></p>
<ul>
<li>이벤트가 발생한 좌표에 무엇이 있는지 확인 </li>
<li>렌더링 과정 중의 &#39;<strong>페인트 기록</strong>&#39;을 찾는다. </li>
</ul>
<h3 id="캡처링-단계">캡처링 단계</h3>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/5f89cddc-9b49-4652-b83b-e70d2360d5e8/image.png" alt=""></p>
<ul>
<li>페인트 기록을 통해 좌표를 알아냈다면</li>
<li>해당 좌표에 위치한 요소의 이벤트 리스너를 실행</li>
<li>이 과정이 캡쳐링 단계 (capturing phasese)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/dc4fafeb-59a2-40c1-afe6-21660aeefd61/image.png" alt=""></p>
<ul>
<li>이 때 타켓 요소의 가장 최상위 window 객체로부터 캡처링 단계의 이벤트 리스너가 등록이 되어있는 지 확인</li>
<li>있다면 실행</li>
<li>계속 자식 요소로 전파되며 만나는 캡쳐링 이벤트 리스너 실행</li>
<li>타켓 요소까지 이동</li>
</ul>
<h3 id="버블링-단계">버블링 단계</h3>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/da7c1c61-fe50-4c0d-9196-573009d6cda3/image.png" alt=""></p>
<ul>
<li>캡쳐링이 끝나고, 최초에 이벤트가 발생했던 요소에 버블링 이벤트 리스너가 있다면 실행</li>
<li>다음 직계 부모 요소에 버블링 이벤트 리스너가 있다면 실행</li>
<li>가장 최상위 window 객체까지 계속 전파</li>
</ul>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;이벤트 캡쳐링, 버블링&lt;/title&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;button type=&quot;button&quot;&gt;click&lt;/button&gt;

    &lt;script&gt;
      window.addEventListener(
        &quot;click&quot;,
        function () {
          console.log(1);
        },
        useCapture
      );

      document.addEventListener(
        &quot;click&quot;,
        function () {
          console.log(2);
        },
        true
      );

      document.documentElement.addEventListener(
        &quot;click&quot;,
        function () {
          console.log(3);
        },
        true
      );

      document.body.addEventListener(
        &quot;click&quot;,
        function () {
          console.log(4);
        },
        true
      );

      document.querySelector(&quot;button&quot;).addEventListener(
        &quot;click&quot;,
        function () {
          console.log(5);
        },
        true
      );

      document.querySelector(&quot;button&quot;).addEventListener(
        &quot;click&quot;,
        function () {
          console.log(6);
        },
        false
      );

      document.body.addEventListener(
        &quot;click&quot;,
        function () {
          console.log(7);
        },
        false
      );

      document.documentElement.addEventListener(
        &quot;click&quot;,
        function () {
          console.log(8);
        },
        false
      );

      document.addEventListener(
        &quot;click&quot;,
        function () {
          console.log(9);
        },
        false
      );

      window.addEventListener(
        &quot;click&quot;,
        function () {
          console.log(10);
        },
        false
      );
    &lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre><h4 id="캡쳐링-단계">캡쳐링 단계</h4>
<ol>
<li>윈도우 객체</li>
<li>document</li>
<li>document의 documentElement(html요소)</li>
<li>body</li>
<li>button ( 타깃요소 )</li>
</ol>
<h4 id="버블링-단계-1">버블링 단계</h4>
<ol start="6">
<li>button ( 타깃요소 )</li>
<li>body</li>
<li>document의 documentElement(html요소)</li>
<li>document</li>
<li>윈도우 객체</li>
</ol>
<ul>
<li><p>addEventListner (&quot;이벤트 타입&quot;, 이벤트 발생 시 실행할 함수, useCapture =&gt; 캡쳐링 단계에서 해당 리스너를 실행 여부 T/F) </p>
</li>
<li><p>버튼 클릭 했을 때 :  캡쳐링 -&gt; 버블링 실행
<img src="https://velog.velcdn.com/images/dev_eunchae/post/1386fac7-ea62-4b28-8c4d-83fca3ebd653/image.png" alt=""></p>
</li>
<li><p>버튼 바깥을 클릭했을 때 : 5, 6번 실행되지 않음
<img src="https://velog.velcdn.com/images/dev_eunchae/post/f3de48ee-bcaa-4e76-8b3d-2dfc237ef0c9/image.png" alt=""></p>
</li>
</ul>
<h1 id="이벤트-위임">이벤트 위임</h1>
<ul>
<li><p>이벤트 리스너가 div 요소에 있고 사용자가 부모 요소 div의 자식인  button 태그를 클릭했다면?</p>
<ul>
<li>브라우저는 이벤트가 발생한 button 태그를 찾는다</li>
<li>이벤트 캡쳐링, 버블링을 통해 button 태그의 부모 요소인 div의 이벤트 리스너를 실행한다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ce0ad5e4-4e3d-4ebb-979a-784da60e0101/image.png" alt=""></p>
</li>
</ul>
<h3 id="event-객체--돔에서-일어나는-이벤트의-정보-포함">event 객체 = 돔에서 일어나는 이벤트의 정보 포함</h3>
<ul>
<li>event.currentTarget은 이벤트가 등록된 요소 </li>
<li>이벤트 리스너 안의 this 가 참조하는 대상과 같음</li>
<li>이벤트가 최초에 발생한 요소는 event.target에 참조</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/f55c63c8-f7ee-412c-9a06-a120c551a099/image.png" alt=""></p>
<p>확인해보기</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/d9b7bca0-f74c-4ddf-8f54-a07c88a44628/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/71eb274c-f987-4f65-83c1-9e69879b65e1/image.png" alt=""></p>
<ul>
<li>버튼을 누르면?<ul>
<li>this =  event.currentTarget</li>
<li>event.target = 이벤트가 최초에 발생한 button </li>
</ul>
</li>
</ul>
<p>또 확인해보기</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/acf12f6b-59fa-44b8-a2bd-a8a05a009142/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/569b82fb-f48c-46f9-9010-a289bf36c4bc/image.png" alt=""></p>
<ul>
<li><p>버튼을 눌렀을 때, 아이템을 만들건데 이벤트는 더 상단의 div에 있을 때.</p>
<ul>
<li>이벤트 리스너는 div를 클릭 할 때로 만들었음</li>
<li>event.target의 태그 이름이 button 이면, li태그를 만들어서 ul안에 배치 
<img src="https://velog.velcdn.com/images/dev_eunchae/post/d4e8a27e-78cc-4b14-894d-2fb3a558e143/image.png" alt=""></li>
</ul>
</li>
<li><p>버튼을 누르면 새로운 li들이 생겨난다.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/7b0649d0-2744-4a2e-a455-1a5c48a60c18/image.png" alt=""></p>
<ul>
<li><p>li들을 눌렀을 때 console.log 찍히게 이벤트 발생시키기도 추가
<img src="https://velog.velcdn.com/images/dev_eunchae/post/92e3ccd2-5d71-4296-a715-d0627a271558/image.png" alt=""></p>
</li>
<li><p>기존에 있던 아이템, 새로 생긴 hello~들을 누르면 hit 이 콘솔에 나온다.</p>
</li>
<li><p>버튼, li, 새로 생긴 자식 요소 들에도 모두 이벤트가 등록되었다.</p>
</li>
</ul>
<h2 id="이벤트-위임-1">이벤트 위임</h2>
<ul>
<li>이벤트를 발생시키고 싶은 요소를 이벤트 리스너가 설치된 부모 요소의 자식으로 배치한다면<ul>
<li>그 요소가 몇 개든 상관없이 이벤트 등록 가능</li>
<li>요소가 동적으로 생성되어 계속 추가되어도 같은 기능 유지</li>
</ul>
</li>
<li>이벤트 위임 : 이벤트 흐름을 활용하여 단일의 이벤트 리스너가 여러개의 이벤트 대상을 처리할 수 있게 되는 방법</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[리페인트 & 리플로우]]></title>
            <link>https://velog.io/@dev_eunchae/%EB%A6%AC%ED%8E%98%EC%9D%B8%ED%8A%B8-%EB%A6%AC%ED%94%8C%EB%A1%9C%EC%9A%B0</link>
            <guid>https://velog.io/@dev_eunchae/%EB%A6%AC%ED%8E%98%EC%9D%B8%ED%8A%B8-%EB%A6%AC%ED%94%8C%EB%A1%9C%EC%9A%B0</guid>
            <pubDate>Fri, 16 Sep 2022 05:32:47 GMT</pubDate>
            <description><![CDATA[<h1 id="reflow">Reflow</h1>
<ul>
<li>생성된 DOM 노드의 레이아웃 변경 시 영향을 받는 모든 노드 (부모, 자식)의 수치를 다시 계산하여 레이아웃 트리(렌더 트리)를 재생성하는 작업</li>
</ul>
<h3 id="발생-속성">발생 속성</h3>
<ul>
<li>width, height, padding, margin, float, position 등</li>
<li><strong>레이아웃에 영향</strong>을 주는 모든 속성은 리플로우를 발생시킨다.</li>
</ul>
<h1 id="repaint">Repaint</h1>
<ul>
<li>Reflow 과정이 끝나고 재생성된 레이아웃 트리(렌더 트리)를 다시 레이어에 그리는 작업</li>
</ul>
<h3 id="발생-속성-1">발생 속성</h3>
<ul>
<li>color, border-radius, background, box-shadow 등</li>
<li>시각적으로 보여지는 모든 속성</li>
</ul>
<blockquote>
<p>리플로우와 리페인트는 렌더링 과정에서 레이아웃 단계와 페인트 단계를 다시 거치는 과정</p>
</blockquote>
<h2 id="렌더링-속도에-영향을-미치는-이유">렌더링 속도에 영향을 미치는 이유</h2>
<ul>
<li>렌더링 과정은 순차적으로 진행되기 때문</li>
<li>각 렌더링 과정들은 반드시 전 단계의 데이터가 필요</li>
<li>전 단계에서 변화가 일어났다면? -&gt; 다음 단계에도 모두 영향을 미침</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/a9150e12-6796-4305-b2c7-f7d6a2ac0d7e/image.gif" alt=""></p>
<ul>
<li>스타일 -&gt; 레이아웃 -&gt; 페인트 </li>
<li>스타일에 변화가 생기면 -&gt; 레이아웃, 페인트 까지 모두 영향을 받는다</li>
<li>레이아웃만 변화가 생기면? -&gt; 페인트가 영향을 받는다</li>
</ul>
<h3 id="애니메이션-생각해보기">애니메이션 생각해보기</h3>
<ul>
<li>왼쪽에서 오른쪽으로 이동하는 애니메이션을 만들었을 때<ul>
<li>60fps로 움직이게 했다면</li>
<li>요소의 레이아웃이 변경되기 때문에 렌더링 엔진은 60장의 프레임에 0.1초 간격으로 리플로우, 리페인트 과정을 수행 </li>
<li>이 과정 중에 0.1초 안으로 리플로우,리페인트를 끝내지 못한다면 애니메이션이 버벅거리는 것을 보게 된다. </li>
<li>reflow, repaint 해야할 요소가 많으면 많아질 수록 자연스럽지 못한 애니메이션을 그리게 된다</li>
<li>브라우저 전체적인 성능에 영향</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/b34ec582-a951-49d3-9c6f-e4bd1e52d612/image.png" alt=""></p>
<h1 id="해결방법">해결방법</h1>
<h2 id="css-troansform-속성">CSS Troansform 속성</h2>
<ul>
<li>transform을 사용하여 만드는 애니메이션은 cpu 대신 gpu를 사용하여 화면 렌더링 처리</li>
<li>CPU는 해야 할 일이 아주 많기 때문에... (OS 구동, 브라우저 구동 등)</li>
<li>GPU는 여러개의 코어가 간단한 작업을 동시에 협업하는데 특화 -&gt; 애니메이션을 빠르게 처리</li>
<li>CPU 코어가 4-8개 vs GPU 코어가 5nnn개 (기기마다 차이 있음)</li>
</ul>
<h2 id="requestanimationframe">requestAnimationFrame()</h2>
<ul>
<li>자바스크립트를 통해 일어나는 애니메이션 정보를 브라우저에 매 프레임마다 미리 알려줌</li>
<li>자바스크립트 애니메이션이 프레임의 시작 시 실행되도록 보장</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/4be6dbb9-04d7-4a97-b9d7-49e1a38260b3/image.png" alt=""></p>
<ul>
<li>방향키를 움직였을 때, 그 방향으로 쭉~~ 움직이도록 =&gt; 부드러운 애니메이션 실행</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹페이지 렌더링]]></title>
            <link>https://velog.io/@dev_eunchae/%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80-%EB%A0%8C%EB%8D%94%EB%A7%81</link>
            <guid>https://velog.io/@dev_eunchae/%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80-%EB%A0%8C%EB%8D%94%EB%A7%81</guid>
            <pubDate>Fri, 16 Sep 2022 04:50:28 GMT</pubDate>
            <description><![CDATA[<h3 id="공부자료-키워드">공부자료 키워드</h3>
<ul>
<li>모던 웹 브라우저 들여다보기</li>
<li>렌더링 트리 생성, 레이아웃 및 페인트</li>
<li>How Browsers Work : Behind the scenes of modern web browsers</li>
</ul>
<h1 id="웹브라우저의-기본적인-구조">웹브라우저의 기본적인 구조</h1>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/cd437247-c274-4c82-b3f2-8ad49370d290/image.png" alt=""></p>
<ul>
<li>사용자 인터페이스 : 웹 페이지에서 보이는 부분 외 부분 (주소창, 뒤로가기/앞으로가기, 새로고침버튼, 즐겨찾기 등)</li>
<li>브라우저 엔진 : 사용자 인터페이스와 렌더링 엔진을 중개</li>
<li><strong>렌더링 엔진</strong> : htm 코드를 사용자에게 렌더링해주는 부분, <ul>
<li>이미지,css,js등을 통신을 통해 다운받는다</li>
<li>작성했던 자바스크립트 코드를 해석한다</li>
<li>브라우저마자 selectbox, button 등이 다른데 os에 의존하는 UI형태</li>
</ul>
</li>
<li>자료저장소 : 쿠키와 같이 지속적으로 저장되어야 하는 것들이 저장되는 공간</li>
</ul>
<h1 id="렌더링-엔진">렌더링 엔진</h1>
<h2 id="파싱">파싱</h2>
<ul>
<li><strong>HTML을 파싱</strong>하여 DOM으로 변환</li>
<li>작성했던 코드를 <strong>트리구조로 변환</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ea9e6404-ee91-4f21-b577-d9f950d7d492/image.png" alt=""></p>
<ul>
<li>오타, 잘못된 문법 =&gt; 예외처리</li>
<li>link, img 태그 =&gt; 리소스 다운로드</li>
<li>script 태그 =&gt; DOM 파싱 중단, 자바스크립트 해석</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/24c1b4db-0b1e-438f-a200-5f42214dd4ac/image.png" alt=""></p>
<ul>
<li>document.write를 통해서 h2 태그가 생성됨 =&gt; DOM 구조의 변화가 생기기 때문에 파싱 중단</li>
</ul>
<h2 id="스타일-계산">스타일 계산</h2>
<ul>
<li>CSS를 파싱하여 CSSOM으로 변환</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/b8216c09-2277-4037-bbb2-716e120216bd/image.png" alt=""></p>
<ul>
<li><strong>CSSOM</strong>(CSS Object Model ~ 트리형태)정보를 통해 DOM 노드에 대한 <strong>스타일 결정</strong></li>
<li>결정된 스타일은 크롬 개발자 도구의 computed 항목에서 확인 가능</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/94ca39a6-0677-4461-88e8-980a13aaa709/image.png" alt=""></p>
<h2 id="레이아웃-트리-생성">레이아웃 트리 생성</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/c7a93086-d45e-4bce-bb4a-67a1a5641027/image.png" alt=""></p>
<ul>
<li>돔과 계산된 스타일을 따라가며 <strong>요소의 크기, 좌표</strong>와 같은 정보를 담은 레이아웃 트리(렌더트리)를 생성</li>
<li>화면에 표현되는 정보만 트리에 담기게 된다<ul>
<li>display : none =&gt; 돔에는 있었지만 레이아웃 트리에는 보이지 않음</li>
<li>가상요소는 화면에 보일 수 있기 때문에 돔에는 없었지만 레이아웃 트리에는 보일 수 있음</li>
<li>visibilty : hidden =&gt; 돔에도 있고, 레이아웃 구조는 유지해야하기 때문에 있음!</li>
</ul>
</li>
</ul>
<h2 id="페인트-기록">페인트 기록</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/8cdc46a1-a014-494b-a0d8-f5820b808f6d/image.png" alt=""></p>
<ul>
<li>레이아웃 트리(렌더트리)가 생성되면 이 트리를 따라 페인트 기록 생성</li>
<li>페인트 기록에는 요소를 렌더링하는 순서가 저장</li>
<li>지금까지의 정보를 바탕으로 한 페이지를 여러개의 레이어로 나눈 뒤 그 위에 텍스트, 색, 이미지, 보더, 그림자 등의 모든 <strong>시각적 부분을 그리는 작업</strong>이 진행</li>
</ul>
<h2 id="컴포지팅">컴포지팅</h2>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/584a3914-307a-4b30-b927-43d3f73a0a61/image.png" alt=""></p>
<ul>
<li>각각의 <strong>레이어를 스크린에 픽셀</strong>로 표현 (레스터링)</li>
<li>나누었던 <strong>레이어들을 합성</strong>해 페이지 그리기 (컴포지팅)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] part.1 리액트 기초 - (3)]]></title>
            <link>https://velog.io/@dev_eunchae/React-part.1-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B8%B0%EC%B4%88-3</link>
            <guid>https://velog.io/@dev_eunchae/React-part.1-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B8%B0%EC%B4%88-3</guid>
            <pubDate>Thu, 15 Sep 2022 18:00:52 GMT</pubDate>
            <description><![CDATA[<h1 id="13-컴포넌트-상태-다루기">13 컴포넌트 상태 다루기</h1>
<h2 id="컴포넌트">컴포넌트</h2>
<ul>
<li><p>DOM : 논리 트리</p>
</li>
<li><p>컴포넌트 :** 엘리먼트의 집합**</p>
</li>
<li><p>엘리먼트 : 요소</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/6095d35f-7d1d-4c82-909b-0dcea0f1c184/image.png" alt=""></p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/29bb354b-5cbf-468b-bca6-2234603c9cc8/image.png" alt=""></p>
<ul>
<li>useState가 바로 상태값을 관리해주는 react의 훅이다.</li>
<li>useState() 안에 들어있는 값이 초기 값</li>
<li>이 안에는 문자도, 배열도, 불린 값도 넣을 수 있다</li>
<li>const [우리가 관리해야 할 state 상태 , 업데이트 하는 함수] </li>
</ul>
<h1 id="14-컴포넌트-사이드-이펙트-다루기">14 컴포넌트 사이드 이펙트 다루기</h1>
<ul>
<li>use~~로 시작하는 것들이 react의 훅이다.</li>
</ul>
<h2 id="사이드-이펙트">사이드 이펙트?</h2>
<ul>
<li>부작용</li>
<li>의도하지 않은 효과 vs 부수 효과(변경, 효과가 일어날 때 그 효과를 다른 곳에도 전파하기 위함)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/c5af57da-2452-4743-a207-8ef444a45d48/image.png" alt=""></p>
<ul>
<li>input에 쓴 내용을 남겨놓고 싶다면? =&gt; 로컬스토리지, 세션스토리지, 쿠키 등의 브라우저 저장 공간을 활용하자</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/678366e6-faea-4ce4-b8ed-de45f59fdc2e/image.png" alt=""></p>
<ul>
<li><p>onChange에  들어갈 함수에 localStorage 에 저장하는 함수를 써준다. setItem()
<img src="https://velog.velcdn.com/images/dev_eunchae/post/51cc2b9b-bdc5-453a-a4d7-4f08249887e5/image.png" alt=""></p>
</li>
<li><p>다시 접속했을 때도 남아있게 하고 싶다면, keyword state의 초기값을 로컬스토리지에서 받아오고, input의 값으로 해볼까?
<img src="https://velog.velcdn.com/images/dev_eunchae/post/13057dae-4c1c-43cb-9c27-9a1461a5db41/image.png" alt="">
<img src="https://velog.velcdn.com/images/dev_eunchae/post/feb157df-a907-4ab3-967e-77e89d0d711a/image.png" alt=""></p>
</li>
</ul>
<h3 id="문제점-1">문제점 1</h3>
<ul>
<li>하지만, 로컬스토리지에서 값을 읽어오면서 데이터가 크거나, 길면 딜레이가 생겨 문제가 생길 수도 있다. 
그럴 때, useState에는 함수로 값을 넣어줄 수 있다. 초기값을 리턴하는 함수를 사용해서 처음 값을 읽어오는 시간이 길더라도, 함수가 실행되면 값을 받아올 수 있게하자.  =&gt; <strong>lazy initialize</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/3958a0ba-1383-4ddf-a349-9a8af0059690/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/5ccb40a0-6de1-4b1b-b717-5ab61dd93bb8/image.png" alt=""></p>
<ul>
<li>render 보다 늦게 initialize가 찍힌다.</li>
</ul>
<h3 id="문제점-2">문제점 2</h3>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/6e85e555-e31e-49a3-95fe-fd55b6e5b5ff/image.png" alt=""></p>
<ul>
<li>어떤 동작을 하던지 계속해서 render 중</li>
<li>keyword가 바뀌었을 때만, 발생하는 사이드 이펙트로 로컬스토리지에 keyword가 저장되게 하자 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/a3713646-ec50-42bf-8c61-91ee56146355/image.png" alt=""></p>
<ul>
<li>useEffect 에서 두 번째 인자(dependency array)로 빈 배열을 두면 최초 렌더 시, 한 번만 실행</li>
<li>keyword가 바뀔 때마다 실행 되게 하려면, keyword state를 넣어준다.</li>
<li>의존성 배열을 작성하지 않으면, 모든 변화에 반응하게 된다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/0072ccca-5a2b-4b05-afc9-62d81cdaae89/image.png" alt=""></p>
<h1 id="15-커스텀-훅-만들기">15 커스텀 훅 만들기</h1>
<ul>
<li><p>keyword, typing, result가 바뀔 때 마다 로컬스토리지에 저장하고 싶다고하면 -&gt; useEffect를 3번??? (비효율)</p>
</li>
<li><p>반복되는 부분은 =&gt; 함수화</p>
</li>
<li><p>useState/useEffect가 반복되는 부분은 =&gt; use 커스텀 훅</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/4147a802-643a-4164-ab81-ead05d2d93a3/image.png" alt=""></p>
<ul>
<li>state 값을 로컬스토리지에 저장하는 커스텀 훅을 만들어보자</li>
<li>처음 만들었던 state와 로컬스토리지에서 값을 받아오는 초기값셋팅</li>
<li>훅을 실행하면, useEffect도 state가 변할 때 실행하여 로컬스토리지에 저장하게 한다 </li>
<li>이 훅은 결과적으로 [state, setState] 를 반환하게 된다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/fe482321-491b-4f01-9249-9bd913dd8dd2/image.png" alt=""></p>
<ul>
<li>우리가 사용할 state와 useState 대신 커스텀 훅을 쓰고, 인수로 state 이름을 보내준다</li>
<li>typing의 경우 타입이 boolean 이었기 때문에, 두 번째 인수로 보내주고 다른 것들은 기본값이 &quot;&quot; 일 수 있게 한다</li>
</ul>
<p>application 확인</p>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/b19e3fb7-37df-4546-81aa-771b6846b217/image.png" alt=""></p>
<ul>
<li>아무것도 안 썼을 때 </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ae6d802b-62af-4c31-8690-b7891b80e39a/image.png" alt=""></p>
<ul>
<li>작성 중일 때</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/77d5c059-12e9-46db-bc23-58c2e62e714a/image.png" alt=""></p>
<ul>
<li>click 했을 때 </li>
</ul>
<h1 id="16-hook-flow-이해하기">16 hook flow 이해하기</h1>
<h2 id="hook-flow">hook flow</h2>
<ul>
<li>훅의 호출 타이밍</li>
<li>useState에 setState 시 prev(이전 동작)을 주입할 수 있음</li>
</ul>
<pre><code> const rootElement = document.getElementById(&quot;root&quot;);

      const App = () =&gt; {
        console.log(&quot;App render start&quot;);
        const [show, setShow] = React.useState(() =&gt; {
          console.log(&quot;App useState&quot;);
          return false;
        });

        React.useEffect(() =&gt; {
          console.log(&quot;의존성 배열 없음&quot;);
        });

        React.useEffect(() =&gt; {
          console.log(&quot;의존성 빈배열&quot;);
        }, []);

        React.useEffect(() =&gt; {
          console.log(&quot;의존성 배열에 show&quot;);
        }, [show]);

        const handelClick = () =&gt; {
          setShow((prev) =&gt; !prev);
        };

      console.log(&quot;App render end&quot;); // 여기!!

        return (
          &lt;&gt;
            &lt;button onClick={handelClick}&gt;search&lt;/button&gt;
            {show ? (
              &lt;&gt;
                &lt;input /&gt;
                &lt;p&gt;&lt;/p&gt;
              &lt;/&gt;
            ) : null}
          &lt;/&gt;
        );
      };

      console.log(&quot;App render end&quot;); // 여기 아님!! 틀렸음
      ReactDOM.render(&lt;App /&gt;, rootElement);</code></pre><p><img src="https://velog.velcdn.com/images/dev_eunchae/post/ecb52dca-f256-4c84-a20f-efe713ec49b0/image.png" alt=""></p>
<ul>
<li><p>최초 렌더링
_ - ⚠️ 가장 바깥의 end ?? ====&gt; 나는 왜 end가 먼저 render 되는거지???_</p>
<p>=&gt; 콘솔 위치를 ㅋㅋㅋ DOM이 그려지기 전에 했으니까! 
retrun 이전에 console.log를 해주자</p>
</li>
</ul>
<p>  <img src="https://velog.velcdn.com/images/dev_eunchae/post/918eaa8f-a269-4343-8cad-4eaeeb09352d/image.png" alt=""></p>
<ul>
<li>상단부터 순서대로 render -&gt; useState -&gt; end -&gt; 이후에 useEffect</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/16b8ab64-dc14-4d28-9d5b-898b5b880db1/image.png" alt=""></p>
<ul>
<li>search 버튼 클릭했을 때
1) 렌더
2) 항상 실행되는 의존성 배열없는 useEffect / show가 변했을 때 실행되는 useEffect</li>
</ul>
<h1 id="17-hookflow-이해하기">17 hookflow 이해하기</h1>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/e6507f4d-39e7-47cb-9ec9-d4d6f25313c1/image.png" alt="">
<img src="https://velog.velcdn.com/images/dev_eunchae/post/ecbdbefa-c8f1-491f-ae35-4a348637b9a3/image.png" alt=""></p>
<ul>
<li>Child 를 만들고, 기존 input/p 위치에 Child 컴포넌트를 넣어준다.  </li>
<li>최초 렌더링 시 console 순서는 처음과 같다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/c20d7f96-3449-491b-b946-83a568621462/image.png" alt=""></p>
<ul>
<li>show가 true 되었을 때는 app render/end -&gt; Child render / end -&gt; useEffect 확인</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/88ff2e61-a0a9-432d-bd52-45d2821b782c/image.png" alt=""></p>
<ul>
<li>Child 안에서도 useState를 만들어서 사용해보자.</li>
<li>input의 value가 바뀔 때마다 state도 바뀔 것</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/91107cbe-4373-4de6-ae23-6da5f5d72bed/image.png" alt=""></p>
<ul>
<li><p>show = true</p>
</li>
<li><p>Child가 나타나면서, App -&gt; Child render/useState/end -&gt; App에 있는 useEffect 실행
<img src="https://velog.velcdn.com/images/dev_eunchae/post/c9a4b0a7-5410-420e-8824-1f68de04d3c7/image.png" alt=""></p>
</li>
<li><p>text가 바뀔 때는 Child 내부의 render가 반복된다. App은 바뀌지 않음.</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/c85324fd-c392-41f1-b6e7-1e0ca76127a9/image.png" alt=""></p>
<ul>
<li>Child 안의 useEffect도 확인해보자</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/5e40d856-139e-4539-afde-4080c2122495/image.png" alt=""></p>
<ul>
<li>부모 (App) -&gt; 자식 (Child) -&gt; 자식의 useEffect -&gt; 부모의 useEffect (최초 렌더링이 아니어서 빈배열은 작동하지 않음)</li>
</ul>
<h3 id="clean-up">clean up</h3>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/37cb4788-4d65-4a2a-9fa2-ed9501df531b/image.png" alt="">
<img src="https://velog.velcdn.com/images/dev_eunchae/post/2aecb2b5-b67f-421b-9d3d-4fb6edd8485e/image.png" alt=""></p>
<ul>
<li>App, Child 에 있는 useEffect 들에 모두 return 을 해주어 clean up을 해보자</li>
<li>return을 하면서 다른 함수를 호출하면, 다시 동작할 때 이전의 사이드 이펙트를 지우고 다시 생성하는 것? </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/53f570ef-8e8c-466b-a10e-1f412ca0717e/image.png" alt=""></p>
<ul>
<li>App에 있던 useEffect 들이 cleanup하는 것이 Child보다 먼저 실행되었따. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/9efa58d8-053a-4401-9e1e-a97f97a94736/image.png" alt=""></p>
<ul>
<li>input 작성하면</li>
<li>render -&gt; cleanup -&gt; useEffect</li>
</ul>
<p><img src="https://velog.velcdn.com/images/dev_eunchae/post/d1d1851b-aeeb-497c-9497-0acf3f17260e/image.png" alt=""></p>
<ul>
<li>show = false</li>
<li>Child 컴포넌트가 아예 제거 되는 상황인데,  cleanup 함수가 모두 실행되었다.</li>
<li>[] useEffect도 clean up 은 실행되었다는 점</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>