<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>getelementby_.log</title>
        <link>https://velog.io/</link>
        <description>개발이 싫어.</description>
        <lastBuildDate>Sun, 31 Aug 2025 11:38:03 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. getelementby_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/getelementby_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[(3) 2시간 만에 서비스 만들기]]></title>
            <link>https://velog.io/@getelementby_/3-2%EC%8B%9C%EA%B0%84-%EB%A7%8C%EC%97%90-%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@getelementby_/3-2%EC%8B%9C%EA%B0%84-%EB%A7%8C%EC%97%90-%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sun, 31 Aug 2025 11:38:03 GMT</pubDate>
            <description><![CDATA[<p>mvp 나온걸 기반으로 후다닥 서비스를 만들어보기로 했다. 
우선 빠르게 배포해서 어디 부분에서 이탈율이 생기는지 알아보고, 빠르게 개선 -&gt; 배포 과정을 거치기로 했다. </p>
<p>우리의 mvp: 매 주 5개의 질답을 이미지로 저장 -&gt; 공유 가능</p>
<p>(GPT 이용해서 만든 내용 쓰기)</p>
<p>GTM 심기. 
역시 제로베이스에서 GPT를 다루는 건 꽤나 까다롭다. 
모든 걸 단계별로 물어가며 진행해야 했다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[(2) 우리 프로덕트의 아하모먼트는 뭐가 될까?]]></title>
            <link>https://velog.io/@getelementby_/2-%EC%9A%B0%EB%A6%AC-%ED%94%84%EB%A1%9C%EB%8D%95%ED%8A%B8%EC%9D%98-%EC%95%84%ED%95%98%EB%AA%A8%EB%A8%BC%ED%8A%B8%EB%8A%94-%EB%AD%90%EA%B0%80-%EB%90%A0%EA%B9%8C</link>
            <guid>https://velog.io/@getelementby_/2-%EC%9A%B0%EB%A6%AC-%ED%94%84%EB%A1%9C%EB%8D%95%ED%8A%B8%EC%9D%98-%EC%95%84%ED%95%98%EB%AA%A8%EB%A8%BC%ED%8A%B8%EB%8A%94-%EB%AD%90%EA%B0%80-%EB%90%A0%EA%B9%8C</guid>
            <pubDate>Tue, 26 Aug 2025 14:30:10 GMT</pubDate>
            <description><![CDATA[<p>AHA Moment
-&gt; 고객이 제품의 핵심 가치를 처음 경험하는 것이라고 했다. </p>
<p>예를들어 페북의 아하모먼트는 가입 후 최초 10일 이내에 7명의 친구와 연결 되는 것.</p>
<p>그래서 이** 아하모먼트를 어떻게 만들 수 있을까가 핵심이다.** </p>
<p>1번. 페이스북의 핵심 기능</p>
<ul>
<li>사람들과 커뮤니케이션</li>
<li>글 작성, 서로에게 좋아요 댓글</li>
</ul>
<p>2번. 이걸 잘하려면 무엇이 필요할까?</p>
<ul>
<li>친구가 있어야 한다.</li>
<li>몇 명이 필요할까?</li>
<li>친구 확보하는데 얼마의 시간이 필요하지?</li>
</ul>
<p>이러한 고민과 분석을 통해 위에 아하모먼트를 정의하게 된 것.
즉 문제 본질에 대해 고민해봐야 제대로된 아하모먼트를 찾을 수 있는것!!!</p>
<p>이걸 우리 서비스에도 적용해보자</p>
<h3 id="우리-서비스-핵심-기능">우리 서비스 핵심 기능</h3>
<p> 1) 나의 취향을 선택해서 보여줄 수 있음.
 2) 다른 사람의 피드(임시)를 읽을 수 있음.
 3) 레터를 통한 커뮤니케이션</p>
