<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>DogFoot.log</title>
        <link>https://velog.io/</link>
        <description>프론트 개발자 김용민입니다.</description>
        <lastBuildDate>Sat, 22 Feb 2025 10:23:10 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>DogFoot.log</title>
            <url>https://velog.velcdn.com/images/k_y/profile/d61cd912-2149-4fb1-90e4-b72fbd0f46b7/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. DogFoot.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/k_y" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[any와 unknown 무엇이 다른가?]]></title>
            <link>https://velog.io/@k_y/any%EC%99%80-unknown-%EB%AC%B4%EC%97%87%EC%9D%B4-%EB%8B%A4%EB%A5%B8%EA%B0%80</link>
            <guid>https://velog.io/@k_y/any%EC%99%80-unknown-%EB%AC%B4%EC%97%87%EC%9D%B4-%EB%8B%A4%EB%A5%B8%EA%B0%80</guid>
            <pubDate>Sat, 22 Feb 2025 10:23:10 GMT</pubDate>
            <description><![CDATA[<p>오늘은 타입스크립트를 사용하면서 한 번쯤 고민 해봤을 <code>any</code>와 <code>unknown</code>의 차이점에 대해 적어보려고 한다.</p>
<p>처음에 타입스크립트를 접하게되면 <code>any</code>를 편하게 사용하는 경우를 자주 봤었다.
나또한 <code>any</code>를 둘의 차이점을 이해하지 못한채 <code>any</code>를 자주 사용했던 거 같다.</p>
<p>그러다가 문뜩 <strong>정말 이게 맞을까?</strong> 라는 고민이 들기 시작했다.
<img src="https://velog.velcdn.com/images/k_y/post/aab9f056-fea3-4aa6-bd96-395f2ed918f1/image.png" alt=""></p>
<p>그래서 <code>unknown</code>과 어떤 차이가 있고, 언제 어떤 타입을 써야 더 안전한 코드를 만들 수 있을지 고민하게된 내용들을 공유하려고 한다.</p>
<h2 id="any와-unknown의-차이점">any와 unknown의 차이점</h2>
<p>타입스큽리트에서 <code>any</code>와 <code>unknown</code>은 모두 <strong>어떤 타입이든 될 수 있는</strong> 타입이다.
하지만 실제로는 큰 차이가 있는데 같이 자세하게 알아보자.</p>
<p><img src="https://velog.velcdn.com/images/k_y/post/35404da4-4875-403f-a2c3-30c16f0d4153/image.png" alt=""></p>
<h3 id="--any">- any</h3>
<p><code>any</code>는 어떤 값이든 허용하므로 타입 검사를 우회한다.</p>
<pre><code class="language-ts">let value: any;
value = &quot;hello&quot;;
value = 42;
value.toUpperCase(); // 런타임 오류 없음</code></pre>
<p>이처럼 <code>any</code>를 사용하면 편리하지만, 예상치 못한 런타입 오류가 발생할 가능성이 크다.</p>
<h3 id="--unknown">- unknown</h3>
<p><code>unknown</code>은 <code>any</code>처럼 모든 타입을 받을 수 있지만, <strong>사용하기 전에 타입 검사</strong>가 필요합니다</p>
<pre><code class="language-ts">let value: unknown;
value = &quot;hello&quot;;
value = 42;

if(typeof value === &quot;string&quot;) {
    value.toUpperCase();
}</code></pre>
<p>이처럼 <code>unknown</code>은 <strong>무분별한 사용을 막고 타입 검사를 강제</strong>하여 안전한 코드를 작성하도록 도움을 준다.</p>
<h2 id="언제-any와-unknown을-사용할까">언제 any와 unknown을 사용할까?</h2>
<p>✅<code>any</code>는 정말 어쩔 수 없는 경우에만 사용을 해야한다. (ex. 외부 라이브러리 데이터)
✅<code>unknown</code>은 타입이 확실하지 않지만, 검사를 거쳐 안전하게 사용할 때 활용하면 된다.</p>
<p><img src="https://velog.velcdn.com/images/k_y/post/d8827e15-3b7d-4136-9dab-50e7d80634d0/image.png" alt=""></p>
<p>이번 글에서는 <code>any</code>와 <code>unknown</code>에 차이점에 대해서 적어보았다.
<code>any</code>는 유연하지만 위험할 수 있고, <code>unknown</code>은 안전하지만 타입 검사가 필요하다는 점이 핵심이었다.</p>
<p>앞으로 타입스크립트를 사용할 때는 무분별하게 <code>any</code>를 사용하는 것보다는 <code>unknown</code>을 고려해보는 습관을 가지면 더욱 안전한 코드를 작성할 수 있을 거 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[테스트 코드는 왜 만들어야할까 ?]]></title>
            <link>https://velog.io/@k_y/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C%EB%8A%94-%EC%99%9C-%EB%A7%8C%EB%93%A4%EC%96%B4%EC%95%BC%ED%95%A0%EA%B9%8C</link>
            <guid>https://velog.io/@k_y/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C%EB%8A%94-%EC%99%9C-%EB%A7%8C%EB%93%A4%EC%96%B4%EC%95%BC%ED%95%A0%EA%B9%8C</guid>
            <pubDate>Mon, 22 Apr 2024 16:29:28 GMT</pubDate>
            <description><![CDATA[<p>오늘은 테스트 코드에 대해서 적어보려고 한다.</p>
<p>사실 나는 처음에 테스트 코드를 왜 작성해야하는지 잘 이해가 되지 않았었다.</p>
<p>하지만 여러 기업들에서 테스트 코드를 작성해본 사람들을 찾는 것을 목격하게 되었고, 기업들에서 원하는 이유가 있을 것이라고 생각이 들어 왜 중요한지에 대해서 찾아보기 시작하였다.</p>
<p>그러면서 내가 가지고 있던 생각들과 사용하던 방식이 잘못 되었다는 것을 깨닫게 되었다.
이제는 내가 테스트 코드를 사용하면서 느꼈던 점과 찾아본 내용들을 공유 해보려고 한다 !!</p>
<p><img src="https://velog.velcdn.com/images/k_y/post/b15052ae-9ec4-4791-b736-a06da36661b4/image.png" alt=""></p>
<h2 id="테스트-코드란-무엇일까">테스트 코드란 무엇일까</h2>
<p>테스트 코드란 개발자가 작성한 실제 코드의 기능과 동작을 체계적으로 검증하기 위해 별도로 작성하는 코드를 말한다.</p>
<p>개발자는 특정 기능을 구현한 후 해당 기능이 의도한 대로 정상적으로 동작하는지 확인해야 한다. 이때 수동으로 일일이 테스트하는 것은 비효율적이며, 사람의 실수로 인해 누락되는 경우가 많다. 이러한 문제를 해결하기 위해 테스트 코드를 작성하는 것이다.</p>
<h2 id="테스트-코드는-왜-만들어야할까-">테스트 코드는 왜 만들어야할까 ?</h2>
<h3 id="1-무엇을-만들고-있는지-확실하게-파악한다">1. 무엇을 만들고 있는지 확실하게 파악한다.</h3>
<p><img src="https://velog.velcdn.com/images/k_y/post/d05576e0-5a6c-459a-85aa-998c13467525/image.png" alt=""></p>
<p>개발자는 요구사항을 분석하여 설계한 후 구현하는 일을 하게 된다.
하지만 요구사항을 확실하게 구현했는지를 아는 것은 쉬운 일이 아니다.
그렇기에 테스트 코드를 작성하며 요구사항들을 다시 한 번 확인하고 정리하며 완성도를 높일 수 있다.</p>
<h3 id="2-디버깅에-투자되는-시간이-줄어든다">2. 디버깅에 투자되는 시간이 줄어든다.</h3>
<p><img src="https://velog.velcdn.com/images/k_y/post/6466d08a-d6e7-493b-9579-4a4332b223f2/image.png" alt=""></p>
<p>테스트 코드를 사용하지 않는 경우에는 버그와 이슈들을 디버깅할 때 많은 시간을 투자하였다.
실제로 문제를 해결하는 것은 얼마 걸리지 않은 경우가 더욱 많았었다.</p>
<p>하지만 테스트 코드를 적용하면서 버그들을 줄이게 되었고, 여러 케이스들에 대해서 빠르게 접근이 가능해지며 디버깅에 투자되는 시간들이 눈에 띄게 줄어들게 되었다.</p>
<h3 id="3-코드-변경에-두려움이-없어진다">3. 코드 변경에 두려움이 없어진다.</h3>
<p><img src="https://velog.velcdn.com/images/k_y/post/9d72350e-a397-4add-9b10-a954a88c4645/image.png" alt=""></p>
<p>테스트 코드가 없는 프로젝트에서는 기능 추가/수정 작업에 큰 어려움이 있다.
기존 기능을 수정하게 될 시에는 초기 요구사항과 예외 케이스를 명확히 파악하는게 어렵다.
또한 기능은 여러 요소의 상호작용으로 이루어져 있어, 하나의 기능 수정 시 의도치 않게 다른 기능에 영향을 미치고 회귀 버그가 발생할 수 있다.</p>
<p>여러가지 이슈들을 해결하기 위해서는 테스트 코드가 중요한 역할을 한다.
회귀 버그를 완전히 없애는 건 불가능하지만 회귀 테스트를 통해 대처하고 관리할 수 있다.
그리고 기존에 구현된 기능들이 새로운 변경사항에 의해 영향을 받지 않았는지를 검증 할 수 있기에 코드 변경에 대한 두려움을 없앨 수가 있다.</p>
<h3 id="4-좋은-문서-자료로-사용이-된다">4. 좋은 문서 자료로 사용이 된다.</h3>
<p>테스트 코드는 문서로서도 중요한 역할을 한다.
다른 개발자가 작업을 하게 되었을 때, 막연하게 코드만 보는 것보다 테스트 코드를 보면서 어떤 프로세스로 구성되어 있는지를 이해하게 된다면 더욱 수월하게 업무를 진행할 수 있다.</p>
<p>또한, 기존 문서의 가장 큰 문제점은 코드는 수정되었지만 문서는 수정되지 않아 방치되는 경우가 많았습니다. 이렇게 되면 문서 자료의 신뢰성이 떨어지게 된다.</p>
<p>하지만 테스트 코드를 작성할 때는 먼저 명세를 작성하고, 코드의 실제 동작을 기술한다. 이를 통해 해당 코드가 어떤 역할을 가지고 있는지 이해할 수 있게한다.</p>
<p><img src="https://velog.velcdn.com/images/k_y/post/56ba1c4b-0223-4c6d-a6f1-338642dbe887/image.png" alt=""></p>
<p>결과적으로 테스트 코드는 다른 개발자의 코드 이해를 돕는 문서의 역할을 할 수 있다.</p>
<h3 id="5-좋은-코드를-작성하게-된다">5. 좋은 코드를 작성하게 된다.</h3>
<p>테스트 코드를 작성하는 과정에서 개발자는 자연스럽게 더 좋은 코드를 작성하게 된다.
우선 테스트 코드를 작성하기 위해서는 코드의 결합도와 의존성이 낮아야한다.
높은 결합도와 의존성을 가진 코드는 테스트하기 어렵기 때문이다.
따라서 개발자는 테스트 가능한 코드를 작성하기 위해 노력하게 되고, 이는 자연스럽게 낮은 결합도와 의존성을 지향하는 좋은 코드로 이어지게 된다.</p>
<p><img src="https://velog.velcdn.com/images/k_y/post/fa7ffeb5-2214-4f66-b772-9371f75be97f/image.png" alt=""></p>
<p>또한 테스트 코드가 있다면 리팩토링을 진행할 때 부담이 줄어든다.
기존 기능이 정상적으로 동작하는지 테스트 케이스로 검증을 할 수 있기 때문에 안심하고 코드를 리팩토링 할 수 있따. 이를 통해 코드의 질을 지속적으로 개선하며 좋은 코드를 작성하게 될 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React Query를 쓰면 꼭 봐야하는 v5 주요 변경사항 !!]]></title>
            <link>https://velog.io/@k_y/React-Query%EB%A5%BC-%EC%93%B0%EB%A9%B4-%EA%BC%AD-%EB%B4%90%EC%95%BC%ED%95%98%EB%8A%94-v5-%EC%A3%BC%EC%9A%94-%EB%B3%80%EA%B2%BD%EC%82%AC%ED%95%AD</link>
            <guid>https://velog.io/@k_y/React-Query%EB%A5%BC-%EC%93%B0%EB%A9%B4-%EA%BC%AD-%EB%B4%90%EC%95%BC%ED%95%98%EB%8A%94-v5-%EC%A3%BC%EC%9A%94-%EB%B3%80%EA%B2%BD%EC%82%AC%ED%95%AD</guid>
            <pubDate>Sun, 24 Mar 2024 08:15:40 GMT</pubDate>
            <description><![CDATA[<p>오늘은 TanStack Query v5에 주요 변경 및 개선 사항들에 정리하며 적어보려고 한다.
일단 v5 버전에서는 기존 v4에 비해서 크기를 20%로 줄이고, API 간소화에 신경을 썼다고 한다.
또한 타입스크립트 최소 요구 버전이 4.7로 변경되었다.</p>
<p>이제 변경된 핵심 내용들을 알아보자</p>
<h3 id="하나의-함수-호출-객체-형식만을-지원">하나의 함수 호출 (객체 형식)만을 지원</h3>
<p>v5에서는 옵션들이 정의된 <strong>단일 객체</strong>를 받아서 실행하게 됩니다.</p>
<pre><code class="language-ts">+ useQuery({ queryKey, queryFn, ...options })
+ useInfiniteQuery({ queryKey, queryFn, ...options })
+ useMutation({ mutationFn, ...options })
+ useIsFetching({ queryKey, ...filters })
+ useIsMutating({ mutationKey, ...filters })</code></pre>
<p>useQuery, useInfiniteQuery 등 함수들은 타입스크립트에서 많은 오버로드를 가지곤 했습니다. 
이는 타입을 잘 유지하기 어려웠을 뿐만 아니라, option을 올바르게 생성하기 위해 첫 번째 또는 두 번째 매개변수가 어떤 타입인지 확인하는 런타임 검사도 필요했습니다.
또한 일관성이 떨어지며, 사용 방식이 달라 협업을 하는 방식도 정해야하기에 <strong>단일 객체를 전달 받아 처리하는 방식</strong>으로 변경 되었습니다.</p>
<pre><code class="language-ts">// 아래와 같은 사용방식을은 없어졌습니다 !!
- useQuery(queryKey, fn, options)
- useQuery(queryKey, options);
- useQuery(options);
- useInfiniteQuery(queryKey, fn, options)
- useMutation(fn, options)
- useIsFetching(queryKey, filters)
- useIsMutating(queryKey, filters)</code></pre>
<h3 id="suspense">Suspense</h3>
<p>v5부터는 안정적으로 suspense를 사용해 데이터 패칭을 할 수 있습니다. 
useQuery에서 사용되던 suspense: boolean 옵션은 제거되었습니다.
이제는 새로 추가된 useSuspenseQuery, useSuspenseInfiniteQuery와 useSuspenseQueries를 사용합니다.</p>
<pre><code class="language-ts">const { data: post } = useSuspenseQuery({
  queryKey: [&#39;post&#39;, postId],
  queryFn: () =&gt; fetchPost(postId),
})</code></pre>
<h3 id="usemutationstate">useMutationState</h3>
<p>useMutationState은 MutationCache에 있는 mutation 상태를 공유하고, 다른 컴포넌트에서 접근이 가능하도록 합니다.
filters 옵션을 통하여 mutation을 필터링하고, select 옵션으로 상태 값을 가공하거나 선택 할 수 있습니다.</p>
<pre><code class="language-ts">const variables = useMutationState({
    filters: { status: &#39;pending&#39; },
      select: (mutation) =&gt; mutation.state.variables,
});</code></pre>
<pre><code class="language-ts">const mutationKey = [&#39;posts&#39;];
const mutation = useMutation({
  mutationKey,
  mutationFn: (values) =&gt; {
      return axios.post(`/posts`, values)
  },
});

const data = useMutationState({
  filters: { mutationKey },
  select: (mutation) =&gt; mutation.state.data,
});</code></pre>
<h3 id="usequery-remove-제거">useQuery remove 제거</h3>
<p><strong>remove</strong> 메서드는 queryCache에서 query를 제거할 때 관찰자에게 알리지 않고 제거 할 수 있는 방식이었습니다.</p>
<p>하지만 query 상태가 <strong>active</strong>일 경우에는 <strong>remove</strong> 메서드의 행위는 잘못 되었다고 합니다.
왜냐하면 쿼리를 제거한 다음 렌더에서 새로운 로딩 상태로 이어지기 때문에 활성화 되어있는 쿼리를 제거하면 안된다고 합니다.</p>
<p>그렇기에 이제부터 query를 제거하기 위해서는 <strong>queryClient.removeQueries</strong>({ queryKey })를 사용해야 합니다.</p>
<pre><code class="language-ts">const queryClient = useQueryClient();
const query = useQuery({ queryKey, queryFn });

queryClient.removeQueries({ queryKey });</code></pre>
<h3 id="cachetime-→-gctime-으로-변경">cacheTime → gcTime 으로 변경</h3>
<p><strong>gc</strong>는 <strong>garbage collecting</strong>의 약어로 기술적으로 더욱 적합한 표현인 <strong>gcTime</strong>으로 변경됩니다.</p>
<p>기존 <strong>cacheTime</strong>은 데이터가 캐시되는 시간을 표현한 것이라고 이해가 되는데, 
이건 잘못된 이해이며 해당 값은 query가 사용되지 않는 경우에 시간에 대해서 표현한 것입니다.</p>
<pre><code class="language-ts">const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      gcTime: 10
    },
  },
})</code></pre>
<h3 id="에러-기본-타입이-unknown-→-error-로-변경">에러 기본 타입이 unknown → Error 로 변경</h3>
<p>이제 에러의 <strong>기본 타입은 Error</strong> 입니다.</p>
<pre><code class="language-ts">const { error } = useQuery({
  queryKey: [&quot;posts&quot;],
  queryFn: axios.get(`/posts`)
});</code></pre>
<h3 id="loading-→-pending-으로-변경">Loading → Pending 으로 변경</h3>
<blockquote>
<p><strong>status: loading</strong> → <strong>status: pending</strong>
<strong>isLoading</strong> → <strong>isPending</strong>
<strong>isInitialLoading</strong> → <strong>isLoading</strong></p>
</blockquote>
<p><strong>loading</strong> 상태의 이름이 <strong>pending</strong>으로 변경 되었다.</p>
<h3 id="hydration-api">Hydration API</h3>
<p><strong>Hydrate</strong> 는 <strong>HydrationBoundary</strong> 로 이름이 변경 되며, <strong>useHydrate</strong> 훅은 제거 되었다. </p>
<h3 id="useerrorboundary-→-throwonerror">useErrorBoundary → throwOnError</h3>
<p>특정 프레임워크에 종속되지 않으면서 React의 훅 접두사인 &quot;use&quot;와 &quot;ErrorBoundary&quot; 컴포넌트명과 혼동을 피하기 위하여 이름을 변경하였다고 한다.</p>
<p><img src="https://velog.velcdn.com/images/k_y/post/dd9c9509-e763-4a35-a5ef-8ee1ed37a920/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React 개발자라면 알아야 할 React19 소식]]></title>
            <link>https://velog.io/@k_y/React-19-%EC%86%8C%EC%8B%9D</link>
            <guid>https://velog.io/@k_y/React-19-%EC%86%8C%EC%8B%9D</guid>
            <pubDate>Sun, 03 Mar 2024 06:26:57 GMT</pubDate>
            <description><![CDATA[<p>오늘은 <strong>React 19</strong> 버전에 대한 소식을 공유 해보려고 한다.</p>
<p><img src="https://velog.velcdn.com/images/k_y/post/fdcb086c-8c5d-4258-891f-19874e8e6f44/image.png" alt=""></p>
<p>React를 개발하는 개발자들은 꼭 알아야할 정보라고 생각이된다.
최신버전에 대하여 알고 있어야지 무엇이 추가되었고, 변경되었는지를 파악할 수 있고,  앞으로 성장을 어떻게 해야할지도 생각할 수 있게 된다고 생각한다.</p>
<p>현재 <strong>React 19</strong>는 출시를 위해서 준비 작업들을 진행하고 있다고 한다.</p>
<p>관련된 내용들을 자세하게 다뤄보겠다.</p>
<h2 id="1-react-컴파일러">1. React 컴파일러</h2>
<p>React를 위한 컴파일러를 개발이며 오픈소스로 출시를 준비하고 있다고 한다.
또한 <strong>useMemo</strong>, <strong>useCallback</strong> 자동 최적화가 적용된다고 한다.</p>
<h2 id="2-새로운-client-side-hooks">2. 새로운 client-side hooks</h2>
<h3 id="--usepromise--">- use(Promise) -</h3>
<p>이 새로운 훅은 클라이언트에서 중단하는 공식 API입니다. 
프라미스를 전달하면 React가 해결될 때까지 이를 중단합니다. 
이 훅을 데이터 가져오기에 사용할 수 있습니다.</p>
<pre><code class="language-ts">import { use } from &#39;react&#39;;

function MessageComponent({ messagePromise }) {
    const message = use(messagePromise);
    // ...
}</code></pre>
<p>React 문서에서 <a href="https://react.dev/reference/react/use">use(Promise)</a>에 대해 자세히 확인할 수 있습니다.</p>
<h3 id="--usecontext--">- use(Context) -</h3>
<p>이 훅은 React 컨텍스트를 읽는 데 사용됩니다. 
useContext와 유사하지만 루프 및 조건문 내에서 호출할 수 있습니다.</p>
<pre><code class="language-ts">import { use } from &#39;react&#39;;

function HorizontalRule({ show }) {
    if (show) {
        const theme = use(ThemeContext);
        return &lt;hr className={theme} /&gt;;
    }
    return false;
}</code></pre>
<p>React 문서에서 <a href="https://react.dev/reference/react/use">use(Context)</a>에 대해 자세히 확인할 수 있습니다.</p>
<h3 id="--form-actions--">- Form actions -</h3>
<p>이 새로운 기능을 사용하여 <strong>form</strong> 태그의 action prop에 함수를 전달할 수 있습니다.</p>
<pre><code class="language-tsx">&lt;form action={handleSubmit} /&gt; // form 태그 함수 전달</code></pre>
<p><strong>useFormState</strong> 훅은 비동기 폼 액션 기능을 지원합니다.</p>
<pre><code class="language-ts">// useFormState
import { useFormState } from &#39;react-dom&#39;;
import { action } from &#39;./action&#39;;

function MyComponent() {
    const [state, formAction] = useFormState(action, null);
    // ...
    return &lt;form action={formAction}&gt;{/* ... */}&lt;/form&gt;;
}</code></pre>
<p>React 문서에서 <a href="https://react.dev/reference/react-dom/hooks/useFormState">useFormState</a>에 대해 자세히 확인할 수 있습니다.</p>
<p><strong>useFormStatus</strong> 훅은 부모 form 태그의 현재 제출 중인지 또는 성공적으로 제출되었는지 여부를 알려줍니다.</p>
<pre><code class="language-ts">// useFormStatus
const { pending, data, method, action } = useFormStatus();</code></pre>
<p>React 문서에서 <a href="https://react.dev/reference/react-dom/hooks/useFormStatus">useFormStatus</a>에 대해 자세히 확인할 수 있습니다.</p>
<p>Form actions 관련 Hook들이 추가되었다고 하더라도 <strong>React-Hook-Form</strong>을 <strong>제거</strong>하기에는 <strong>충분하지 않을 수 있다</strong>고 생각을 한다.
하지만 추가적으로 라이브러리를 설치하지 않고 <strong>검색 처리를 크게 단순화</strong> 시킬 수 있다는건 상당히 큰 이점으로 다가올 것이라고 생각한다.</p>
<h3 id="--useoptimistic--">- useOptimistic -</h3>
<p>이 훅을 사용하여 작업이 제출되는 동안 최적화된 방식으로 사용자 인터페이스를 업데이트할 수 있습니다.</p>
<pre><code class="language-ts">import { useOptimistic } from &#39;react&#39;;

function AppContainer() {
    const [optimisticState, addOptimistic] = useOptimistic(
        state,
        // updateFn
        (currentState, optimisticValue) =&gt; {
            // merge and return new state
            // with optimistic value
        },
    );
}</code></pre>
<p>React 문서에서 <a href="https://react.dev/reference/react/useOptimistic">useOptimistic</a>에 대해 자세히 확인할 수 있습니다.</p>
<p>추가적으로 자세한 내용들을 보고 싶다면 <a href="https://react.dev/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024">React Labs</a>를 방문하여 읽어보는 것을 추천드립니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트 개발자가 보면 좋은 메일링 서비스]]></title>
            <link>https://velog.io/@k_y/%ED%94%84%EB%A1%A0%ED%8A%B8-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%B3%B4%EB%A9%B4-%EC%A2%8B%EC%9D%80-%EB%A9%94%EC%9D%BC%EB%A7%81-%EC%84%9C%EB%B9%84%EC%8A%A4</link>
            <guid>https://velog.io/@k_y/%ED%94%84%EB%A1%A0%ED%8A%B8-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%B3%B4%EB%A9%B4-%EC%A2%8B%EC%9D%80-%EB%A9%94%EC%9D%BC%EB%A7%81-%EC%84%9C%EB%B9%84%EC%8A%A4</guid>
            <pubDate>Sun, 18 Feb 2024 15:12:37 GMT</pubDate>
            <description><![CDATA[<h4 id="오늘은-프론트-개발자들에게-도움이-되는-메일링-시스템들을-공유해보려고-한다">오늘은 프론트 개발자들에게 도움이 되는 메일링 시스템들을 공유해보려고 한다.</h4>
<p>빠르게 변화하는 프론트엔드 개발에 뒤쳐지지 않기 위해서 메일링 시스템을 통해 트렌드를 파악하며 성장 하는 것이 좋다고 생각한다.</p>
<h4 id="korean-fe-article---httpskofearticlesubstackcomabout">Korean FE article - <a href="https://kofearticle.substack.com/about">https://kofearticle.substack.com/about</a></h4>
<p>첫 번째로 추천하고 싶은 메일링 서비스는 <code>Korean FE article</code> 이다.
매주 해외 커뮤니티에서 인기 있었던 내용들을 한국어로 번역 해주어 편하게 트렌드를 파악할 수 있다.
<img src="https://velog.velcdn.com/images/k_y/post/10d7dfee-1d4e-4789-80fd-1c3e42ef1ec3/image.png" alt=""></p>
<h4 id="react-status---httpsreactstatuscodecom">React Status - <a href="https://react.statuscode.com">https://react.statuscode.com</a></h4>
<p>두 번째로 추천하고 싶은 메일링 서비스는 <code>React Status</code> 이다.
매주 목요일 Cooper Press에서 제공하는 <code>React</code>와 <code>ReactNative</code> 관련 소식을 받아볼 수 있는 서비스이다.
<img src="https://velog.velcdn.com/images/k_y/post/df2dd5ff-b4b4-484a-9d9d-f89cfdd890a2/image.png" alt=""></p>
<h4 id="javascript-weekly---httpsjavascriptweeklycom">JavaScript Weekly - <a href="https://javascriptweekly.com">https://javascriptweekly.com</a></h4>
<p>세 번째로 추천하고 싶은 메일링 서비스는 <code>JavaScript Weekly</code> 이다.
매주 금요일 Cooper Press에서 제공하는 <code>JavaScript</code> 관련 소식들을 받아볼 수 있는 서비스이다.
<img src="https://velog.velcdn.com/images/k_y/post/13485178-e0af-4063-965a-9d250b029347/image.png" alt=""></p>
<h4 id="노마드-뉴스레터---httpsnomadcodersus16list-managecomsubscribeua99b43453db5050f1f26b2744id4313d957c9">노마드 뉴스레터 - <a href="https://nomadcoders.us16.list-manage.com/subscribe?u=a99b43453db5050f1f26b2744&amp;id=4313d957c9">https://nomadcoders.us16.list-manage.com/subscribe?u=a99b43453db5050f1f26b2744&amp;id=4313d957c9</a></h4>
<p>네 번째로 추천하고 싶은 메일링 서비스는 <code>노마드 뉴스레터</code> 이다.
매주 금요일 최신 개발 뉴스, IT 이슈와 같이 개발자 성장에 도움이 되는 정보들을 보내주는 서비스이다.
추가적으로 AI 소식, 사이드프로젝트, UIUX, 서비스기획 등의 주제도 다루고 있어 여러 방향으로 성장을 원하는 사람에게는 더 좋은 서비스가 될 것 같다.
<img src="https://velog.velcdn.com/images/k_y/post/599f26b7-457d-46f6-9e24-5a0a9a59bc5d/image.png" alt=""></p>
<h4 id="우아한테크-뉴스레터---httpsdocsgooglecomformsde1faipqlse5hmoawj5-lsjcolvf5btxwwr7d_uzxychkwse1bgqs58c4wviewform">우아한테크 뉴스레터 - <a href="https://docs.google.com/forms/d/e/1FAIpQLSe5HMoawj5-lsjcOLvF5BtxWWr7D_uZXYChkWse1bgQs58C4w/viewform">https://docs.google.com/forms/d/e/1FAIpQLSe5HMoawj5-lsjcOLvF5BtxWWr7D_uZXYChkWse1bgQs58C4w/viewform</a></h4>
<p>마지막으로 추천하고 싶은 메일링 서비스는 <code>우아한테크 뉴스레터</code> 이다.
매달 우아한형제들의 개발 및 기술 관련 소식, 우아한테크 세미나와 콘퍼런스, 개발자 교육 프로그램 등 소식을 받아볼 수 있는 서비스이다.
<img src="https://velog.velcdn.com/images/k_y/post/2bfb801d-b80b-4391-a467-f45b2d3bf85f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[블록체인 관련 기본지식]]></title>
            <link>https://velog.io/@k_y/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EA%B4%80%EB%A0%A8-%EA%B8%B0%EB%B3%B8%EC%A7%80%EC%8B%9D</link>
            <guid>https://velog.io/@k_y/%EB%B8%94%EB%A1%9D%EC%B2%B4%EC%9D%B8-%EA%B4%80%EB%A0%A8-%EA%B8%B0%EB%B3%B8%EC%A7%80%EC%8B%9D</guid>
            <pubDate>Sun, 04 Feb 2024 10:06:04 GMT</pubDate>
            <description><![CDATA[<p>내가 이번에 취업한 회사는 블록체인 거래소 회사이다.
그렇기에 회사에서 블록체인 관련된 용어들이 자주 나오고 있다.
하지만 나는 블록체인 용어에 대해서 잘 모르고 있기에 업무에 효율이 떨어지는 것을 느끼게 되었다.
그래서 관련 지식들을 찾아보고 정리 해보려고 한다.</p>
<h3 id="블록체인이란-무엇인가-">블록체인이란 무엇인가 ?</h3>
<p>블록체인은 분산된 컴퓨터 네트워크에서 공유되는 블록이라 불리는 데이터 단위로 구성된다.
이전 블록과의 연결을 통해 안전하게 연결된 형태를 이루며 정보를 저장하는 시스템이다.
중앙화된 데이터베이스와는 달리 높은 안전성과 투명성을 제공한다.
<img src="https://velog.velcdn.com/images/k_y/post/eb3ef0a4-d80f-4529-9432-c2a4d32cb90d/image.png" alt=""></p>
<h3 id="중앙화와-탈중앙화는-무엇인가-">중앙화와 탈중앙화는 무엇인가 ?</h3>
<p>중앙화는 결정과 권한이 한 지점 또는 단일 기관에 집중 되어 있는 것을 의미한다.
그러므로 단일 지점에서 문제가 발생 시에 전체 시스템에 영향을 미칠 수 있다.</p>
<p>탈중앙화는 결정과 권한이 여러 지점 또는 다수의 참여자에게 분산되어 있는 것을 의미한다.
시스템 전체가 단일 지점에 의존하지 않기 때문에 신속한 의사결정과 안정성을 제공할 수 있다.
<img src="https://velog.velcdn.com/images/k_y/post/ce7dad8a-44ef-4672-bfdc-e5fdcc364c53/image.png" alt=""></p>
<h3 id="블록체인의-기술적인-이해">블록체인의 기술적인 이해</h3>
<h4 id="--블록block">- 블록(Block)</h4>
<p>블록은 데이터를 담고 있는 기본 단위이다.
각 블록에는 트랜잭션 데이터와 이전 블록을 식별하는 고유한 해시 값이 들어있다.</p>
<h4 id="--해시hash">- 해시(Hash)</h4>
<p>해시 함수는 어떠한 데이터에 대해 고정된 길이의 문자열을 생성하는 알고리즘이다.
블록체인에서는 해시 함수가 사용되어 블록의 내용을 고유하게 식별하고, 이전 블록의 해시 값을 참조하여 체인을 형성한다.
<img src="https://velog.velcdn.com/images/k_y/post/6c72e458-38f6-4d42-b92e-93502cd56a82/image.png" alt=""></p>
<h4 id="--채굴mining">- 채굴(Mining)</h4>
<p>블록을 생성하고 블록체인 네트워크를 유지하기 위해 수학적 문제를 해결하는 프로세스를 의미한다.
이를 통해 새로운 블록이 체인에 추가되고, 참여자들 간의 합의가 이뤄진다.</p>
<h4 id="--토큰token">- 토큰(Token)</h4>
<p>블록체인에서는 자체적인 가치를 나태나는 디지털 자산을 토큰이라고 한다.
대표적인 토큰으로는 이더리움의 ETH가 있다.</p>
<h3 id="web3란-무엇인가-">Web3란 무엇인가 ?</h3>
<p>Web3는 탈중앙화와 블록체인 기술을 통한 분산된 웹을 지칭한다.
Web3는 사용자가 중앙 기관이나 중앙화된 서비스에 의존하지 않고 개인적이고, 투명한 디지털 경제를 경험 할 수 있도록 하는 개념이다.
<img src="https://velog.velcdn.com/images/k_y/post/f598515b-ca22-426f-adc0-a64d5b6de8e2/image.png" alt=""></p>
<h3 id="컨센서스란-무엇인가-">컨센서스란 무엇인가 ?</h3>
<p>컨센서스는(Consensus)는 분산 시스템에서 여러 참여자 간에 동의에 도달하는 프로세스를 나타낸다.
분산 시스템에서는 여러 노드(참여자)가 동시에 데이터를 관리하고 업데이트 하기 때문에, 각 노드 간에 일치된 합의가 필요하다. 이러한 합의를 컨센서스 메커니즘을 통해 이뤄지게 된다.</p>
<p>컨센시스의 목적은 네트워크 상의 모든 노드가 동일한 상태의 분산 원장을 유지하도록 하는 것이다.
일치된 합의 없이 각 노드가 독자적으로 데이터를 수정하면 데이터 불일치가 발생할 수 있으며, 이는 신뢰성과 무결성에 문제를 일으킬 수 있다.</p>
<h3 id="트랜잭션이란-무엇인가-">트랜잭션이란 무엇인가 ?</h3>
<p>트랜잭션(Transaction)은 블록체인에서 수행되는 하나의 작업 또는 거래를 나타낸다.
이는 데이터베이스나 원장에 변경을 가하는 모든 단위적인 활동을 의미한다.
주로 암호화폐 거래와 관련이 있지만, 블록체인에서의 트랜잭션은 다양한 형태를 가질 수 있다.</p>
<p><strong>1. 송금 트랜잭션</strong>
암호화폐를 보내거나 받는 행위.
가장 일반적인 트랜잭션 형태 중 하나이다.</p>
<p><strong>2. 스마트 계약 트랜잭션</strong>
스마트 계약을 실행하는 행위.
스마트 계약은 조건이 충족되면 자동으로 실행되는 프로그램으로 트랜잭션을 통해 상호작용 한다.</p>
<p><strong>3. 데이터 전송 트랜잭션</strong>
블록체인에 데이터를 저장하거나 업데이트하는 행위.</p>
<p><strong>4. 참여 인증 트랜잭션</strong>
블록체인 네트워크에 참여하는 사용자의 인증과정을 나타내는 트랜잭션이며,
프로토콜에 따라 참여자가 블록을 검증할 수 있도록 하는 트랜잭션도 있다.</p>
<h3 id="트랜잭션의-서명원리">트랜잭션의 서명원리</h3>
<p>서명원리는 주로 공개키 암호화 기술을 기반으로 하며, 티지털 서명을 통해 트랜잭션의 무결성과 인증을 보장한다.</p>
<h4 id="1-키-생성">1. 키 생성</h4>
<p>사용자는 공개키와 개인키를 생성한다.</p>
<blockquote>
<ul>
<li>*<em>공개키 : *</em> 누구나 알 수 있는 키로, 다른 사용자들이 여러 정보를 암호화 하는데 사용된다.
또한 블록체인에서는 사용자의 지갑 주소로 주로 사용된다.</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>*<em>개인키 : *</em> 해당 키와 연결된 공개키를 소유한 사용만이 알 수 있는 비밀 키이다.</li>
</ul>
</blockquote>
<h4 id="2-트랜잭션-생성">2. 트랜잭션 생성</h4>
<p>사용자가 거래를 생성할 때, 해당 거래에는 수신자의 공개키가 포함된다.</p>
<h4 id="3-디지털-서명-생성">3. 디지털 서명 생성</h4>
<p>사용자는 개인키를 사용하여 거래의 디지털 서명을 생성한다.
이 서명은 거래와 사용자의 개인키를 기반으로 생성되므로, 해당 사용자에 의해 만들어진 것을 증명한다.</p>
<h4 id="4-서명-확인">4. 서명 확인</h4>
<p>거래를 받는 사람은 해당 거래와 송신자의 공개키, 그리고 디지털 서명을 이용하여 서명을 확인한다.
만약 디지털 서명이 올바르게 검증되면, 그 거래는 송신자에 의해 만들어진 것이 입증된다.</p>
<h3 id="스마트-컨트랙트란-무엇인가-">스마트 컨트랙트란 무엇인가 ?</h3>
<p>스마트 컨트랜트는 계약 조건이 코드로 작성된 프로그램으로, 블록체인 상에서 실행되는 자동화된 계약이다.
이는 코드로 작성되어 블록체인에 배포되고, 조건이 충족되면 자동으로 실행되는 특징이 있다.
<img src="https://velog.velcdn.com/images/k_y/post/ada17eb9-3167-4c50-bf35-fc63ce997a20/image.png" alt=""></p>
<h3 id="스마트-컨트랙트의-동작-방식">스마트 컨트랙트의 동작 방식</h3>
<h4 id="1-계약-작성">1. 계약 작성</h4>
<p>스마트 컨트랜트는 코드로 작성되어야 한다.</p>
<h4 id="2-블록체인-배포">2. 블록체인 배포</h4>
<p>작성된 스마트 컨트랙트 코드는 특정 블록체인 네트워크에 배포된다.
이 때 스마트 컨트랙트는 주소를 갖게 된다.</p>
<h4 id="3-트랜잭션-실행">3. 트랜잭션 실행</h4>
<p>스마트 컨트랙트는 블록체인 네트워크에 의해 실행되는데, 이는 사용자가 특정 조건을 충족시켰거나, 특정 함수를 호출 했을 때 발생한다.</p>
<h4 id="4-조건-검사">4. 조건 검사</h4>
<p>스마트 컨트랜트는 실행 시점에 조건을 검사하고, 조건이 충족되면 정의된 로직에 따라 자동으로 특정 행동을 수행한다.</p>
<h4 id="5-트랜잭션-결과-및-상태-변경">5. 트랜잭션 결과 및 상태 변경</h4>
<p>스마트 컨트랙트가 실행된 결과와 상태 변경은 블록체인에 기록된다.
이는 모든 노드가 동일한 상태를 유지하게 해주는 분산 원장의 특징 중 하나이다.</p>
<h4 id="6-암호화폐-전송">6. 암호화폐 전송</h4>
<p>스마트 컨트랙트가 암호화폐를 다루는 경우, 특정 조건이 충족되면 자동으로 암호화폐가 전송되거나 계좌에 입금되는 등의 행동을 수행한다.</p>
<h4 id="7-이벤트-발생">7. 이벤트 발생</h4>
<p>스마트 컨트랙트는 특정 상황에서 이벤트를 발생시킬 수 있다.
이는 외부 시스템이나 인터페이스에서 이벤트를 감지하고 반응할 수 있게 해준다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 - 타입 선언 방법]]></title>
            <link>https://velog.io/@k_y/%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%83%80%EC%9E%85-%EC%84%A0%EC%96%B8-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@k_y/%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%83%80%EC%9E%85-%EC%84%A0%EC%96%B8-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Wed, 24 Jan 2024 14:56:52 GMT</pubDate>
            <description><![CDATA[<p>리액트 프로젝트를 진행하면서 타입 선언에서 막히는 부분이 많았었다.
그런 부분에 대해서 이해하고 학습한 내용을 정리해보려고 한다.</p>
<h3 id="reactfc">React.FC</h3>
<p>FC란 Function Component의 줄임말이다.
함수형 컴포넌트 사용 시 타입 선언에 사용할 수 있도록 React에서 제공하는 타입이다.</p>
<pre><code class="language-ts">type HeaderProps {
    title: string;
};

const Header: React.FC&lt;HeaderProps&gt; = ({ title }) =&gt; {
    return &lt;div&gt;{title}&lt;/div&gt;;
};</code></pre>
<h3 id="reactcomponenttype">React.ComponentType</h3>
<p>React.ComponentType은 함수형 컴포넌트와 클래스 컴포넌트를 모두 나타낼 수 있는 타입이다.</p>
<pre><code class="language-ts">type HeaderProps = {
    title: string;
};

const Header: React.ComponentType&lt;HeaderProps&gt; = ({ title }) =&gt; {
    return &lt;div&gt;{title}&lt;/div&gt;;
};</code></pre>
<h3 id="reactnode">ReactNode</h3>
<p>ReactNode란 모든 종류의 자식 요소를 나타내는 타입이다.
어떠한 자식 요소든지 전달할 수 있다.</p>
<pre><code class="language-ts">type ContentProps = {
    children: React.ReactNode;
};

const Content: React.FC&lt;ContentProps&gt; = ({ children }) =&gt; {
    return &lt;div&gt;{children}&lt;/div&gt;
}</code></pre>
<h3 id="setstateaction">SetStateAction</h3>
<p>SetStateAction이란 useState 훅에서 사용되는 매개변수 타입이다.</p>
<pre><code class="language-ts">type CounterProps = {
    count: number;
      setCount: React.Dispatch&lt;React.SetStateAction&lt;number&gt;&gt;;
}

const Counter: React.FC&lt;CounterProps&gt; = ({ count, setCount }) =&gt; {
  const handleCounter = () =&gt; {
      setCount((prevCount) =&gt; prevCount + 1)
  };
    return (
        &lt;div&gt;
              &lt;button onClick={handleCounter}&gt;카운트&lt;/button&gt;
          &lt;/div&gt;
    )
}

const List: React.FC = () =&gt; {
      const [count, setCount] = useState&lt;number&gt;(0);
    return (
        &lt;div&gt;
              &lt;Counter count={count} setCount={setCount} /&gt;
          &lt;/div&gt;
    )
}</code></pre>
<h3 id="event">Event</h3>
<p>Input 태그에서 이벤트를 사용할 때는 아래와 같이 이벤트 별로 다른 형식의 타입을 사용해야한다.</p>
<pre><code class="language-ts">// Input Event
const handleInputChange = (event: React.ChangeEvent&lt;HTMLInputElement&gt;) =&gt; {
    const { value } = e.target;
      setInput(value);
}

// Select Event
const handleSelectChange = (event: React.ChangeEvent&lt;HTMLSelectElement&gt;) =&gt; {
    const { value } = e.target;
      setSelect(value);
}

// KeyDown, KeyUp Event
const handleKeyDown = (event: React.KeyboardEvent&lt;HTMLInputElement&gt;) =&gt; {
    const { value } = e.target;
      setKeyDown(value);
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[타입스크립트 - type과 interface 쓰는법]]></title>
            <link>https://velog.io/@k_y/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-type%EA%B3%BC-interface-%EC%93%B0%EB%8A%94%EB%B2%95</link>
            <guid>https://velog.io/@k_y/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-type%EA%B3%BC-interface-%EC%93%B0%EB%8A%94%EB%B2%95</guid>
            <pubDate>Wed, 17 Jan 2024 13:58:39 GMT</pubDate>
            <description><![CDATA[<p>오늘은 타입스크립트에서 타입을 정의하는 두 가지 키워드를 언제 어떻게 써야하는지 적어보려고 한다.</p>
<p>지금까지는 개발을 진행할 때 자바스크립트만을 사용하면서 타입스크립트에 대한 지식이 많이 부족한 상태라 두 가지의 키워드를 언제 쓰는게 좋은지 잘 구분이 되지 않았다.
그렇기에 잘 쓰기 위해서 찾아봤던 내용들을 소개하려고 한다.</p>
<h3 id="인터페이스interface는-무엇인가-">인터페이스(interface)는 무엇인가 ?</h3>
<p>인터페이스(interface)란 상호 간의 정의한 약속 혹은 규칙을 의미한다.
간단하게 인터페이스에 선언된 프로퍼티 또는 메소드의 구현을 강제하여 일관성을 유지하는 것이다.</p>
<pre><code class="language-ts">interface UserProfile {
    name: string;
      age: number;
}

interface UserInfo extends UserProfile {
    job: string
}

const userInfo: UserInfo = {
    name: &#39;김용민&#39;,
      age: 24,
      job: &#39;개발자&#39;
}</code></pre>
<h3 id="타입type은-무엇인가-">타입(type)은 무엇인가 ?</h3>
<p>타입(type)이란 TypeScript에서 사용자 정의 타입을 생성하는데 사용된다.</p>
<pre><code class="language-ts">type UserProfile {
    name: string;
      age: number;
}

type UserInfo = UserProfile &amp; {
    job: string
}

const userInfo: UserInfo = {
    name: &#39;김용민&#39;,
      age: 24,
    job: &#39;개발자&#39;
}</code></pre>
<p>두 키워드 사용할 때는 네이밍 시작을 대문자로 해야한다.
이렇게 두 가지 키워드에 대해서 알아보았다.</p>
<h3 id="인터페이스interface와-타입type을-언제-어떻게-">인터페이스(interface)와 타입(type)을 언제 어떻게 ?</h3>
<p>클래스나 객체를 정의하고 싶다면 인터페이스를 사용하는 게 좋을 거 같고
그 외의 상황에서는 타입으로 정의 하는 것이 좋을 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[타입스크립트 - 선언 & 종류]]></title>
            <link>https://velog.io/@k_y/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%84%A0%EC%96%B8-%EC%A2%85%EB%A5%98</link>
            <guid>https://velog.io/@k_y/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%84%A0%EC%96%B8-%EC%A2%85%EB%A5%98</guid>
            <pubDate>Sat, 13 Jan 2024 08:59:40 GMT</pubDate>
            <description><![CDATA[<p>오늘은 타입스크립트를 사용할 때 타입 선언 방법과 종류들에 대해서 적어보려고 한다.</p>
<h2 id="변수-타입-선언">변수 타입 선언</h2>
<pre><code class="language-typescript">const age: number = 24;</code></pre>
<p>변수를 생성할 때 원하는 변수명 옆에 :(콜론)을 붙여 원하는 타입을 설정한다.</p>
<h2 id="함수-타입-선언">함수 타입 선언</h2>
<pre><code class="language-typescript">function getAge(name: string): number {
 ...
 return age;
}
const get = (name?: string): number =&gt; {
 ...
 return age;
}</code></pre>
<p>함수를 생성할 때 매개변수 옆에 :(콜론)을 붙여 원하는 타입 설정한다.
매개변수에 타입을 선언할 경우 필수 값으로 정의되어 값이 없으면 오류가 발생하는데,
필수값으로 처리하지 않을 매개변수 옆에 ?를 붙일 경우 null, undefined 값도 처리할 수 있도록 한다.
또한 함수의 리턴 값이 있을 경우 () 옆에 원하는 타입을 설정해주면 된다.</p>
<h2 id="타입-종류">타입 종류</h2>
<h3 id="--string">- String</h3>
<pre><code class="language-typescript">const name: string = &#39;김용민&#39;;</code></pre>
<p>값이 문자열인 경우 사용한다.</p>
<h3 id="--number">- Number</h3>
<pre><code class="language-typescript">const age: number = &#39;24&#39;;</code></pre>
<p>값이 숫자인 경우 사용한다.</p>
<h3 id="--boolean">- Boolean</h3>
<pre><code class="language-typescript">const isLoading: boolean = false;</code></pre>
<p>값이 true/false 같은 진위 값인 경우 사용한다.</p>
<h3 id="--object">- Object</h3>
<pre><code class="language-typescript">const kym: object = {
    name: &#39;김용민&#39;,
    age: 24
};</code></pre>
<p>객체인 경우 사용한다.
Object 타입은 밑에 나오는 any와 같이 모든 타입을 허용한다.</p>
<pre><code class="language-typescript">interface UserType = {
    name: string;
    age: number;
}
type UserType = {
    name: string;
    age: number;
}

const kym: UserType = {name: &#39;김용민&#39;, age: 24};</code></pre>
<p>그렇기에 객체는 interface와 type이라는 키워드를 통하여 타입을 정의한다.</p>
<p><strong>type과 interface의 간단한 차이점</strong></p>
<ol>
<li>interface는 캐싱처리가 가능하다.<pre><code class="language-typescript">// interface 캐싱 예시
interface userType {
 name: string;
 age: number;
}
interface userType {
 gender: string;
}
</code></pre>
</li>
</ol>
<p>const user:userType = {
    name: &#39;김용민&#39;,
    age: 24,
    gender: &#39;남자&#39;
}</p>
<pre><code>```typescript
// type 캐싱 예시
type userType {
    name: string;
    age: number;
}
// 동일한 이름의 type을 재선언하면 오류가 발생하게됨.
type userType {
    gender: string;
}</code></pre><ol start="2">
<li>타입 확장 방법이 다르다.</li>
</ol>
<p><strong>interface</strong>는 <strong>extends</strong> 키워드를 사용하여 확장 시킬 수 있다.</p>
<pre><code class="language-typescript">interface car {
    brand: string; 
}

interface sportsCar extends car {
    speed: number;
}</code></pre>
<p><strong>type</strong>은 &#39;<strong>&amp;</strong>&#39; 및 &#39;<strong>|</strong>&#39; 등의 연산자를 사용하여 유니온이나 인터섹션을 통해 타입을 결합 할 수 있다.</p>
<pre><code class="language-typescript">type car {
    brand: string;
}

type sportsCar = car &amp; {
    speed: number;
}</code></pre>
<h3 id="--array">- Array</h3>
<pre><code class="language-typescript">const list: string[] = [&#39;김용민&#39;, &#39;박용민&#39;, &#39;이용민&#39;];
const list: Array&lt;string&gt; = [&#39;김뱀민&#39;, &#39;김소민&#39;, &#39;김닭민&#39;];
const list: Array&lt;string | number&gt; = [&#39;김용박&#39;, &#39;김용진&#39;, 11, 22];</code></pre>
<p>정해져있지 않은 배열인 경우 사용한다.
배열 안에 요소 타입이 한가지로 정해지지 않고 여러가지로 들어가는 경우 &quot;|&quot;를 통해서
유니온 타입을 선언할 수 있다.</p>
<h3 id="--tuple">- Tuple</h3>
<pre><code>const list: [string, number] = [&#39;김용민&#39;, 24];</code></pre><p>배열 길이가 고정이며 요소의 타입이 지정된 경우에 사용한다.</p>
<h3 id="--enum">- Enum</h3>
<pre><code class="language-typescript">enum week {
    sunday, // 0
    monday, // 1
    tuesday, // 2
    wedneday, // 3
    thursday, // 4
    friday, // 5
    saturday // 6
}</code></pre>
<p>여러 값들의 번호를 매기는 경우에 사용한다.</p>
<h3 id="--any">- any</h3>
<pre><code class="language-typescript">const name: any = &#39;김용민&#39;;
const age: any = &#39;24&#39;;
const isLoading: any = false;</code></pre>
<p>모든 타입에 대해서 허용하는 경우에 사용한다.</p>
<h3 id="--void">- void</h3>
<pre><code class="language-typescript">const voidTest = (): void =&gt; {
    console.log(&#39;void 테스트입니다.&#39;);
}</code></pre>
<p>리턴 값이 없는 함수일 경우에 사용한다.</p>
<h3 id="--never">- Never</h3>
<pre><code class="language-typescript">const voidTest = (): never =&gt; {
    while(true) {
        ...
    }
}</code></pre>
<p>절대로 함수 끝까지 실행되지 않을 경우에 사용한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 폴더 구조]]></title>
            <link>https://velog.io/@k_y/%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@k_y/%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%8F%B4%EB%8D%94-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Tue, 09 Jan 2024 09:41:02 GMT</pubDate>
            <description><![CDATA[<p><strong>오늘은 리액트 폴더 구조에 대해서 적어보려고 한다.</strong></p>
<p>프로젝트를 진행하면서 폴더 구조는 떼놓을 수가 없는 중요한 부분이다.
어떻게 디자인을 하는지에 따라 유지보수, 확장성, 코드 재사용성 등 프로젝트 관리를 효율적으로 할 수 있도록 도와주기 때문이다.</p>
<pre><code>**최상위 폴더 구조**

my-app
├── node_modules
├── public
├── src
├── .env
├── .gitignore
├── package.json
├── tailwind.config
└── README.md</code></pre><p><strong>node_modules</strong>
프로젝트에서 사용되는 외부 패키지 및 모듈이 설치되는 폴더입니다.</p>
<p><strong>public</strong>
정적 파일을 저장하는 곳으로 HTML, 이미지, 폰트 등 여러가지 정적 자산들을 저장하는 폴더입니다.</p>
<p><strong>src</strong>
&quot;source&quot;의 줄임말로 리액트 프로젝트에서 개발할 때 작성되는 소스 파일들로 구성되어 있다.</p>
<p><strong>.gitignore</strong>
깃에 추적하지 않을 파일 및 폴더등을 지정하는 파일입니다.
<em>예시)</em> /node_modules, /.yarn, /build, .env.local 등</p>
<p><strong>package.json</strong>
프로젝트의 구성 파일로 프로젝트 이름, 버전, 의존성, 스크립트를 정의하는 JSON 형식의 파일입니다. 
이 파일은 프로젝트를 공유하고 협업할 때 중요하며, 파일에 명시된 라이브러리 목록을 기반으로 <strong>node_modules</strong>를 설치할 수 있도록 한다.</p>
<p><strong>README.md</strong>
프로젝트에 대한 간단한 설명, 사용법, 라이선스 등의 정보를 제공하는 파일이다.
<strong>md</strong>는 마크다운(Markdown)의 약자로 일반 텍스트 기반의 경량 마크업 언어를 사용하여 작성된다.</p>
<pre><code>**src 폴더 구조**

src
├── components
├── pages
├── styles
├── store
├── utils
├── hooks
└── App.js</code></pre><p><strong>components</strong>
리액트에서 UI를 작성하는데 핵심이 되는 폴더입니다.
재사용이 가능한 컴포넌트들을 모아두며, 코드들을 모듈화하고 유지보수성을 높이기 위해 사용된다.</p>
<p><strong>pages</strong>
각각의 페이지를 구성하는 컴포넌트들을 모아두는 폴더입니다.
각 페이지 컴포넌트는 애플리케이션 내에서 특정 URL 경로에 대응되는 컴포넌트들이다.
<em>예시)</em> /Dashboard, /Home, /About 등</p>
<p><strong>styles</strong>
스타일 관련 파일들을 모아두는 폴더입니다.
css modules, scss 등과 같은 스타일 관련 파일들을 관리합니다.</p>
<p><strong>store</strong>
상태 관리를 위한 코드들을 모아두는 폴더입니다.
프로젝트를 관리하는 핵심 기능이며 Redux, ContextApi 등을 사용하여 구현 할 수 있다.</p>
<p><strong>utils</strong>
재사용이 가능한 유틸리티 함수들이나 헬퍼 함수들을 모아두는 폴더입니다.
중복되는 코드들을 방지하며 컴포넌트 코드의 가독성을 향상 시킬 수 있습니다.</p>
<p><strong>hooks</strong>
커스텀 훅들을 모아두는 폴더입니다.
프로젝트를 진행하며 자주 사용하는 로직을 커스텀 훅으로 추상화하여 재사용성을 높이고, 코드를 깔끔하게 유지 할 수 있습니다.</p>
<p><strong>App.js</strong>
리액트의 최상위 컴포넌트로서, 애플리케이션의 전반적인 구조와 레이아웃을 정의하고 각 페이지 또는 컴포넌트들을 조합하여 화면을 구성하는 역할을 합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[들어가며]]></title>
            <link>https://velog.io/@k_y/%EB%93%A4%EC%96%B4%EA%B0%80%EB%A9%B0</link>
            <guid>https://velog.io/@k_y/%EB%93%A4%EC%96%B4%EA%B0%80%EB%A9%B0</guid>
            <pubDate>Mon, 08 Jan 2024 17:00:31 GMT</pubDate>
            <description><![CDATA[<h3 id="블로그를-시작하게-된-이유">블로그를 시작하게 된 이유</h3>
<p>요즘은 다들 개발 블로그를 무조건 해야한다라는 분위기였다.
하지만 나는 시작하게 된 이유도 없이 무작정 시작을 하고 싶진 않았었다.
그렇기에 장점과 단점을 비교하며 생각했을 때 시작을 해야겠다고 결심하게 되었다.
아래에 내용들은 내가 생각했던 장단점들이다.</p>
<p><strong>개발 블로그의 장점</strong></p>
<ol>
<li>기록을 남길 수 있다.</li>
<li>여러사람들과 소통 할 수 있다.</li>
<li>나는 어떤 사람인지 보여줄 수 있다.</li>
<li>쉽게 설명하도록 노력하며 제대로 이해하게 된다.</li>
<li>꾸준한 노력과 성장을 하기에 좋은 환경이 될 것이라고 느꼈다.</li>
<li>대부분의 사람들이 가지고 있지만 나에게 없다는건 너무 큰 빈틈이다. </li>
</ol>
<p><strong>개발 블로그의 단점</strong></p>
<ol>
<li>많은 시간 투자가 필요하다.</li>
<li>쓸 내용이 없더라도 글을 써야한다는 압박감이 생길 수 있다.</li>
<li>시간이 지날수록 내용이 늘어남에 따라 스스로 썼던 내용들을 기억하지 못하게 된다면 
오히려 독이 될 수 있다.</li>
</ol>
<p><strong>해당 내용들이 개발 블로그에 대해 고민을 하고 있는 사람들에게 도움이 되면 좋겠다.</strong></p>
]]></description>
        </item>
    </channel>
</rss>