<h3 id="이걸-잘하려면-무엇이-필요할까">이걸 잘하려면 무엇이 필요할까?</h3>
<p>1) 나의 취향을 선택해서 보여줄 수 있음.</p>
<ul>
<li>일단. 무조건 프로필을 등록해야 한다.
홈 방문시 무조건 가입 + 등록을 해야 보이도록 설정?
프로필 등록 단계를 간소화</li>
</ul>
<p>참고 데이터: 첫방문자 등록비율 / 이탈되는 단계 </p>
<ul>
<li>누군가에게 보여주고 싶은 마음을 들게 한다.
피드를 어떻게 구성해야 그런 마음이 들까? -&gt; 내향인 타겟이니까 집 내부 무언가로... 느낌이 나면 좋겠는데. 비밀스럽게 꺼내는 느낌이 들면 좋겠어. </li>
</ul>
<p>계속 쓰게 만들려면 어떻게 해야할까? -&gt; 글 3번 써야 사진 추가 열리게? 이런건 어떨까. 자기가 찍은 사진을 올리고 싶어서라도 계속 들어와서 글을 쓰지 않으려나. 
참고 데이터:다른 앱에 리그램 하는 횟수 / 프로필 수정 횟수?</p>
<p>2) 다른 사람의 피드(임시)를 읽을 수 있음.</p>
<ul>
<li>어떻게 해야 클
3) 레터를 통한 커뮤니케이션</li>
</ul>
<p>3번. 1,2번에서 도출해낸 아하모먼트</p>
<p>--&gt; 여기까지 써보고 들은 피드백.</p>
<p>지금까지 핵심기능을 보면 블로그, 트위터가 비슷한데 
내 서비스는 어떤 차별점이 있냐? -&gt; USP를 찾아라! 
기능적으로 보면 피드나 쪽지가 동일하잖아. 
왜 내걸 써야 하냐????</p>
<p>타겟 페르소나를 정해라. 
내향인이 어떤 내향인?인데??</p>
<p>핵심기능이 너무 크다. 좀 줄여야할거 같음. 
(내껄 보여줄 수 있음. 
남의 걸 볼 수 있음. 
서로 레터를 보낼 수 있음.)
-&gt; MVP를 생각해봐. </p>
<p>로그인 / 프로필 (취향 선택한) / 프로필을 카드 형식으로 만들어서 저장하도록 한다. (카드 url공유) / 
-&gt; 디자인이 넘 중요할 것 같아. -&gt; 이건 우리의 가설. </p>
<ol>
<li>디자인이 기깔나야한다. </li>
<li>공유하는게 우선이다 vs 내 프로필을 만들어서 기록하는게 우선이다. 이걸 체크해볼 수 있겠음. </li>
</ol>
<p>프로필을 어떻게 구성시킬지 고민해봐야겠다. . .</p>
<p>(이야기 하다보니) 취향으로 과연 잘 맞는 사람을 찾을 수 있나???
나는 사실 이제 취향으로 사람을 판단하는게 재미가 없어졌거든...
-&gt; 흠 그럼 100문 100답해?! </p>
<p>!! 이걸로 해보자. 
우리의 mvp
매 주 5개 정도의 질문을 뽑아서 그 질문의 대한 답을 이미지로 만들어서 공유하게 한다. (나를 보여주는 카드) </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[(1)PMF 프로세스에 맞춰서 프로덕트 고민 시작 ]]></title>
            <link>https://velog.io/@getelementby_/1PMF-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%97%90-%EB%A7%9E%EC%B6%B0%EC%84%9C-%ED%94%84%EB%A1%9C%EB%8D%95%ED%8A%B8-%EA%B3%A0%EB%AF%BC-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@getelementby_/1PMF-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%97%90-%EB%A7%9E%EC%B6%B0%EC%84%9C-%ED%94%84%EB%A1%9C%EB%8D%95%ED%8A%B8-%EA%B3%A0%EB%AF%BC-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Mon, 25 Aug 2025 13:01:43 GMT</pubDate>
            <description><![CDATA[<p>_카일스쿨 <a href="https://www.inflearn.com/course/pm-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A6%AC%ED%84%B0%EB%9F%AC%EC%8B%9C/dashboard">PM을 위한 데이터 리터러시 </a>인프런 강의를 들으며 방법론등을 따라갑니다. _</p>
<h2 id="시작-전">시작 전</h2>
<p>내가 하고 싶은 것은... 
나는 <strong>사람들이 연결되는 과정</strong>을 좋아한다.
이왕이면 잘 맞는. <strong>취향이 있는 사람들을 연결</strong>시키고 싶다. 
여기서 연결은 꼭 <strong>오프라인만을 요구하지 않는다.</strong> </p>
<h4 id="제품은-고객의-불편함을-해결하기-위해-존재함">제품은 고객의 불편함을 해결하기 위해 존재함!!!!</h4>
<p>그렇다면 나 + 친구들이 그동안 매칭서비스(ex.남의집,문토,소모임,인스타그램 기타 등등)를 써보며 <strong>불편하다고 느낀점은</strong>...</p>
<ol>
<li>인싸들만 모여있는 것 같아. 부담스러워.</li>
<li>포괄적인 취향으로 모임이 만들어지네. -&gt; 누가 올지 가늠이 안 돼.</li>
<li>취향보단 결국 사람을 만나기 위해 모임이 생산되는거 같아. -&gt; 난 모임에 가고 싶은게 아니라 취향이 맞는 사람을 만나고 싶은거야!</li>
<li>꼭 만나지 않아도 이 사람에 대해 계속 지켜보고 싶음(단순 디깅용으로)</li>
</ol>
<p>이걸 해결할 수 있는 서비스를 만들어보자!! 
만들기 전 PMF를 통해 틀을 짜보겠다. </p>
<h2 id="pmf-프로세스product-market-fit">PMF 프로세스(Product Market Fit)</h2>
<p>-&gt; 사람들이 문제를 해결하고, 문제 해결을 위해 비용을 지불할 시장이 있냐.</p>
<p><em>타겟정의 → 타겟니즈파악 → 현재 사용할 수 있는 대안 탐색 → 대안보다 뭐가 좋은지 파악</em></p>
<h4 id="타겟-정의"><strong>&lt;타겟 정의&gt;</strong></h4>
<p>⇒ <strong>나와 &lt;잘 맞는&gt; 사람과 커넥팅 되고 싶은 내향인</strong></p>
<p>((다음 포스트에서 고도화))
여기서 내가 명확히 정의할 내용은...</p>
<p>내향인: 사람을 싫어하는게 아니다.(너무 많은 사람이 있는게 부담스럽다.) 재미없는 사람이 아니다. (굳이 나서고 싶지 않다)  소심하거나 말이 없는 사람이 아니다. </p>
<p>잘맞는다: 모든 걸 포괄하는 취향으로 갈지 카테고리 하나만 잡고 일단 시작할지. </p>
<h4 id="타겟-니즈-파악">&lt;타겟 니즈 파악&gt;</h4>
<p>내향인: 4인 이상 넘어가면 부담스러워함 / 괜한 위험부담을 짊어지기보단 차라리 혼자 즐긴다. </p>
<p>취향:  좀 더 넓고 깊은 취향을 가진 사람들이 </p>
<h4 id="현재-사용할-수-있는-대안-탐색">&lt;현재 사용할 수 있는 대안 탐색&gt;</h4>
<p>내향인을 위한 대안 → 블로그 인스타그램 애플뮤직 왓챠피디아</p>
<p>공통점: 일방향적이어도 되는 것. 그래도 나의 무언가를 전시할 수 있고 내가 선택한 사람들이 볼 수 있는 것. </p>
<p>취향→ 넷플연가 트레바리 문토 당근</p>
<p>공통점: 평소라면 만날 수 없는 세미인플루언서도 만날 수 있음. 비용이 필요함. 단발성도 가능. 거의 모든 사람을 포용할 수 있을 것 같음. </p>
<h4 id="대안보다-좋은게-뭔지-파악">&lt;대안보다 좋은게 뭔지 파악&gt;</h4>
<h2 id="aha-moment">AHA Moment</h2>
<p>-&gt; 고객이 제품의 핵심 가치를 처음 경험하는 것</p>
<p>AHA Moment 생각하는 과정은 즉 본질부터 고민하는 것이다. </p>
<p>예를들어 페북의 아하모먼트는
10일 이내 2명의 친구를 만나서 쌍방향 리액션이 이루도록 한다.</p>
<p>그렇다면 <strong>우선 우리 서비스의 핵심 기능(MVP가 될것임)</strong>은?</p>
<ul>
<li>나와 잘 맞는 친구를 찾는 것</li>
<li>잘맞는 친구와 연결 되는 것(각각 리액션을 하는 것)</li>
</ul>
<p>((다음 포스트에서 고도화))
이걸 잘하려면 무엇이 필요할까?</p>
<ul>
<li><p>잘 맞음의 기준을 명확히 세운다.
ex.. 취향이라는 포괄적인 것으로 갈것인지. 아님 하나의 카테고리로 갈 것인지. (하나씩 여는 것도 괜찮을듯...)</p>
</li>
<li><p>서로에게 부담주지 않는 방법으로 리액션 할 수 있는 방법이 뭔지 정리한다.
ex.. 매칭 말고 서로의 글을 펼쳐서 볼 수 있고. 그 중에 선택할 수 있는 형식으로 가는게 좋을 것 같음.(이걸 이미지화 하는게 좀 중요하겠는디.. 귀엽게 가야 해볼거 같음)
맘에 드는 글에 레터를 보낼 수 있음. 레터를 주고 받는 형태로 연결시키기. (동숲처럼 그런 레터..)</p>
</li>
<li><p>리액션을 했을때 어떤 리워드를 줄것인지 정리한다.
ex.. 이건 다음 단계에서 넣으면 될거 같은데 레터를 주고 받은 사람들끼리 뭉칠 수 있도록</p>
</li>
</ul>
<p>오늘의 요약
문제 상황 -&gt; 아하모먼트 -&gt; 습관형성</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[1차 회의]]></title>
            <link>https://velog.io/@getelementby_/1%EC%B0%A8-%ED%9A%8C%EC%9D%98</link>
            <guid>https://velog.io/@getelementby_/1%EC%B0%A8-%ED%9A%8C%EC%9D%98</guid>
            <pubDate>Tue, 25 Feb 2025 04:24:18 GMT</pubDate>
            <description><![CDATA[<p>ㅇㅇㅇ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 문서 읽기 useTransition / useDeferredValue]]></title>
            <link>https://velog.io/@getelementby_/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%AC%B8%EC%84%9C-%EC%9D%BD%EA%B8%B0-useTransition-useDeferredValue</link>
            <guid>https://velog.io/@getelementby_/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%AC%B8%EC%84%9C-%EC%9D%BD%EA%B8%B0-useTransition-useDeferredValue</guid>
            <pubDate>Mon, 26 Feb 2024 10:23:17 GMT</pubDate>
            <description><![CDATA[<h1 id="usetransition">useTransition</h1>
<ul>
<li><p>UI를 차단하지 않고 상태를 업데이트할 수 있는 hook</p>
</li>
<li><p>startTransition은 non-blocking이다</p>
</li>
<li><p><strong>startTransition에 전달하는 함수는 동기식이어야 한다.</strong></p>
</li>
<li><p>진행 중인 transition이 여러 개 있는 경우 React는 현재 이를 일괄 처리. 이는 향후 릴리스에서 제거될 가능성이 있음.</p>
</li>
<li><p>Suspense 가 가능한 라우터는 기본적으로 transition 으로 감싸야한다.</p>
</li>
<li><p>state update marked as a transition will be interrupted by other state updates. For example, if you update a chart component inside a transition, but then start typing into an input while the chart is in the middle of a re-render, React will restart the rendering work on the chart component after handling the input update.
전환으로 표시된 상태 업데이트는 다른 상태 업데이트에 의해 중단될 수 있습니다. 예를 들어 전환 내에서 차트 컴포넌트를 업데이트하지만, 차트가 다시 렌더링되는 중에 입력란에 입력을 시작하면, React는 입력 업데이트를 처리한 후 차트 컴포넌트의 렌더링 작업을 다시 시작합니다.</p>
</li>
<li><p>startTransition함수 안에는 하나 또는 여러 개의 state setter가 있다. 논블로킹이고, 원치않는 로딩 인디게이터를 노출하지 않는다.</p>
</li>
<li><p>인자가 있는 걸 원하는 useDeferredValue를 쓰고, 그렇지 않으면 useTransition을 쓰면 된다.</p>
</li>
<li><p>startTransition 안에는 실행되는 로직은 반드시 동기적이어야 한다.</p>
</li>
<li><p>text input 제어에는 사용할 수 없다.</p>
</li>
<li><p>라우터를 서스펜스로 감쌌다. 라우터가 네비게이터가 될때 폴백이 뜨며 스피너가 돌면 안 되자나. 그러니까 useTransition을 통해 스피너가 폴백을 안 타게 한다. </p>
</li>
</ul>
<h1 id="usedeferredvalue">useDeferredValue</h1>
<ul>
<li><p>React는 먼저 지연된 값을 업데이트하지 않고 렌더링하고, 그런 다음 백그라운드에서 새로 받은 값으로 다시 렌더링을 시도</p>
</li>
<li><p>useDeferredValue로 인한 백그라운드 재렌더링은 화면에 커밋될 때까지 Effects를 발생시키지 않는다. 백그라운드 리렌더링이 일시 중단되면, 해당 effect는 데이터가 로드되고 UI가 업데이트된 후에 실행. </p>
</li>
<li><p>UI의 업데이트를 연기할 수 있는 hook</p>
</li>
<li><p>During updates, the deferred value will “lag behind” the latest value. In particular, React will first re-render without updating the deferred value, and then try to re-render with the newly received value in background.
React에서는 업데이트 중에 useDeferredValue로 반환되는 값이 최신 값과 동기화되지 않는다. --&gt;  React는 먼저 useDeferredValue로 사용하여 화면을 다시 렌더링 한다.</p>
</li>
<li><p>이전 state로 리렌더링을 일으키고, 백그라운드에서 새로운 state를 렌더하고 있다. 이 새로운 리렌더링은 중단될 수 있다(퍼포먼스에 도움이 되겠구만??)
1 --&gt; 2로 업데이트 하다가 1로 다시 사용하지 않아도...</p>
</li>
<li><p>디바운싱, 쓰로틀링은 지연시간을 정해줘야하지만, useDeferredValue는 지연시간을 정해주지 않아도 된다</p>
</li>
</ul>
<p>During the initial render, the deferred value will be the same as the value you provided.</p>
<p>During updates, the deferred value will “lag behind” the latest value. In particular, React will first re-render without updating the deferred value, and then try to re-render with the newly received value in background.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 문서 읽기. useMemo / useCallback]]></title>
            <link>https://velog.io/@getelementby_/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%AC%B8%EC%84%9C-%EC%9D%BD%EA%B8%B0.-useMemo-useCallback</link>
            <guid>https://velog.io/@getelementby_/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%AC%B8%EC%84%9C-%EC%9D%BD%EA%B8%B0.-useMemo-useCallback</guid>
            <pubDate>Mon, 19 Feb 2024 09:54:18 GMT</pubDate>
            <description><![CDATA[<p><a href="https://react.dev/reference/react/useMemo">https://react.dev/reference/react/useMemo</a>
<a href="https://react.dev/reference/react/useCallback">https://react.dev/reference/react/useCallback</a></p>
<p>###useMemo
useMemo is a React Hook that lets you cache the result of a calculation between re-renders.</p>
<p>React will call your function during the initial render. On next renders, *<em>React will return the same value again if the dependencies have not changed since the last render. 
*</em></p>
<p>React will not throw away the cached value unless there is a specific reason to do that. For example, in development, React throws away the cache when you edit the file of your component. Both in development and in production, React will throw away the cache if your component suspends during the initial mount. In the future, React may add more features that take advantage of throwing away the cache—for example, if React adds built-in support for virtualized lists in the future, it would make sense to throw away the cache for items that scroll out of the virtualized table viewport. This should be fine if you rely on useMemo solely as a performance optimization. Otherwise, a state variable or a ref may be more appropriate.</p>
<p>리액트는 특정 이유가 없는 한 캐시된 값을 버리지 않습니다. 예를 들어, 개발 중에는 컴포넌트 파일을 편집할 때 캐시를 버립니다. 개발 및 프로덕션 모두에서 초기 마운트 중에 컴포넌트가 중단되면 리액트는 캐시를 버립니다. 미래에는 리액트가 캐시를 버리는 기능을 활용하는 더 많은 기능을 추가할 수 있습니다. 예를 들어, 리액트가 미래에 가상 목록을 내장 지원하는 기능을 추가한다면, 가상 테이블 뷰포트에서 스크롤되어 보이지 않는 항목에 대한 캐시를 버리는 것이 타당할 것입니다. 이것은 useMemo를 성능 최적화 용도로만 사용하는 경우에는 문제가 되지 않을 것입니다. 그렇지 않으면 상태 변수나 ref를 사용하는 것이 더 적절할 수 있습니다.</p>
<p>--&gt; 이부분 잘 이해가 안 가는데 useMemo는 불필요하게 캐싱된 값을 가진다는 의미인건지..? </p>
<p>useMemo caches a calculation result between re-renders until its dependencies change.
다시 말해, useMemo는 종속성이 변경될 때까지 다시 렌더링 사이에 계산 결과를 캐시합니다.</p>
<p>Also, not all memoization is effective: a single value that’s “always new” is enough to break memoization for an entire component.
&quot;항상 새로운&quot; 단일 값이 있으면 컴포넌트 전체에 대한 메모이제이션을 깨뜨릴 수 있습니다.</p>
<p>*<em>Depending on an object like this defeats the point of memoization. *</em>When a component re-renders, all of the code directly inside the component body runs again. The lines of code creating the searchOptions object will also run on every re-render. Since searchOptions is a dependency of your useMemo call, and it’s different every time, React knows the dependencies are different, and recalculate searchItems every time.</p>
<p>*<em>My useMemo call is supposed to return an object, but returns undefined *</em></p>
<pre><code>  const searchOptions = useMemo(() =&gt; {
    matchMode: &#39;whole-word&#39;,
    text: text
  }, [text]);

    // This works, but is easy for someone to break again
  const searchOptions = useMemo(() =&gt; ({
    matchMode: &#39;whole-word&#39;,
    text: text
  }), [text]);</code></pre><p>###useCallback
useMemo is a React Hook that lets you cache the result of a calculation between re-renders.
useMemo는 재렌더링 사이에서 계산 결과를 캐시하는 React Hook입니다.</p>
<p>useCallback is a React Hook that lets you cache a function definition between re-renders.
useCallback은 재렌더링 사이에서 함수 정의를 캐시하는 React Hook입니다.</p>
<pre><code>export default function Page({ productId, referrer }) {
  const handleSubmit = useMemo(() =&gt; {
    return (orderDetails) =&gt; {
      post(&#39;/product/&#39; + productId + &#39;/buy&#39;, {
        referrer,
        orderDetails
      });
    };
  }, [productId, referrer]);

  return &lt;Form onSubmit={handleSubmit} /&gt;;
}

export default function Page({ productId, referrer }) {
  const handleSubmit = useCallback((orderDetails) =&gt; {
    post(&#39;/product/&#39; + productId + &#39;/buy&#39;, {
      referrer,
      orderDetails
    });
  }, [productId, referrer]);

  return &lt;Form onSubmit={handleSubmit} /&gt;;
}</code></pre><p>위처럼 한 이유. 일단 useMemo는 빈 파라미터를 보내야 하니까!!! 이 부분 넘 중요하다. </p>
<p>useMemo: Caches the result of calling a function. It&#39;s useful when you want to memoize the result of a computation based on certain dependencies. React will call the function to recalculate the result only when necessary.</p>
<p>useCallback: Caches the function itself. It&#39;s handy when you want to memoize a callback function to prevent unnecessary re-renders of child components. The function will not be invoked until it&#39;s actually needed, typically when an event occurs.</p>
<p>useMemo: 함수 호출 결과를 캐시합니다. 특정 종속성에 따라 계산 결과를 메모이제이션하려는 경우 유용합니다. React는 필요할 때만 함수를 호출하여 결과를 다시 계산합니다.</p>
<p>useCallback: 함수 자체를 캐시합니다. 자식 컴포넌트의 불필요한 다시 렌더링을 방지하기 위해 콜백 함수를 메모이제이션하려는 경우 유용합니다. 함수는 실제로 필요할 때까지 호출되지 않습니다. 일반적으로 이벤트가 발생할 때 호출됩니다.</p>
<p>팀원들과 나눈 이야기
##useMemo</p>
<ul>
<li>React will not throw away the cached value unless there is a specific reason to do that. For example, in development, React throws away the cache when you edit the file of your component. Both in development and in production, React will throw away the cache if your component suspends during the initial mount.</li>
<li>-&gt; 이부분 잘 이해가 안 가는데 리액트가 특정 상황이 아니라면 캐시된 값을 버리지 않는다는건데 이게 useMemo의 특징인건지 리액트의 특징이란건지..?</li>
<li>-&gt; 이건 메모제이션의 특징이라고 보면 된다!!!</li>
</ul>
<ul>
<li><p>My useMemo call is supposed to return an object, but returns undefined.. </p>
</li>
<li><p>-&gt; 이거 실수한적 있던 기억이 났음. </p>
</li>
<li><p>useMemo 쓸지 말지 비용이 비싼지 알고 싶을 땐, console.time을 이용하자. </p>
</li>
<li><p>calculation function은 pure 해야한다.</p>
</li>
</ul>
<p>##useCallback</p>
<ul>
<li>useCallback is a React Hook that lets you cache a function definition between re-renders.</li>
</ul>
<p>useMemo is a React Hook that lets you cache the result of a calculation between re-renders.
함수를 호출하고 나온 결과를 캐싱하는 것이 useMemo useCallback은 함수 자체를 캐시 하는 차이가 있다. </p>
<ul>
<li><p>자식 컴포넌트의 불필요한 렌더링을 막고 싶다면 사용하기 좋다.</p>
</li>
<li><p>다음상태를 계산하기 위해 상태를 읽는 경우, 대신 업데이트 함수를 전달하여 해당 dependency를 제거할 수 있다.</p>
</li>
<li><p>커스텀 훅에서, 해당 Hook이 반환하는 모든 함수를 useCallback으로 래핑하는 것을 권장</p>
</li>
<li><p>useMemo는 함수의 결과값을 캐싱하고, useCallback은 함수 자체를 캐싱한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React 공홈 읽기 - Reference [useEffect ] / [useLayoutEffect ] / [useInsertionEffect]]]></title>
            <link>https://velog.io/@getelementby_/React-%EA%B3%B5%ED%99%88-%EC%9D%BD%EA%B8%B0-Reference-useEffect-useLayoutEffect-useInsertionEffect</link>
            <guid>https://velog.io/@getelementby_/React-%EA%B3%B5%ED%99%88-%EC%9D%BD%EA%B8%B0-Reference-useEffect-useLayoutEffect-useInsertionEffect</guid>
            <pubDate>Thu, 25 Jan 2024 09:29:43 GMT</pubDate>
            <description><![CDATA[<p><a href="https://react.dev/reference/react/useEffect">https://react.dev/reference/react/useEffect</a>
<a href="https://react.dev/reference/react/useInsertionEffect">https://react.dev/reference/react/useInsertionEffect</a></p>
<p>팀원들과 공유한 이야기.</p>
<h1 id="useeffect">useEffect</h1>
<ul>
<li>외부 동기화 되는 코드가 아니라면  Effect를 제거할 수 있는 방법을 찾아보자. 간결화.</li>
<li>클린업 함수는 언마운트중 + 종속성이 변경되어 리렌더링 전에도 실행된다. 셋업 로직 없이 클린업 코드만 쓰는 걸 피해라.</li>
<li>useEffect는 외부시스템(external system)과 컴포넌트를 연결해주는 훅이다.</li>
<li>첫번째 인자를 setup function 이라고 부르는 구나. 처음 알았다.</li>
<li>서버렌더링에서는 useEffect는 돌아가지 않는다.</li>
<li>cleanup function은 unmount 외에도 dependencies가 변경되서 리렌더링 될 때마다호출된다</li>
<li>시각적인 작업에 대해 useLayoutEffect로 바꾸자.</li>
<li>effects를 수동으로 작성해야 하는 경우가 많다면 customHook을 추출해야 하는 신호다~</li>
<li>lint를 이용해 deps를 막는거보다 deps가 필요 없다는것을 증명 하자</li>
<li>effect는 서버사이드 렌더링의 영향을 안끼침</li>
<li>effect내의 Non-reactive 한 코드는 분리해서 사용</li>
</ul>
<h1 id="uselayouteffect">useLayoutEffect</h1>
<ul>
<li>The purpose of useLayoutEffect is to let your component use layout information for rendering (useLayoutEffect의 목적 --&gt; 컴포넌트가 렌더링에 레이아웃 정보를 사용할 수 있도록 하는 것)</li>
</ul>
<ul>
<li><p>서버 렌더링 환경에서 에러 없이 useLayoutEffect 사용하려면 </p>
<ul>
<li>useEffect 대체하자.</li>
<li><Suspense> 활용.<ul>
<li>hydration 이후에 사용할 수 있도록 훅 만들어주자. </li>
</ul>
</li>
<li>useSyncExternalStore 사용</li>
</ul>
</li>
<li><p>repaint 전에 호출되는 훅이다.</p>
</li>
<li><p>문서에서 useEffect setup 부분과 다른 설명: Before your component is added to the DOM, setup 함수가 호출된다.</p>
</li>
<li><p>Before your component is removed from the DOM, clean up 함수가 호출된다.</p>
</li>
<li><p>SSR 프레임워크를 쓰는 경우에는 useLayoutEffect보다는 useEffect를 써야할 수도 있다. 또는 Suspense 컴포넌트를 활용해서 클라이언트사이드에서만 렌더링되게 해볼 수도 있다.</p>
</li>
</ul>
<h1 id="useinsertioneffect">useInsertionEffect</h1>
<ul>
<li>useInsertionEffect는 레이아웃 이펙트가 발생하기 전에 요소를 DOM에 삽입할 수 있게 하는 것. </li>
<li>CSS in JS 라이브러리 개발자를 위한 훅이다. layout effects 가 동작하기 전에 style 태그를 DOM에 집어넣기 위해 호출되는 훅이다.<ul>
<li>이 훅 안에서는 state setter(setState)할 수 없고, ref가 지원되지 않고, DOM 업데이트 전 또는 후에 실행될 수 있으니까 무조건 한쪽 라이프사이클만 생각하고 코드를 작성하면 안된다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React 공홈 읽기 - Reference
[useRef] / [useImperativeHandle]]]></title>
            <link>https://velog.io/@getelementby_/React-%EA%B3%B5%ED%99%88-%EC%9D%BD%EA%B8%B0-useRef-useImperativeHandle</link>
            <guid>https://velog.io/@getelementby_/React-%EA%B3%B5%ED%99%88-%EC%9D%BD%EA%B8%B0-useRef-useImperativeHandle</guid>
            <pubDate>Mon, 15 Jan 2024 10:25:58 GMT</pubDate>
            <description><![CDATA[<p>읽고 스터디원들과 공유한 내용. </p>
<p>useRef</p>
<ul>
<li>다음 렌더링에서 useRef는 동일한 객체를 반환한다. </li>
<li>useRef 는 렌더링에 필요하지 않은 값을 참고할 수 있게 해주는 훅</li>
<li>ref는 그냥 자바스크립트 plain object이다. ref.current가 바껴도 리액트는 변화를 감지하지 못하고 리렌더링을 하지 않는다.</li>
<li>strict mode에서는 ref 객체가 두번 생성되고, 둘 중 하나는 버려진다. 컴포넌트 함수가 pure하게 만들었다면 문제 없다! (pure 하지 않다면, ref 동작이 원하는대로 안된다는 말인가보네)</li>
<li>언제쓰면 좋은가? <ul>
<li>re-render 일어나는 사이에 값을 저장하고 싶을 때.</li>
<li>리렌더를 일으키지 않고 값을 변경하고 싶은게 있을 때</li>
</ul>
</li>
<li>useRef(new VideoPlayer())는 객체 생성 비용이 넘 많이 든다. playerRef.current === null이면, playerRef.current = new VideoPlayer(); 로 값을 할당할 수도 있다.</li>
</ul>
<p>useImperativeHandle</p>
<ul>
<li>useInperativeHandle 은 props으로 표현할 수 없는 명령형 동작에만 사용해야한다. (무분별한 사용 x)<ul>
<li>예를들면 스크롤 이동, 포커스</li>
</ul>
</li>
</ul>
<pre><code> `&lt;input {...props} ref={ref} /&gt;`보며 궁금한 점. 
 ref={ref}를 제일 마지막에 둔 이유는 뭘까?


1번 의견. 
ref를 넘길 수 있는 방법
element냐
forwordRef냐 

element? forwordRef 아니면면 넘길 수 없다며?
---&gt; htmlElement면 ref를 넘길 수 있다. 
컴포넌트면 ref를 넘길 수 없음. 


forwordRef라면
두번째 인자로 무조건 ref라 요렇게 해줘야함. 
&lt;input {...props} ref={ref} /&gt;;</code></pre><p>   2번 의견
   뒤에 쓴 애가 최종값이자나?  내가 쓴 ref만 쓰게 막아둔거다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[시나브로자바스크립트 - 웹서버기초(1,2)]]></title>
            <link>https://velog.io/@getelementby_/%EC%8B%9C%EB%82%98%EB%B8%8C%EB%A1%9C%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9B%B9%EC%84%9C%EB%B2%84%EA%B8%B0%EC%B4%8812</link>
            <guid>https://velog.io/@getelementby_/%EC%8B%9C%EB%82%98%EB%B8%8C%EB%A1%9C%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9B%B9%EC%84%9C%EB%B2%84%EA%B8%B0%EC%B4%8812</guid>
            <pubDate>Thu, 11 Jan 2024 22:00:46 GMT</pubDate>
            <description><![CDATA[<p>(1) 강의에서. . </p>
<p>1번.
웹서버 작성 코드를 작성하다가 <strong>Content-Typ</strong>e은 뭘까? 궁금해졌다.
<code>res.setHeader(&#39;Content-Type&#39;, &#39;text/plain&#39;);</code></p>
<blockquote>
<p>The Content-Type entity header is used to indicate the media type of the resource. In requests, (such as POST or PUT), the client tells the server what type of data is actually sent. (Source: MDN Web Docs)</p>
</blockquote>
<p>HTTP GET 메소드는 text 형식으로 보내지니까 별도로 Content-Type 필요 없지만 POST, PUT처럼 <strong>request</strong> 하는 것은 필요해 ! <a href="https://pygmalion0220.tistory.com/entry/HTTP-Content-Type">인용</a></p>
<p>즉 Content-Type은 request에 실어보내는 데이터(body)의 Type 정보라고 할 수 있다. <a href="https://gist.github.com/jays1204/703297eb0da1facdc454">인용</a></p>
<p>2번.
package.json --&gt; &quot;type&quot;: &quot;module&quot; 이라면 import / export를 써야한다.</p>
<pre><code>// 변경전
const http = require(&#39;http&#39;);

// 변경후
import http from &#39;http&#39;;</code></pre><p>만약 변경하기 싫고. require로 할거라면 해당 .js 파일을 .cjs로 바꾸자.</p>
<p>(2)강의에서. . 
node.js만 순수하게 쓴다면 간편하지만, 관리가 어려울 수 있어. 
그래서 node.js 웹 프레임워크 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React 공홈 읽기 - Reference [useContext]]]></title>
            <link>https://velog.io/@getelementby_/React-%EA%B3%B5%ED%99%88-%EC%9D%BD%EA%B8%B0-Reference-useContext</link>
            <guid>https://velog.io/@getelementby_/React-%EA%B3%B5%ED%99%88-%EC%9D%BD%EA%B8%B0-Reference-useContext</guid>
            <pubDate>Tue, 09 Jan 2024 09:07:08 GMT</pubDate>
            <description><![CDATA[<p><a href="https://react.dev/reference/react/createContext">https://react.dev/reference/react/createContext</a></p>
<p>useContext returns the context value for the calling component.</p>
<p>If there is no such provider, then the returned value will be the defaultValue you have passed to createContext for that context. 
--&gt; defaultValue를 설정 안 할수도 있나? 그렇다면 무엇을 반환하게 되는거지?</p>
<p>useContext() call in a component is not affected by providers returned from the same component. The corresponding <strong>&lt;Context.Provider&gt;</strong> needs to be above the component doing the useContext() call.</p>
<p>의견</p>
<ul>
<li>가장 가까운 <code>Context.Provider</code> 에 전달된 value에 따라 결정된다.</li>
<li>Provider는 항상 useContext의 상위에 있어야 한다.</li>
<li>정해진 value가 없으면 스킵해도 되는거 아닌가? 했는데  value={undefined}로 value 명시가 필요하군요.</li>
<li>Context value 변경시 리렌더가 자주 일어나다 보니 이때는 useMemo, useCallback 을 적절히 사용해서 최적화 하자.
가장 가까운 SomeContext.Provider에서 정의한 값을 리턴하고, 프로바이더가 없으면 defaultValue를 리턴한다.</li>
<li>Object.is() 로 비교했을 때 value가 변경된거면, 리액트는 모든 자식을 리렌더 시킨다.</li>
<li>symlinks가 뭐지??? --&gt; 바로가기 같은 것.</li>
<li>*<em>memo를 사용한 경우에도 context의 새로운값(최신 값)을 자식에 전달한다. = memo로 렌더링을 건너뛰어도 새로운 값을 받는 것을 막을 수 없다. = 새로운 값은 받지만 리렌더는 안 한다는 것 ! ! *</em></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 7장]]></title>
            <link>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-7%EC%9E%A5</link>
            <guid>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-7%EC%9E%A5</guid>
            <pubDate>Fri, 23 Jun 2023 00:00:46 GMT</pubDate>
            <description><![CDATA[<p>배열은 값의 순서 있는 집합. 순서, 즉 위치를 나타내는 숫자인 인덱스가 있다. 
배열에는 모두 length 프로퍼티가 있다. </p>
<h2 id="배열-생성-방법">배열 생성 방법</h2>
<pre><code>//* 1. 배열 리터럴
let arr = [];

//배열 리터럴에 성긴 배열 생성. 값이 생략한 위치에 실제로 배열 요소가 존재하지는 않지만 검색하면 undefined가 반환.
//성긴 배열은 인덱스가 연속적이지 않다. 하여 성긴 배열의 경우 length 프로퍼티의 값이 요소 개수 보다 크다. 
let und = [1,,3];



//* 2. 분해 연산자
let a = [1,2];
let b = [0, ...a, 3]; //[0,1,2,3,4]

// 얕은 복사에 유용 
let original = [1,2,3];
let new = [...original];

new[0] = 0;
original[0] = 1;</code></pre><h3 id="배열-순회">배열 순회</h3>
<p><code>entries()</code> --&gt; 각 요소 index가 필요하다면?</p>
<pre><code>let letters = [...&quot;Hello world&quot;];
let empty = &quot;&quot;;
for(let [index, letter] of letters.entries()) {
    if (index % 2 ===0) empty += letter;

}

empty = Hlowrd</code></pre><p><code>forEach()</code>
배열 순회를 함수형으로 바꾼 배열 메서드. 전달 받은 함수를 각 배열 요소에서 호출하는 것!!!</p>
<pre><code>let data = [1,2,3,4,5] sum = 0;

//forEach는 배열 요소의 인덱스 배열 자체도 인자로 받을 수 있다는 게 포인트! 
data.forEach((item, i, a) =&gt; {
    retrun [a[i] =&gt; item + 1]
}) data = [2,3,4,5,6]</code></pre><h3 id="배열-메서드-자주-사용하는데-헷갈렸던-개념-위주">배열 메서드 (자주 사용하는데 헷갈렸던 개념 위주)</h3>
<p><code>map()</code>
<strong>반환 값이 배열이다 !</strong> </p>
<p><code>filter()</code>
 <strong>true, false를 반환</strong> </p>
<pre><code>//let a = [1,2,3,4,5];

a.filter(x =&gt; x&lt;3) //[1,2]</code></pre><p><code>find()</code> / <code>findIndex()</code>
true를 찾는다는 점에서 filter()와 같지만 이 친구들은 <strong>기준을 만족하는 첫 번째 요소를 찾으면 순회를 바로 멈춘다</strong>! 
요소를 찾았다 --&gt; find()는 요소를 반환 / dinfIndex는 인덱스를 반환. 
요소를 찾지 못했다 --&gt; find()는 undefined / dinfIndex는 -1.</p>
<p><code>every()</code> / <code>some()</code>
이 친구들은 <strong>자신이 어떤 값을 반환할지 확실해지면 순회를 멈춘다.</strong>
some()은 true를 반환하는 즉시 멈추기 때문에 모든 요소를 순회하는 순간은 모든 요소가 false일때. 그럼 모든 값이 false라면.. ..해라 이런 조건식에 쓰면 좋겠지.</p>
<p>every()는 반대야. 하나라도 false면 바로 멈춘다. 모든 요소가 true일때만 다 순환하는 거. 
이런건. 모든 요소가 조건식에 부합해야지만 통과할 수 있어~ 에 쓰면 좋다. </p>
<p><code>flat()</code> --&gt; ...연산자와 concat()도 평탄화 가넝. </p>
<pre><code>[1,[2,3]] = [1,2,3];</code></pre><p><code>concat()</code>
인자에 배열이 들어있으면 배열이 아니라 그 요소를 추가하는 것!!! 기존 배열을 수정하지 않는다. 얕은 복사 ! </p>
<p><code>slice()</code> / <code>splice()</code>
splice()는 slice와 다르게 기존 배열을 수정한다.  </p>
<h3 id="배열을-문자열로-변환">배열을 문자열로 변환</h3>
<p><code>join()</code> 과 <code>toString()</code></p>
<pre><code>let a = [1,2,3];
a.join(&quot;&quot;) //&quot;123&quot;;
[1,2,3].toString() //&quot;a,b,c&quot;;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 6장]]></title>
            <link>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-6%EC%9E%A5</link>
            <guid>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-6%EC%9E%A5</guid>
            <pubDate>Sun, 11 Jun 2023 12:41:50 GMT</pubDate>
            <description><![CDATA[<p>객체: 프로퍼티의 순서 없는 집합이다.</p>
<pre><code>//우리가 hook 만들고 나서 return 할 때 배열이 아닌 객체로 보내는 이유다! 

function useProgress(){
    ...
    return {
        data,
    }
}</code></pre><h4 id="프로퍼티-접근-에러">프로퍼티 접근 에러</h4>
<p>타입스크립트 있으면 좋겠지만. 점 연산자의 왼쪽이 null or undefined면 실패. 그러니 명시적으로 &amp;&amp; or ?. 를 이용해서 하자. </p>
<h4 id="객체-직렬화">객체 직렬화</h4>
<p>객체를 문자열로 변환하는 작업. JSON.stringfy() / JSON.parse()</p>
<p>객체는 아니지만 서버에 데이터 보낼때 배열이 아니라 문자열로 보내야 할 때가 있었다. 그럴 때 JSON.stringfy()로 보내야 할 경우가 있었음. </p>
<h4 id="객체-변경">객체 변경</h4>
<p>스프레드 연산자로 하는 경우가 많았는데.
분해되는 개체와 프로프티를 받는 객체 둘다 같은 이름의 프로퍼티를 갖는다면, 해당프로퍼티의 값은 마지막에 오는 값이 된다. 시즌 요금에서 객체를 덮을 때 이렇게 많이 했지!!</p>
<pre><code>let obj = {name: &#39;고은찬&#39; sex: &#39;male&#39;};
let newObj = {sex: &#39;female&#39;, ...obj};
newobj.sex // male; 


let obj = {name: &#39;고은찬&#39; sex: &#39;male&#39;};
let newObj = {...obj, sex: &#39;female&#39; };
newobj.sex // female; </code></pre><h4 id="확장된-객체-리터럴-문법">확장된 객체 리터럴 문법</h4>
<pre><code>//초간단 생략
let x = 1;
let y = 2;
let o = {x, y}
o.x = 1;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[18 리액트 문서 읽어보자.  JavaScript in JSX with Curly Braces / Passing Props to a Component / Conditional Rendering / ]]></title>
            <link>https://velog.io/@getelementby_/18-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%AC%B8%EC%84%9C-%EC%9D%BD%EC%96%B4%EB%B3%B4%EC%9E%90.-JavaScript-in-JSX-with-Curly-Braces-Passing-Props-to-a-Component-Conditional-Rendering</link>
            <guid>https://velog.io/@getelementby_/18-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%AC%B8%EC%84%9C-%EC%9D%BD%EC%96%B4%EB%B3%B4%EC%9E%90.-JavaScript-in-JSX-with-Curly-Braces-Passing-Props-to-a-Component-Conditional-Rendering</guid>
            <pubDate>Wed, 07 Jun 2023 10:58:19 GMT</pubDate>
            <description><![CDATA[<p><strong>Passing Props to a Component</strong>
Use spread syntax with restraint. If you’re using it in every other component, something is wrong. Often, it indicates that you should split your components and pass children as JSX. More on that next!</p>
<ul>
<li>같은 프롭스를 두 번 쓰는 휴먼 에러나 /  자바스크립트는 런타임 단어니깐. props에 런타임 에러를 일으킬 것들을 보낼 수도 있는데 리액트 문법에만 맞다면 보낼 수 있는거잖아? 이런걸 방지하기 위해 남용하지 말자. </li>
</ul>
<pre><code>//Card가 children이라고 생각할 때, 따로 fragment로 감싸지 않는다. 
&lt;Card&gt;
&lt;h1&gt;안뇽&lt;/h1&gt;
&lt;h1&gt;안뇽&lt;/h1&gt;
&lt;/Card&gt;</code></pre><h4 id="conditional-rendering">Conditional Rendering</h4>
<p>return null; 많이 사용하지 마라. 18버전부터 return;만 해도 된다. </p>
<p><code>foo.length &amp;&amp; &lt;&gt;&lt;/&gt;</code> 이런식으로 쓰지 않는거 꼭꼭 모두에게 리마인드.. &gt;&gt; 앞에 boolean 형태로 들어가도 된다. </p>
<p>&amp;&amp; 잘 안 쓰는 이유 &gt; 다른 사람이 보기에 삼항이 더 명시적이고 undefined, null은 전혀 다르기 때문에 따로 분리해서 해주면 좋을 거 같다. </p>
<p>null == undefined 같아보지만 엄격하게 타입 체크를 한다면 null은 object, undefined = undefined </p>
<p>두 개 체크 할 때 편리하게 ! 이용할 수도 있지만 이건 0, &#39;&#39;까지 포함한다. </p>
<p>이벤트 실행할때</p>
<ol>
<li>onClick={(e) =&gt; console.log(e.target)}</li>
<li>onClick={onClick}
요즘 추세는 1번이다.....</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 5장을 읽고.. ]]></title>
            <link>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-5%EC%9E%A5%EC%9D%84-%EC%9D%BD%EA%B3%A0</link>
            <guid>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-5%EC%9E%A5%EC%9D%84-%EC%9D%BD%EA%B3%A0</guid>
            <pubDate>Tue, 07 Feb 2023 09:55:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>문. <strong>실행</strong>을 통해 <strong>어떤 동작을 수행</strong>하다. </p>
</blockquote>
<p>동작을 수행하는 방법엔 뭐가 있나. </p>
<p><strong>표현문</strong>: 할당이나 함수 호출처럼 부수 효과가 있는 표현식
<strong>선언문</strong>: 변수를 선언하거나 함수를 정의
<strong>제어문</strong>: 기본 실행 순서를 바꾸는 조건문(if, switch) / 루프(while, for)</p>
<h3 id="선언문">선언문</h3>
<ul>
<li>가져오기와 내보내기 할 때 {} 쓰는 차이점은?<pre><code>//default 
export default function getPerHeight({});
</code></pre></li>
</ul>
<p>import getPerHeight from &#39;./&#39;;</p>
<p>//mesure 폴더에서 여러 개를 내보내고 싶다면?
export function getPerHeight({});</p>
<p>import { getPerHeight } from &#39;./&#39;;</p>
<pre><code>


### 제어문
- forEach / map 쓰는 차이는 멀까?

forEach는 기존 배열을 변경 하지 않는다. 또한 undefined 리턴. 구문 밖에선 아무것도 리턴할 수 없는거지.. </code></pre><p>const number=[1,2,3];
const list = [];
number.forEach(n=&gt;list.push(x+1));
console.log(list); //[2,3,4]</p>
<p>```</p>
<p>map도 기존 배열을 변경 하지 않음 다만 ! *<em>새로운 배열을 내뱉는다. *</em> 그래서 데이터 변경엔 좀 더 용이함..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 4장을 읽고. ]]></title>
            <link>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-4%EC%9E%A5%EC%9D%84-%EC%9D%BD%EA%B3%A0</link>
            <guid>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-4%EC%9E%A5%EC%9D%84-%EC%9D%BD%EA%B3%A0</guid>
            <pubDate>Sun, 29 Jan 2023 11:06:30 GMT</pubDate>
            <description><![CDATA[<h2 id="표현식">표현식</h2>
<ul>
<li><p>어떤 값으로 평가 되는 구절로 단순 <strong>상수</strong>, <strong>변수 이름</strong>도 표현식으로 부를 수 있고, <strong>배열 객체 초기화 표현식</strong>, <strong>함수 정의 표현식</strong>, <strong>프로터티 접근 표현식</strong>, <strong>호출 표현식</strong>, <strong>객체 생성 표현식</strong>이 있다.</p>
</li>
<li><p><strong>배열 초기화 표현식</strong> 내의 요소 표현식은 배열 초기화 표현식을 평가할 때마다 평가하기 때문에 결과가 달라질 수 있다. 
<code>let array: [1,,,,5]</code> 콤마 사이의 값을 생략하면 정의되지 않은 요소가 그 자리에 들어간다. </p>
</li>
<li><p>자바스크립트에서 <code>expression.identifier</code>, <code>ecpression [expression]</code> 방식을 통해 프로퍼티에 접근 가능하다. <code>.</code> 이나 <code>[</code> 앞에 표현식을 첫 번째로 평가한다. 그 값이 null / undefinded 면 typeError! 아래 예시로 한 번 더 쳌!</p>
<pre><code>let o ={x: 1, y: {z:3}};
let a = [0, 4, [5,6]];
</code></pre></li>
</ul>
<p>o[&quot;x&quot;] //1 객체 o의 프로퍼티 x
a[1] //4 표현식 a의 인덱스 1에 있는 요소
a[2][&quot;1&quot;] 5 표현식 a[2]의 인덱스 1에 있는 요소 </p>
<pre><code>- **옵셔닝 체이닝**. ?.를 이용한 프로퍼티 접근은 단축 평가다 ! 즉 ?.의 왼쪽에 있는 하위 표현식이 null, undefined인지만 체크. 그래서 실제 뭔지까지는 체크 안 해. 무튼 그래서 둘 중 하나라면 더는 프로퍼티에 접근 하지 않고 전체 표현식을 undefined로 평가 해준다 ! 





## 연산자

![](https://velog.velcdn.com/images/getelementby_/post/741ecdf5-76ef-47ad-8859-2d4e0659fd34/image.jpeg)

- `+`</code></pre><p>1+2 // 3 덧셈
&quot;1&quot;+&quot;2&quot; // &quot;12&quot; 병합
&quot;1&quot;+2 // &quot;12&quot; 숫자를 문자열로 변환 &gt; 병합
1+{} // &quot;1[object Object]&quot; 객체를 문자열로 변환 &gt; 병합
true+true // 2 bool 숫자로 변환 &gt; 덧셈
2+null // 2 null 0으로 변환 &gt; 덧셈
2+undefined NaN</p>
<pre><code>
- `&amp;&amp;`: 오른쪽에 있는 피연산자를 평가할 수도, 안 할수도 있다는 사실을 이해해야 한다. 옵셔널체이닝처럼 단축평가. 왼쪽이 false &gt; 전체적인 값이 false. 왼쪽이 true &gt; 오른쪽이 true면 전체적으로 true, 오른쪽이 false면 전체적인 값이 false.

- `||`: &amp;&amp;와 다르게 두 피연사 중 하나라도 true 같은 값이면 이 연산자는 true 같은 같을 반환한다 ! 왼쪽이 true다? 그럼 단축평가로 바로 true 되는거다. 그래서 이건 사용하기가 까다로움.. 몇가지 변수 중에 첫 번째로 등장하는 true 같은 값을 선택하려고 할 때 이용. 



## 대괄호 표기법에 대해 좀 더 알아보자 !
. 점말고 대괄호 표기법만 사용할 수 있는 경우?
- 프로퍼티로 사용할 수 없는 걸 사용할 경우 (공백, 숫자로 시작하거나..)
- 객체 프로퍼티에 변수를 활용해서 접근 해야 할 떄</code></pre><p>let jonny = {
    age: 20;
    number: &#39;010-000-0000&#39;;
}</p>
<p>function changeType(obj, property, val) {
    obj.property = val; 
}</p>
<p>changeType(jonny, age, 30); //Uncaught ReferenceError:</p>
<p>function changeType(obj, property, val) {
    obj[property] = val; 
}</p>
<p>changeType(jonny, age, 30); //Uncaught ReferenceError:</p>
<pre><code>
- 변수를 key 이름으로 사용할 경우</code></pre><p>let company = {
    name: &#39;여기어떄&#39;
}</p>
<p>let key: &#39;type&#39;;
company[key]: &#39;여행&#39;;</p>
<p>console.log(&#39;company&#39;, companny); // name: &#39;여,,&#39;, type: &#39;여행&#39;</p>
<p>```</p>
<ul>
<li>객체 내부가 정의되지 않은 경우에도 접근 가능 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 완벽가이드 3장을 읽고. ]]></title>
            <link>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%99%84%EB%B2%BD%EA%B0%80%EC%9D%B4%EB%93%9C-3%EC%9E%A5%EC%9D%84-%EC%9D%BD%EA%B3%A0</link>
            <guid>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%99%84%EB%B2%BD%EA%B0%80%EC%9D%B4%EB%93%9C-3%EC%9E%A5%EC%9D%84-%EC%9D%BD%EA%B3%A0</guid>
            <pubDate>Tue, 17 Jan 2023 09:58:57 GMT</pubDate>
            <description><![CDATA[<h4 id="🙋-♀️기본-타입">🙋‍ ♀️기본 타입</h4>
<p>number, string, boolean, null, undefined, symbol(new!)</p>
<p>여기서 <code>null</code>, <code>undefined</code> 알아보자.</p>
<p><code>null</code>: 변수에 값이 없다는 걸 명시적으로 표시. </p>
<p><code>undefined</code>: 존재하지 않는 객체 프로퍼티나 배열 요소에 접근했을 때 반환되는 값. 할당 되지 않은 값. </p>
<h4 id="🙋♀️-객체-타입">🙋‍♀️ 객체 타입</h4>
<p>여기서 <code>전역 객체</code> 알아보자. 
웹 브라우저가 새 페이지를 로드하거나 인터프리터를 시작할 때</p>
<ul>
<li>undefined, infinity, NaN 전역상수 </li>
<li>isNaN(), parseInt(), eval() 전역함수</li>
<li>Date(), RegExp(), String(), Object(), Array() 생성자 함수 </li>
<li>Math, JSON 같은 전역 객체</li>
</ul>
<p>노드에서</p>
<ul>
<li>global 프로퍼티. 이 값이 전역 객체 자체</li>
</ul>
<p>웹 브라우저 </p>
<ul>
<li>window 객체. 모든 자바스크립트 코드의 전역 개체</li>
</ul>
<h4 id="🙋♀️-불변성">🙋‍♀️ 불변성</h4>
<p>기본형 데이터인 숫자, 문자, bool, null, undefined, symbol 모두 불변값. 
불변성 여부를 구분할 떄의 변경가능성의 대상은 <code>데이터영역</code>
<img src="https://velog.velcdn.com/images/getelementby_/post/7b99b497-c72b-4ec1-8263-17f2d7c9c3c5/image.jpeg" alt=""></p>
<pre><code>var a = abc
var c = abc
b = efd</code></pre><ol>
<li><p>컴퓨터는 데이터 영역에서 abc를 찾아본다 &gt;  없네? &gt; 데이터 영역에 abc 생성 &gt; 할당</p>
</li>
<li><p>그 다음 c. c는 데이터 영역에서 abc를 찾았다 &gt; 이 주소를 재활용.</p>
</li>
<li><p>b는? 없네. 1 과정처럼 새로 만들어서 할당한다. 
결국 abc와 edf 모두 다른 값으로 변경할 수 없다.
데이터영역에 저장된 값은 모두 불변하다!</p>
</li>
</ol>
<p>그럼 참조형 데이터는? 참조형 데이터도 사실 데이터 영역은 불변해. 다만 차이가 객체의 변수영역이 또 있어. 그래서 여기 값은 자유롭게 변경 되는거지. </p>
<h4 id="🙋♀️-일치연산자---동등연산자-">🙋‍♀️ 일치연산자 === / 동등연산자 ==</h4>
<p>타입을 엄격하게 규정하는 === 와 다르게 ==의 문제는.  </p>
<pre><code>null == undefined //true
&quot;0&quot; == 0 // true. 비교 전에 문자열을 숫자로 
0 == false // true. 비교 전에 불값을 숫자로
&quot;0&quot; == false // 비교 전 두 피연산자를 모두 0으로</code></pre><h4 id="🙋♀️-명시적으로-타입-변환하려면">🙋‍♀️ 명시적으로 타입 변환하려면?</h4>
<ul>
<li><p>함수
<code>Number()</code>
<code>string()</code>
<code>Boolean()</code></p>
</li>
<li><p>메서드
<code>toString()</code> * null, undefined 제외</p>
</li>
</ul>
<h4 id="변수-선언과-할당-let-const">변수 선언과 할당 let const</h4>
<p>변수 선언시 let, 상수 선언시 const </p>
<ul>
<li>변수 선언시 초기값을 같이 ~</li>
</ul>
<p><code>var</code> 
함수 레벨 스코프 변수를 선언할 때 사용.
함수 외부에서 선언되면 전역범위를 가지고 함수 내부에서 선언되면 함수 외부를 제외한 내부 어디에서든 참조가 가능하다.
var 선언에서 중요한 특징은 <code>호이스팅</code>
변수를 선언하면 이 선언은 맨 위로 끌어올라가짐. 그래서 var로 선언한 변수는 함수 어디에서든 에러 없이 사용 가능.</p>
<p>블록 레벨 스코프를 선언할 수 있는 <code>let</code> <code>const</code>
여기서 블록은 중괄호를 경계로 나눌 수 있는데 자기를 정의한 블록과 하위에서만 접근할 수가 있다. 즉 블록 안에서만 해당 변수와 상수가 유효하다. (if/else문, while문, for 루프)</p>
<ul>
<li>var 는 let과 다르게 여러 번 선언 가능</li>
<li>함수 바디 바깥에서 var를 사용하면 전역 변수로 선언. 전역객체의 프로퍼티로 존재함. (globalthis 참조 가능) 요것이 let가 큰 차이점 ! <pre><code>//같다는 의미~~
globalThis.x =2 ;
var x = 2;</code></pre></li>
</ul>
<h4 id="호이스팅">호이스팅</h4>
<p>선언 라인 전에도 에러가 나지 않고 변수를 참조할 수 있는 현상. 
어떻게 이럴 수 있냐? 
자바스크립트가 실행 전에 코드를 쫙 보고 변수 정보를 기록하거든. 
근데 var는 선언단계에서 메모리 공간을 확보하고 이 식별자에 임의로 값을 연결해둬. 초기화 단계가 같이 있는거지 !!! </p>
<p>반면 let const는 선언만 하게 된다. 초기화(undefind가 없기 때문에)를 안 했기 때문에 유효한 값을 불러올 수 없고 에러 뿜는거임.
선언 라인 전에는 변수를 참조할 수 없다!</p>
<h4 id="분해할당">분해할당</h4>
<p>선언과 할당을 합쳐보쟈</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 완벽가이드 2장을 읽고. (어휘 구조)]]></title>
            <link>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%99%84%EB%B2%BD%EA%B0%80%EC%9D%B4%EB%93%9C-2%EC%9E%A5%EC%9D%84-%EC%9D%BD%EA%B3%A0.-%EC%96%B4%ED%9C%98-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%99%84%EB%B2%BD%EA%B0%80%EC%9D%B4%EB%93%9C-2%EC%9E%A5%EC%9D%84-%EC%9D%BD%EA%B3%A0.-%EC%96%B4%ED%9C%98-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Sat, 07 Jan 2023 06:16:17 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트 어휘 구조 즉 기본적인 규칙에 대해 알아보자. </p>
<ol>
<li>대소문자를 구별한다. </li>
<li>토큰 공백을 무시한다. </li>
<li>대부분의 경우 줄바꿈은 무시한다. </li>
</ol>
<h3>주석</h3>
<h3>리터럴</h3>
프로그램 안에 직접 쓴 데이터 값. 문자열, 숫자, 불리언, null.. 도우 리터럴이다.
<h3>식별자와 예약어</h3>
`식별자` : 식별자. 즉 이름으로 자바스크립트에서 `상수`, `변수`, `프로퍼티`, `함수`, `클래스` 의 이름에 사용한다. 

<p><code>예약어</code>: 특정 식별자를 언어 자체에서 사용하도록 예약한 것.
if, while, for. 등 
let 같은 경우엔 복잡한 규칙이 존재하니 그냥 쓰지마. 
from, set, target은 사용 가능.</p>
<h3>유니코드</h3>
유니코드는 문자나 기호, 숫자에 대응되는 코드로 이루어진 데이터베이스라고 생각할 수 있다. 

<h3>세미클론</h3>
세미클론을 생략해도 되는 순간 

<ul>
<li>두 문 사이에 줄바꿈이 있다면.정확히는 줄바꿈 다음에 오는 공백이 아닌 문자를 현재문에 이어진다고 판단할 수 없다면 줄바꿈을 세미클론으로 취급한다. </li>
</ul>
<pre><code>//생략 가능
a = 3
b = 2

//생략 불가
a = 3; b = 2;
</code></pre><ul>
<li>프로그램의 끝.</li>
<li>토큰이 닫는 중괄호일 때도. </li>
</ul>
<h4 id="위에-말에-이어-줄바꿈을-세미클론으로-해석한다는-규칙에-세-가지-예외">위에 말에 이어 줄바꿈을 세미클론으로 해석한다는 규칙에 세 가지 예외</h4>
<ol>
<li>return throw, yield, break, continue 사이에 줄바꿈이 일어나면 무조건 세미클론으로 해석한다. </li>
</ol>
<pre><code>//return; true; 로 해석해버림
return 
true;</code></pre><ol start="2">
<li><p>++ -- 연산자. 
후위 연산자로 사용한다면 반드시 적용할 표현식과 같은 행에 쓰자.</p>
</li>
<li><p>화살표 함수는 반드시 매개변수 리스트와 같은 행이 쓰자. </p>
</li>
</ol>
<p>일반적으로 문이 <code>( [ / +</code> 로 시작한다면 그 문은 이전 문이 계속되는 것으로 해석될 가능이 있으니까. 방어적인 목적으로 세미콜론을 알문에 붙여주거나 해야한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 완벽가이드 1장을 읽고. ]]></title>
            <link>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%99%84%EB%B2%BD%EA%B0%80%EC%9D%B4%EB%93%9C-1%EC%9E%A5%EC%9D%84-%EC%9D%BD%EA%B3%A0</link>
            <guid>https://velog.io/@getelementby_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%99%84%EB%B2%BD%EA%B0%80%EC%9D%B4%EB%93%9C-1%EC%9E%A5%EC%9D%84-%EC%9D%BD%EA%B3%A0</guid>
            <pubDate>Sat, 07 Jan 2023 05:13:09 GMT</pubDate>
            <description><![CDATA[<h3>간단 소개</h3>
자바스크립트에서 입출력, 네트워크, 스토리지와 같은 발전된 기능은 자바스크립트가 입베드된 '호스트 환경'이 담당한다.
자바스크립 호스트 환경 은 웹 브라우저 > 노드 로 넘어오게 되면서 자바스크립트가 웹 브라우저 API에서 벗어나 운영 체제 전체에 접근해 파일을 읽고 쓰고 네트워크 통해 데이터 송수신, HTTP요청을 보내고 받을 수 있게 됐다. 




<h3>단어 사전</h3>
인터프리터 / 컴파일러 언어 모두 프로그래머가 작성한 프로그래밍 언어를 기계어로 번역하는 건 같다. 다만

<p><code>인터프리터 언어(스크립트 언어)</code>: 기계어로 바로 번역하지 않고 대충 중간 형태로 만든 다음 코드를 한 줄씩 읽어서 실행하는 언어. 컴파일 단계가 따로 없어서 컴파일 시간(번역 시간)이 소요되진 않지만 실행할 때마다 과정을 반복적으로 하여 실행 속도가 느리다.</p>
<p><code>컴파일러 언어</code>: 모든 코드를 한 번에 컴파일(번역) 한다. 그래서 컴파일 시간이 좀 걸릴 수 있어도 실행 속도는 빠르다. </p>
<p><code>컴파일</code>
개발자가 작성한 코드가 기계어로 바뀌어 실행 가능한 프로그램이 되는 과정
정적 타입 언어는 이 단계에서 오류를 발견한다.</p>
<p><code>런타임</code>
컴파일 된 프로그램을 사용자가 실행하는 과정
동적 타입 언어는 이 단계에서 오류를 발견한다.</p>
<p>오류를 발견하는 과정을 지켜보면 정적 다입의 언어가 동적 타입 언어보다 빨리 오류를 발견한다. 그리고 프로그램이 실행된 후에 발견된 오류는 이전에 발견된 오류보다(컴파일 오류) 찾기가 쉽지 않다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[런타임 컴파일]]></title>
            <link>https://velog.io/@getelementby_/%EB%9F%B0%ED%83%80%EC%9E%84-%EC%BB%B4%ED%8C%8C%EC%9D%BC</link>
            <guid>https://velog.io/@getelementby_/%EB%9F%B0%ED%83%80%EC%9E%84-%EC%BB%B4%ED%8C%8C%EC%9D%BC</guid>
            <pubDate>Sun, 07 Aug 2022 12:23:50 GMT</pubDate>
            <description><![CDATA[<p>런타임 오류
프로그램이 동작할 때 발견하는 것. 즉 사용자가 쓸 떼. </p>
<p>컴파일 오류
코드가 컴파일 될 때 타입 오류를 잡아줄 수 있도록 타입스크립트를 사용한다. 
코드가 컴파일 될 때 컴파일러가 해석되지 못해서 발생</p>
<p>런타임 환경에서의 에러.
로그인이 실패했으니. 다른 걸 해봐라. 서비스에 대한 부정적인 경험을 막아라. </p>
<p>try catch. 
finally 로직 성공 * 실패 여부와 상관 없이 실행 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[얕복 깊복]]></title>
            <link>https://velog.io/@getelementby_/%EC%96%95%EB%B3%B5-%EA%B9%8A%EB%B3%B5</link>
            <guid>https://velog.io/@getelementby_/%EC%96%95%EB%B3%B5-%EA%B9%8A%EB%B3%B5</guid>
            <pubDate>Sun, 07 Aug 2022 06:46:01 GMT</pubDate>
            <description><![CDATA[<pre><code>//얕복 케이스
const a = [{name: jonny, age: 10}];
const clone = [...a];
clone[0].name = &#39;greenwood&#39;;

console.log(a); // name: greenwood....

//깁복 케이스
const a = {name: jonny, age: 10};
const clone = [...a];
clone.name = &#39;greenwood&#39;;

console.log(a); // name: jonny;
console.log(clone); // name: greenwood;
</code></pre><p>1번 케이스의 경우 배열안에 중첩된 객체를 가지고 있다. 
얕은 복사는 데이터가 중첩된 것은 복사하지 않고 가장 상위의 객체만 복사한다. 즉 원본 객체와 같은 메모리를 참조한다는 것..
그래서 원본도 변함</p>
<p>그러나 그냥 객체의 경우 상위 객체 뿐만 아니라 중첩된 객체까지 다 복사를 그렇기 때문에 원본가 다른 메모리가 생성 그래서 충돌 안 나는 것.</p>
<p>전개 연산자 혹은 assign()은 위와 같이 댐.</p>
<p>그러나 JSON.parse는 중첩과 상관없이 무조건 깊은 복사.</p>
]]></description>
        </item>
    </channel>
</rss>