<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>tmdghks_dev.log</title>
        <link>https://velog.io/</link>
        <description>반갑습니다~</description>
        <lastBuildDate>Mon, 03 Feb 2025 01:33:25 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>tmdghks_dev.log</title>
            <url>https://velog.velcdn.com/images/tmdghks_dev/profile/c075df3e-417b-4125-a1bd-8c5c7145a3bf/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. tmdghks_dev.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/tmdghks_dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Issue]Yarn berry 사용할때 node_modules가 없을 때]]></title>
            <link>https://velog.io/@tmdghks_dev/IssueYarn-berry-%EC%82%AC%EC%9A%A9%ED%95%A0%EB%95%8C-nodemodules%EA%B0%80-%EC%97%86%EC%9D%84-%EB%95%8C</link>
            <guid>https://velog.io/@tmdghks_dev/IssueYarn-berry-%EC%82%AC%EC%9A%A9%ED%95%A0%EB%95%8C-nodemodules%EA%B0%80-%EC%97%86%EC%9D%84-%EB%95%8C</guid>
            <pubDate>Mon, 03 Feb 2025 01:33:25 GMT</pubDate>
            <description><![CDATA[<h1 id="개요">개요</h1>
<p>최근 같은 이슈를 겪은 사람들과 문제를 해결한 이야기를 기록하기위해 작성합니다.</p>
<p>기존의 yarn 3이상을 사용시 yarn classic 이 아닌 yarn berry 를 사용하는데 yarn berry의 경우 Plug&#39;n&#39;Play(PnP)라는 기술을 기본적으로 사용합니다.
PnP모드를 사용 할 시에 node_modules 를 사용하지 않습니다.
때문에 node_modules에 의존성을 가진 코드와 충돌이 발생 할 수 있습니다.</p>
<p>해당 글은 yarn berry 또는 PnP모드에 관한글이 아닌 yarn berry 사용 시 링커설정을 PnP모드에서 기존의 클래식처럼 node_modules를 사용하는 방법을 작성합니다.</p>
<p>yarn에 대한 세부 내용은 <a href="https://blog.dramancompany.com/2023/02/%EB%A6%AC%EB%A9%A4%EB%B2%84-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%A2%8C%EC%B6%A9%EC%9A%B0%EB%8F%8C-yarn-berry-%EB%8F%84%EC%9E%85%EA%B8%B0/">리멤버 개발블로그</a> 를 참조해주세요</p>
<h2 id="case1">Case1</h2>
<p>Vercel에서 모노레포 툴링으로 Turborepo의 경우 패키기 매니저중 pnpm의 pnp모드만을 지원하고, yarn berry의 경우 지원을 하지않습니다.</p>
<h2 id="case2">Case2</h2>
<p>react-native에서 새 프로젝트를 시작하고 ios의 pod install 을 실행할시 다음과 같은 error 로그를 볼 수 있습니다.</p>
<pre><code class="language-ruby"># 실행 코드(Podfile)
def node_require(script)
  # Resolve script with node to allow for hoisting
  require Pod::Executable.execute_command(&#39;node&#39;, [&#39;-p&#39;,
    &quot;require.resolve(
      &#39;#{script}&#39;,
      {paths: [process.argv[1]]},
    )&quot;, __dir__]).strip
end

# error 코드
Error: Cannot find module &#39;react-native/scripts/react_native_pods.rb&#39;
Require stack:
- /Users/user/Documents/sources/AwesomeProject/ios/[eval]
    at Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)
    at Function.resolve (node:internal/modules/cjs/helpers:127:19)
    at [eval]:1:9
    at Script.runInThisContext (node:vm:123:12)
    at Object.runInThisContext (node:vm:299:38)
    at node:internal/process/execution:79:19
    at [eval]-wrapper:6:22
    at evalScript (node:internal/process/execution:78:60)
    at node:internal/main/eval_string:28:3 {
  code: &#39;MODULE_NOT_FOUND&#39;,
  requireStack: [ &#39;/Users/user/Documents/sources/AwesomeProject/ios/[eval]&#39; ]
}</code></pre>
<p>기본적으로 작성 된 Podfile <code>def node_require</code> 부분이 실행 될때 참조하고자 하는 node_modules가 없어서 에러를 반환하고 있습니다. 해당 코드를 수정하는게 아니라면 기존과 같이 node_modules를 추가해야 합니다.</p>
<h1 id="해결">해결</h1>
<blockquote>
<p><code>yarn set version berry</code> </p>
</blockquote>
<ul>
<li>yarn set version berry를 root project 터미널에 입력</li>
<li>그후 <code>.yarnrc.yml</code> 이 생성됩니다.</li>
<li>해당 파일에서 nodeLinker가 <code>nodeLinker: node-modules</code> 로 되어있는지 확인하고 없다면 추가해주면 됩니다.<pre><code class="language-yml">nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-4.6.0.cjs</code></pre>
</li>
</ul>
<h1 id="토막-정보">토막 정보</h1>
<p>yarnrc는 yarn의 내부 설정을 관리하는 파일입니다.</p>
<ul>
<li>yarnPath: yarn을 프로젝트 내에 설치하는데 가장 선호되는 방법으로 모든 팀원이 같은 yarn version을 사용할 수 있도록 해줍니다.</li>
<li>nodeLinker: Node 패키지를 설치하는데 어떤 링커를 사용할지 명시하는 속성. (<code>pnp</code>, <code>pnpm</code> ,<code>node-modules</code> 가능)</li>
</ul>
<p>출처: <a href="https://nukw0n-dev.tistory.com/37">https://nukw0n-dev.tistory.com/37</a> [찐이의 개발 연결구과:티스토리]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] Tmap 셋팅과 사용법]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-Tmap-%EC%85%8B%ED%8C%85%EA%B3%BC-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-Tmap-%EC%85%8B%ED%8C%85%EA%B3%BC-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Tue, 30 Jan 2024 07:49:38 GMT</pubDate>
            <description><![CDATA[<h3 id="필수-설치-패키지">필수 설치 패키지</h3>
<pre><code class="language-bash">$ yarn add react-native-invoke-tmap</code></pre>
<h3 id="tmap에서-해주어야-할-설정">Tmap에서 해주어야 할 설정</h3>
<ol>
<li><p>Tmap 에서 로그인을 해주고 계정이 없다면 회원가입 해주세요</p>
</li>
<li><p>Tmap api를 사용할 앱을 만들어야 합니다. 처음엔 앱이 없으니 대시보드를 통해 앱을 만들어 주세요. <img src="https://velog.velcdn.com/images/tmdghks_dev/post/1d15fe26-de48-4623-b17d-b28cf6afe0bd/image.png" alt=""></p>
</li>
</ol>
<ol start="3">
<li><p>앱 상품 사용 신청을 신청해야합니다. 무료플랜이나 그 이상을 선택하면 됩니다.</p>
<p> <a href="https://openapi.sk.com/products/detail?linkMenuSeq=127#%EC%83%81%ED%92%88%EC%82%AC%EC%9A%A9%EC%8B%A0%EC%B2%AD%ED%95%98%EA%B8%B0">SK open API</a></p>
</li>
<li><p>무료플랜이 적용되어있다면 App Key를 기억하면 됩니다.</p>
</li>
</ol>
<h3 id="앱내의-설정">앱내의 설정</h3>
<h4 id="android">android</h4>
<ul>
<li>./android/app/src/main/AndroidManifest.xml 수정</li>
</ul>
<pre><code class="language-xml">    &lt;manifest xmlns:android=&quot;&lt;http://schemas.android.com/apk/res/android&gt;&quot; package=&quot;com.grabber.grabbee&quot;&gt;
        ...

        &lt;queries&gt;
          &lt;package android:name=&quot;com.skt.skaf.l001mtm091&quot; /&gt;
          &lt;package android:name=&quot;com.skt.tmap.ku&quot; /&gt;
        &lt;/queries&gt;
        &lt;application
                ...
           &gt;
          &lt;meta-data
            android:name=&quot;com.skt.tmap&quot;
            android:value=&quot;여기에 Tmap App Key를 넣으세요&quot; /&gt;
        &lt;/application&gt;
    &lt;/manifest&gt;</code></pre>
<h4 id="ios">ios</h4>
<ol>
<li>키 추가<pre><code class="language-bash">//in info plist
&lt;dict&gt;
 &lt;key&gt;TMAP_API_KEY&lt;/key&gt;
 &lt;string&gt;Api key를 입력해주세요&lt;/string&gt;
&lt;/dict&gt;</code></pre>
</li>
<li>쿼리 추가<pre><code class="language-bash">//in info plist
&lt;key&gt;LSApplicationQueriesSchemes&lt;/key&gt;
&lt;array&gt;
 &lt;string&gt;tmap&lt;/string&gt;
&lt;/array&gt;</code></pre>
</li>
</ol>
<h3 id="사용-예시">사용 예시)</h3>
<pre><code class="language-tsx">import {
  checkTmapApplicationInstalled,
  invokeTMap,
  complexInvokeTMap,
  InvokeTMapRouteInfo,
} from &#39;react-native-invoke-tmap&#39;;

// ...

//data structure
const routeInfo: InvokeTMapRouteInfo = {
  // required(필수 props)
  rGoName: &#39;강남역&#39;, // 목적지명칭(필수)
  rGoX: 127.027621, // 목적지경도(필수)
  rGoY: 37.497942, // 목적지위도(필수)
  // optional(선택적 props)
  rStName: &#39;서울역&#39;, // 출발지명칭
  rStX: 126.972646, // 출발지경도
  rStY: 37.553017, // 출발지위도
  rV1Name: &#39;용산역&#39;, // 경유지1명칭
  rV1X: 126.964775, // 경유지1 경도
  rV1Y: 37.52989, // 경유지1 위도
  rV2Name: &#39;사당역&#39;, // 경유지2명칭
  rV2X: 126.981633, // 경유지2경도
  rV2Y: 37.476559, // 경유지2위도
};

//in react native components
export default function App() {
    //...
        // 디바이스에 Tmap이 깔려있나 안깔려있나 확인
    const onPressCheckTMapExistButton = () =&gt; {
        checkTmapApplicationInstalled()
        .then((isExist) =&gt; {
            if (isExist) {
            setIsTMapExist(true);
            } else {
            setIsTMapExist(false);
            }
        })
        .catch(() =&gt; {
            setIsTMapExist(false);
        });
    };
        // 지정된 설정으로 티맵 실행
    const onPressInvokeTMap = () =&gt; {
        invokeTMap(routeInfo);
    };
        // 지정된 설정으로 티맵 실행
        // 만일 티맵이 설치가 안되어있다면 스토어로 이동
    const onPressComplexInvokeTMap = () =&gt; {
        complexInvokeTMap(routeInfo);
    };

    return (
        //...
    )
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] screen이 focus될 시 로직실행을 위한 useFocusEffect 사용법]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-screen%EC%9D%B4-focus%EB%90%A0-%EC%8B%9C-%EB%A1%9C%EC%A7%81%EC%8B%A4%ED%96%89%EC%9D%84-%EC%9C%84%ED%95%9C-useFocusEffect-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-screen%EC%9D%B4-focus%EB%90%A0-%EC%8B%9C-%EB%A1%9C%EC%A7%81%EC%8B%A4%ED%96%89%EC%9D%84-%EC%9C%84%ED%95%9C-useFocusEffect-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Tue, 30 Jan 2024 07:32:19 GMT</pubDate>
            <description><![CDATA[<h3 id="참조-">참조 :</h3>
<blockquote>
<p>  <a href="https://reactnavigation.org/docs/use-focus-effect/">https://reactnavigation.org/docs/use-focus-effect/</a></p>
</blockquote>
<h3 id="목적-">목적 :</h3>
<ul>
<li>해당 화면이 디바이스에서 보여질때만 실행되는 로직이 필요    </li>
</ul>
<h3 id="usefocuseffect-사용-">useFocusEffect 사용 :</h3>
<ul>
<li>React Navigation에서 제공해주는 Hooks인 useFocusEffect 사용</li>
</ul>
<h4 id="사용-예">사용 예)</h4>
<pre><code class="language-jsx">    const [user, SetUser] = useState&lt;String[]&gt;([])
    useFocusEffect(
        React.useCallback(() =&gt; {
          let isActive = true;

          const fetchFn = async () =&gt; {
            // anything works
            SetUser([]);
          };

          fetchFn();

          return () =&gt; {
            isActive = false;
          };
        }, [user]), // add dependency
      );</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] 안드로이드에서 기본 텍스트 패딩값 제거]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C%EC%97%90%EC%84%9C-%EA%B8%B0%EB%B3%B8-%ED%85%8D%EC%8A%A4%ED%8A%B8-%ED%8C%A8%EB%94%A9%EA%B0%92-%EC%A0%9C%EA%B1%B0</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C%EC%97%90%EC%84%9C-%EA%B8%B0%EB%B3%B8-%ED%85%8D%EC%8A%A4%ED%8A%B8-%ED%8C%A8%EB%94%A9%EA%B0%92-%EC%A0%9C%EA%B1%B0</guid>
            <pubDate>Tue, 30 Jan 2024 07:22:03 GMT</pubDate>
            <description><![CDATA[<h2 id="상황-">상황 :</h2>
<ul>
<li>외부의 커스텀 폰트를 적용 시켰더니 line-height 를 적용 시키지 않았는데 글자간의 상하 간격이 크게 차이난다.</li>
<li>결정적으로 ios와 스타일 통일이 안됨</li>
</ul>
<h2 id="원인-">원인 :</h2>
<ul>
<li>다음과 같이 별도의 설정을 해주지 않는다면 Android에서는 TextView이 기본 패딩값이 적용된다.
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/17a82d85-511c-466a-9269-e085c208039c/image.png" alt=""></li>
</ul>
<h2 id="해결-">해결 :</h2>
<ul>
<li>style에 <strong><code>include-font-padding: false</code></strong> 를 선언 해주면 된다.</li>
</ul>
<pre><code class="language-tsx">// ex) styled-components
export const Label = styled.Text`
  include-font-padding: false;
    // ...
`;

// ex) styleSheet
const styles= styleSheet.create({
    text: {
        includeFontPadding: false;
    }
})</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] react-native-gifted-chart의 LineChart에서 pointer 활성화 시 scrollView disable 방법]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-react-native-gifted-chart%EC%9D%98-LineChart%EC%97%90%EC%84%9C-pointer-%ED%99%9C%EC%84%B1%ED%99%94-%EC%8B%9C-scrollView-disable-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-react-native-gifted-chart%EC%9D%98-LineChart%EC%97%90%EC%84%9C-pointer-%ED%99%9C%EC%84%B1%ED%99%94-%EC%8B%9C-scrollView-disable-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Tue, 30 Jan 2024 07:16:48 GMT</pubDate>
            <description><![CDATA[<h2 id="목표-">목표 :</h2>
<ul>
<li>그래프를 클릭했을 때 나오는 Pointer가 나오는데 해당 이벤트가 진행중 일때 LineChart를 감싸고있는 Scroll이 스크롤 되지 않게 disable 처리 하는것이 목표
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/4a49b4b2-3aea-4316-a27a-2c619b12b392/image.jpeg" alt=""></li>
</ul>
<h2 id="이슈-사항">이슈 사항:</h2>
<ul>
<li>react-native-gifted-chart 에 문제가 있었다 바로<ul>
<li><code>ref를 받지 않는다는것</code></li>
<li><code>pointer를 보여주는 컴포넌트에 대하여 pressIn과 out이 따로 없다</code></li>
</ul>
</li>
</ul>
<h3 id="라이브러리의-상태">라이브러리의 상태?</h3>
<ul>
<li>해당 라이브러리에 작성된 LineChart 를 살펴보았다.</li>
<li>props 중에서 getPointerProps라는것이 있다   </li>
<li>해당 props는 포인터가 활성화 될때 {pointerIndex, pointerX, pointerY} 값을 받아서 callBack 해주는 Function 타입의 props이다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/tmdghks_dev/post/98e231fd-22de-4c2a-8efe-60e15bb9a39a/image.png" alt=""></p>
<ul>
<li><p>여기서 문제가 생기는데 우리가 목표로 하는 컨트롤이 <code>pointer가 보여지고 사라질때의 상태를 조절</code> 인데 해당 이벤트가 pointerX의 값에 의해서만 수정된다.</p>
<p>  <img src="https://velog.velcdn.com/images/tmdghks_dev/post/40fdf0b8-d156-4330-a03d-9f33487b8491/image.png" alt=""></p>
</li>
</ul>
<ul>
<li>때문에 pointerX값의 변화에 따라서만 다른 액션을 취할 수 있는것이다.</li>
</ul>
<h2 id="문제-해결-">문제 해결 :</h2>
<ul>
<li><p>해결한 코드</p>
<pre><code class="language-jsx">  &lt;LineChart
  ...
      getPointerProps={(item, index) =&gt; {
        const {pointerIndex, pointerX, pointerY} = item;
        if (pointerIndex === -1 &amp;&amp; pointerX === 0 &amp;&amp; pointerY === 0) {
          /**
           * 거의 모든 랜더링에 불필요한 랜더링중 다음값이 나온다.
           *  {&quot;pointerIndex&quot;: -1, &quot;pointerX&quot;: 0, &quot;pointerY&quot;: 0}
           * 해당 조건이 걸릴떄는 return void 시켜 불필요한 이벤트 방지
           */
          return;
        } else if (item.pointerX === 0) {
          setIsScroll(true);
        } else {
          setIsScroll(false);
        }
      }}
  ...
  /&gt;</code></pre>
</li>
<li><p>설명 :</p>
<ol>
<li><p><code>getPointerProps</code> 에는 item과 index 를 파라미터로 받고 item은 <code>{pointerIndex, pointerX, pointerY}</code> 을 포함하고 있습니다.</p>
</li>
<li><p>LineChart의 Line을 누르고 있으면 Pointer가 나오고 <code>getPointerProps</code> 가 동작 하며 item에 포함된 요소를 받을 수 있습니다.</p>
</li>
<li><p><code>getPointerProps</code> 는 랜더링이 되자마자 실행되며 이때 item의 값은 <code>{pointerIndex = -1, pointerX = 0, pointerY = 0 }</code></p>
</li>
<li><p>문제는 getPointerProps를 일으키는 이벤트가 실행 될 때(최초 랜더링, pressIn 상태일 때) 수많은 같은 값이 발생이 됩니다.
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/0b5ad84c-9557-4ce9-9ed6-8cd6d5a43ba9/image.png" alt=""></p>
</li>
</ol>
</li>
</ul>
<pre><code>5. 때문에 이벤트 발생시 너무 많은 중복값 발생시에 void return을 하여 불필요한 이벤트 발생을 막고 필요한 때에만 이벤트를 넣었습니다.</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] could not get batchedbridge react native]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-could-not-get-batchedbridge-react-native</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-could-not-get-batchedbridge-react-native</guid>
            <pubDate>Tue, 30 Jan 2024 07:11:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참조 : <a href="https://hwangtaehyun.github.io/blog/react-native/bundle-error/">Could not get BatchedBridge, make sure your bundle is packaged correctly</a></p>
</blockquote>
<h2 id="원인-">원인 :</h2>
<ul>
<li>native 모듈 설치 이후 해당 모듈 사용 metro 서버에 캐시되어있던 데이터와 충돌이 남</li>
</ul>
<h2 id="해결-">해결 :</h2>
<ul>
<li>metro를 캐시 초기화 하여 새로 시작<pre><code class="language-jsx">npx react-native start --reset-cache</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Android Build Error ) 'compileDebugJavaWithJavac' task (current target is 11)]]></title>
            <link>https://velog.io/@tmdghks_dev/Android-Build-Error-compileDebugJavaWithJavac-task-current-target-is-11</link>
            <guid>https://velog.io/@tmdghks_dev/Android-Build-Error-compileDebugJavaWithJavac-task-current-target-is-11</guid>
            <pubDate>Tue, 30 Jan 2024 07:08:09 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참조  :  <a href="https://kotlinworld.com/426">오류 수정 방법 : Caused by: org.gradle.api.GradleException: &#39;compileDebugJavaWithJavac&#39; task (current target is 17) and &#39;compileDebugKotlin&#39; task (current target is 1.8) jvm target compatibility should be set to the same Java version.</a></p>
</blockquote>
<h2 id="에러-원인">에러 원인</h2>
<p>현재 Kotlin 버전과, Kotlin Compile 시 JVM 타겟 버전 설정이 달라서 생기는 문제이다.</p>
<pre><code>Caused by: org.gradle.api.GradleException: &#39;compileDebugJavaWithJavac&#39; task (current target is) and &#39;compileDebugKotlin&#39; task (current target is) jvm target compatibility should be set to the same Java version.</code></pre><h2 id="에러-해결-방법">에러 해결 방법</h2>
<p>app 수준의 build.gradle.kts 파일 혹은 build.gradle 파일에 다음과 같이 적혀있을텐데</p>
<pre><code>android{
    ...
    kotlinOptions {
        jvmTarget = &quot;[JVM 타겟 버전]&quot;
    }
}</code></pre><p>이 부분을 위에서 말하는 <code>Kotlin 타겟 버전</code> 으로 변경하면된다.
현재 버전이 17이면 jvmTarget을 17로 변경하면 된다.</p>
<p>JDK 1.10버전 이상부터는 1. 을 붙이지 않고 서브버전명을 그대로 쓴다. 즉, 17이라고 쓰면 된다.</p>
<pre><code>android {
    ...
    kotlinOptions {
        jvmTarget = &quot;17&quot;
    }
}</code></pre><p>이렇게 하면 빌드가 성공한다.</p>
<p>위의 상황과 별개의 상황도 고려해야 한다.</p>
<h2 id="case">Case</h2>
<ul>
<li>adb 및 가상 Emulator를 확인(아예 비활성화 및 못읽어 올 경우 build 자체가 안됨)</li>
<li>targetKotlin 버전을 명시화 한다. reactnative의 경우는 알아서 되는것 같지만…혹시나 충돌이 날경우는 해결해주어야 함</li>
<li>서드파티 라이브러리를 설치했을 경우 충돌이 날 수 있으니 어디에서 에러가 나는지 체크 해주어야함 (필자의 경우는 reanimated가 v2→v3로 넘어가는 과정에서 충돌이 난 경우가 있음)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] Android 에서 data요소중 date를 못가져오는 이슈]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-Android-%EC%97%90%EC%84%9C-data%EC%9A%94%EC%86%8C%EC%A4%91-date%EB%A5%BC-%EB%AA%BB%EA%B0%80%EC%A0%B8%EC%98%A4%EB%8A%94-%EC%9D%B4%EC%8A%88</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-Android-%EC%97%90%EC%84%9C-data%EC%9A%94%EC%86%8C%EC%A4%91-date%EB%A5%BC-%EB%AA%BB%EA%B0%80%EC%A0%B8%EC%98%A4%EB%8A%94-%EC%9D%B4%EC%8A%88</guid>
            <pubDate>Tue, 30 Jan 2024 07:03:03 GMT</pubDate>
            <description><![CDATA[<h2 id="이슈-사항">이슈 사항</h2>
<ol>
<li><p>firebase로 얻어온 데이터중 date를 가져오는것이 있는데 나머지 요소를 모두 가져올 수 있지만 오직 date만 가져오지 못한다..!!!</p>
<ol>
<li><p>작성한 코드
 <img src="https://velog.velcdn.com/images/tmdghks_dev/post/44dff74d-3d16-4805-90bb-5560819dc45d/image.png" alt=""></p>
</li>
<li><p>결과값
 <img src="https://velog.velcdn.com/images/tmdghks_dev/post/9781dd8c-dc94-4dc8-b94f-828b73215eef/image.png" alt=""></p>
</li>
</ol>
</li>
</ol>
<h2 id="문제점">문제점</h2>
<ul>
<li><strong>ios에서는 아무 문제없이 date 값을 가져올 수 있다.</strong></li>
<li>android 에서 id가 포함되어있는 + 다른 형식의 createdAt 의 데이터는 date가 불러와지지만 나머지 값들은 date가 불러와지지 않는다</li>
<li>data 에 date를 불러오려고 하면 다음과같은 결과를 반환한다<ul>
<li><code>[data.date] = undefined</code></li>
<li><code>data[’date’] = undefined</code></li>
<li><code>Object.values = [0.04409162, &quot;XAG&quot;, &quot;12321cc-1233223123-29de1a81&quot;, 1123213, &quot;2023-08-11&quot;]</code></li>
</ul>
</li>
<li>각 요소를 탐색 하였을 때 date는 undefined 를 밷지만 배열의 값만 반환하는 Object.values 를 사용 하였을 때 정상적으로 모든 값을 얻을 수 있다.</li>
</ul>
<h2 id="해결">해결</h2>
<blockquote>
<p>이슈에 대한 명확한 해결은 아니지만 해당 이슈에 걸려있는 목적을 위한 값을 얻어내는것을 목적으로 우회하여 문제를 해결</p>
</blockquote>
<p><strong>해결코드 예시:</strong></p>
<pre><code class="language-jsx">const Fn = async () =&gt; {

// firestore에서 가져온 data list
const _list = await firestore()
    .collection(&quot;NonFeMetal&quot;)
    .where(&#39;category&#39;,&#39;==&#39;,&#39;XAG&#39;)
    .get();

// Platform이 안드로이드인 경우에서만 발생하는 문제임으로
// 해당 로직은 안드로이드에서만 적용되게 한다.
if (Platform.OS === &#39;android&#39;) {
  _list.forEach(e =&gt; {
    const listData = e.data();

    const {value, createdAt, category, ...prop} = listData;
    const propKey = Object.keys(prop);

        const resultDate = 
            propKey.includes(&#39;id&#39;) ? prop.date : Object.values(prop)[0],
  });

}</code></pre>
<ul>
<li>js es6인 디스트럭쳐링을 이용하여 유사하게 data를 필터하여 최대한 date값만 남게 처리하였습니다.</li>
<li>필터된 <code>prop</code>라는 값에 Object.keys를 이용하여 key값만 분류하여 <code>propsKey</code>에 입력합니다.</li>
<li><code>propsKey</code>에는 <code>‘id’</code> 라는 key값이 있을 수 있고 id가 있는 데이터 값들은 .date 또는 [’date’]로 날짜가 추출되기 때문에 그대로 사용합니다.</li>
<li>기존에 undefined가 되던 .date와 [’date’] 는 사용하지 않고 Object.values를 이용하여 date값을 정상적으로 얻을 수 있습니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native]FastImage에서 캐싱되는 uri 주소 회피하기]]></title>
            <link>https://velog.io/@tmdghks_dev/React-NativeFastImage%EC%97%90%EC%84%9C-%EC%BA%90%EC%8B%B1%EB%90%98%EB%8A%94-uri-%EC%A3%BC%EC%86%8C-%ED%9A%8C%ED%94%BC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@tmdghks_dev/React-NativeFastImage%EC%97%90%EC%84%9C-%EC%BA%90%EC%8B%B1%EB%90%98%EB%8A%94-uri-%EC%A3%BC%EC%86%8C-%ED%9A%8C%ED%94%BC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 30 Jan 2024 06:51:51 GMT</pubDate>
            <description><![CDATA[<h3 id="상황-">상황 :</h3>
<ul>
<li>프로필 이미지를 바꾸는 Post요청 등으로 인해 이미지가 변경 되어야 하는데 해당 변경되는 uri가 동일할 경우 참조 uri의 내용이 달라져도 해당 주소로 이미지가 캐싱되어 이미지 변경이 이루어지지 않는다 </li>
</ul>
<h3 id="해결-">해결 :</h3>
<ul>
<li>이미지의 Uri 주소 뒤에 garbage값을 붙여 timestamp 등의 값을 붙여 리랜더링 될때마다 다른값을 적용시켜 uri가 캐싱되어 같은값을 불러오는것을 방지<h3 id="code-">code :</h3>
<pre><code class="language-tsx"></code></pre>
</li>
</ul>
<p>const Components = ({image}: {image: String}) =&gt; {
    const timeStamp = new Date().getTime();
    // before
    // const uri = image;</p>
<pre><code>// after
const uri = `${image}?${timeStamp}`

return &lt;View&gt;
    &lt;FastImage 
        resizeMode={&#39;contain&#39;}
        style={[]}
         // uri가 불러오는 주소는 동일하지만 FastImage에서 읽어오는 uri가 매번 달라져 캐싱되는일이 없다
        source = {uri}
    /&gt;
&lt;/View&gt;</code></pre><p>}</p>
<p>```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native]오픈소스 라이센스 고지하기]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4-%EB%9D%BC%EC%9D%B4%EC%84%BC%EC%8A%A4-%EA%B3%A0%EC%A7%80%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4-%EB%9D%BC%EC%9D%B4%EC%84%BC%EC%8A%A4-%EA%B3%A0%EC%A7%80%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 30 Jan 2024 06:43:09 GMT</pubDate>
            <description><![CDATA[<h3 id="install">Install</h3>
<p><code>npm i -g react-native-oss-license</code></p>
<h3 id="usage">Usage</h3>
<ul>
<li>프로젝트 루트 terminal에서 
<code>react-native-oss-license --json --only-direct-dependency --skip-not-required</code> 를 입력하여 나오는 string 배열을 복사하여 사용하자</li>
<li>입력후 다음과같은 형태가 나오는데 저장하여 원하고자 하는 사용값만 리스트로 보여주면 된다.<pre><code class="language-js">export const OpenSourceLicense = [
{
  libraryName: &#39;@eabdullazyanov/react-native-sms-user-consent&#39;,
  version: &#39;1.0.10&#39;,
  _license: &#39;MIT&#39;,
  _description:
    &quot;React Native wrapper for Android&#39;s SMS User Consent API, ready to use in React Native apps with minimum effort&quot;,
  homepage: &#39;&lt;https://github.com/akvelon/react-native-sms-user-consent#readme&gt;&#39;,
  author: {
    name: &#39;Eldar Abdullazyanov&#39;,
    email: &#39;eldar.abdullazyanov@akvelon.com&#39;,
  },
  repository: {
    type: &#39;git&#39;,
    url: &#39;git+https://github.com/akvelon/react-native-sms-user-consent.git&#39;,
    baseUrl: &#39;&lt;https://github.com/akvelon/react-native-sms-user-consent&gt;&#39;,
  },
  _licenseContent:
    &#39;MIT License\\n\\nCopyright (c) 2021 Akvelon\\n\\nPermission is hereby granted, free of charge, to any person obtaining a copy\\nof this software and associated documentation files (the &quot;Software&quot;), to deal\\nin the Software without restriction, including without limitation the rights\\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\ncopies of the Software, and to permit persons to whom the Software is\\nfurnished to do so, subject to the following conditions:\\n\\nThe above copyright notice and this permission notice shall be included in all\\ncopies or substantial portions of the Software.\\n\\nTHE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\nSOFTWARE.\\n&#39;,
},
...
...
 }
]</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] Svg 설정 in Typescript]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-Svg-%EC%84%A4%EC%A0%95-in-Typescript</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-Svg-%EC%84%A4%EC%A0%95-in-Typescript</guid>
            <pubDate>Tue, 30 Jan 2024 06:34:06 GMT</pubDate>
            <description><![CDATA[<h2 id="참조-">참조 :</h2>
<p><a href="https://github.com/kristerkari/react-native-svg-transformer">https://github.com/kristerkari/react-native-svg-transformer</a></p>
<ul>
<li>특이사항 &amp; 고려할 사항<ul>
<li>RN 버전 , TypeScript 사용 유무</li>
</ul>
</li>
</ul>
<h4 id="react-native-svg-transformer-를-devdependencies에-설치">react-native-svg-transformer 를 devDependencies에 설치</h4>
<pre><code class="language-jsx">yarn add react-native-svg
yarn add -D react-native-svg-transformer</code></pre>
<h4 id="metroconfigjs-설정">metro.config.js 설정</h4>
<ul>
<li>특이사항 :<pre><code>  - 해당 부분은 RN의 버전에 따라 설정하는것이 다르기때문에 공식문서를 보고 메뉴얼에 맞게 설정해야한다.
  - 필자는 0.72버전 이상의 RN 을 사용하여서 다음과같이 설정했다.</code></pre></li>
</ul>
<pre><code class="language-jsx">        const {getDefaultConfig, mergeConfig} = require(&#39;@react-native/metro-config&#39;);

        const defaultConfig = getDefaultConfig(__dirname);
        const {assetExts, sourceExts} = defaultConfig.resolver;

        /**
         * Metro configuration
         * &lt;https://facebook.github.io/metro/docs/configuration&gt;
         *
         * @type {import(&#39;metro-config&#39;).MetroConfig}
         */
        const config = {
          transformer: {
            babelTransformerPath: require.resolve(&#39;react-native-svg-transformer&#39;),
          },
          resolver: {
            assetExts: assetExts.filter(ext =&gt; ext !== &#39;svg&#39;),
            sourceExts: [...sourceExts, &#39;svg&#39;],
          },
        };

        module.exports = mergeConfig(defaultConfig, config);</code></pre>
<ul>
<li>typescript decalare.d.ts 생성<ul>
<li>TypeScript 사용시 임의로 svg type을 선언해주어야 한다.</li>
<li>CustomType의 위치와 이름은 자유롭게 설정해도 된다.</li>
<li>tsconfig.json 에 customType 명시<h4 id="예시">예시)</h4>
</li>
</ul>
</li>
</ul>
<pre><code class="language-tsx">    // 위치 : ~/src/@types/declarations.d.ts

    declare module &#39;*.svg&#39; {
      import React from &#39;react&#39;;
      import {SvgProps} from &#39;react-native-svg&#39;;
      const content: React.FC&lt;SvgProps&gt;;
      export default content;
    }</code></pre>
<pre><code class="language-tsx">// location : ~/.tsconfig.json
    {
      &quot;extends&quot;: &quot;@tsconfig/react-native/tsconfig.json&quot;,
      &quot;compilerOptions&quot;: {
            ...
        &quot;typeRoots&quot;: [&quot;./node_modules/@types&quot;, &quot;./src/@types&quot;]
            // ㄴ node_modules/@types는 필수적으로 명시해주고
            // 그 다음에 svg 타입 선언을 위한 declar 파일위치를 명시해준다.
            ...
      }
    }</code></pre>
<h2 id="metro재시작">metro재시작!!</h2>
<ul>
<li>모든 설정을 마치고 metro 서버를 재시작 해주어야 정상적으로 읽어올 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native]의 Style과 사용법]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native%EC%9D%98-Style%EA%B3%BC-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native%EC%9D%98-Style%EA%B3%BC-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Sun, 28 May 2023 12:50:47 GMT</pubDate>
            <description><![CDATA[<h1 id="style-props">style props</h1>
<hr>
<blockquote>
<p><a href="https://reactnative.dev/docs/style">https://reactnative.dev/docs/style</a></p>
</blockquote>
<p>React Native를 사용하면 JavaScript를 사용하여 애플리케이션의 스타일을 지정할 수 있습니다. 모든 style 구성 요소는 prop을 허용합니다.</p>
<p><img src="https://velog.velcdn.com/images/tmdghks_dev/post/f9bed526-c75d-496e-967d-f3300a70d0c2/image.png" alt=""></p>
<p>react native에서 스타일을 구성하기 위한 요소들은(View, Text, ScrollView 등등..) style props 를 optional로 받고있습니다.</p>
<p><img src="https://velog.velcdn.com/images/tmdghks_dev/post/a670917e-4871-4280-9656-9d8d29b160c2/image.png" alt="">
View 컴포넌트의 구성요소를 보면 style로 되어있고</p>
<pre><code class="language-ts">// ViewPropTypes.d.ts
style?: StyleProps&lt;ViewStyle&gt; | undefined</code></pre>
<p>StyleProps는 StyleSheet.d.ts 를 살펴보면 RecursiceArray 타입이 Array를 확장하고 있습니다. 
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/c94befbd-5163-4c7e-aa1d-122c8b91b170/image.png" alt=""></p>
<pre><code class="language-ts">// StyleSheet.d.ts
type Falsy = undefined | null | false;
interface RecursiveArray&lt;T&gt;
  extends Array&lt;T | ReadonlyArray&lt;T&gt; | RecursiveArray&lt;T&gt;&gt; {}
/** Keep a brand of &#39;T&#39; so that calls to `StyleSheet.flatten` can take `RegisteredStyle&lt;T&gt;` and return `T`. */
type RegisteredStyle&lt;T&gt; = number &amp; {__registeredStyleBrand: T};
export type StyleProp&lt;T&gt; =
  | T
  | RegisteredStyle&lt;T&gt;
  | RecursiveArray&lt;T | RegisteredStyle&lt;T&gt; | Falsy&gt;
  | Falsy;</code></pre>
<p>이렇게 선언된 타입으로 style은 각 Style 컴포넌트 타입에 정의된대로 스타일을 단일 또는 배열로 받을 수 있습니다.</p>
<pre><code class="language-jsx">// ex)

const example = () =&gt; {
  return (
        &lt;View style={{width : 100, height: 100}}&gt;
          &lt;View style={[styles.default, styles.box ]}&gt;...&lt;/View&gt;
          &lt;/View&gt;
  )
}

const styles = StyleSheet.create({
    default : {
      flex : 1;
    },
      box : {
      width : 50,
      height : 50,
      backgroundColor : &#39;#222&#39;
    }
})</code></pre>
<h1 id="style-props-작성">style props 작성</h1>
<p>style props 는 inline으로 작성 가능하고 javascript를 이용하여 스타일을 지정 할 수 있습니다.
작성하는 방식은 자유지만 저의 경우는 몇 가지 방식을 나누어 상황에 맞추어 적용 하였습니다.</p>
<ul>
<li>inline style</li>
<li>StyleSheet.create 로 선언한 스타일 설정</li>
</ul>
<h4 id="예시">예시</h4>
<pre><code class="language-tsx">const example = () =&gt; {
  const isDarkMode = false;
  return (
        &lt;View&gt;
            //inline style
          &lt;View style={[{width : 100}]}&gt;&lt;/View&gt;
          // 배열 및 StyleSheet 사용
          &lt;View style={[styles.default, styles.box]}&gt;&lt;/View&gt;
            &lt;View style={[{borderWidth : 1},styles.default, styles.box]}&gt;&lt;/View&gt;
          &lt;View style={[isDarkMode ? styles.dark : styles.light ]}&gt;&lt;/View&gt;
        &lt;/View&gt;
  )
}
const styles = StyleSheet.create({
      default : {},
      box: {},
     dark: {},
      light: {},
})</code></pre>
<h1 id="style-props-우선순위">style props 우선순위</h1>
<p>style props를 배열로 받을 경우 결국 동일하게 선언되는 스타일이 생깁니다.
이때는 배열의 마지막에 오는 스타일이 우선권을 가지게 됩니다.</p>
<h4 id="예시-1">예시</h4>
<pre><code class="language-tsx">import { SafeAreaView, StyleSheet, View } from &#39;react-native&#39;;
import Text from &#39;src/atoms/Text/Text&#39;;

const UIScreen = () =&gt; {
  return (
    &lt;SafeAreaView style={[styles.default]}&gt;
      &lt;View style={{ padding: 20 }}&gt;
        &lt;Text&gt;UIScreen&lt;/Text&gt;
        &lt;Text&gt;Box&lt;/Text&gt;
        &lt;View style={[styles.box]} /&gt;
        &lt;Text&gt;RedBox&lt;/Text&gt;
        &lt;View style={[styles.box, styles.bgBlue, styles.bgRed]} /&gt;
        &lt;Text&gt;BlueBox&lt;/Text&gt;
        &lt;View style={[styles.box, styles.bgRed, styles.bgBlue]} /&gt;
      &lt;/View&gt;
    &lt;/SafeAreaView&gt;
  );
};

export default UIScreen;

const styles = StyleSheet.create({
  default: {
    flex: 1,
    backgroundColor: &#39;#fff&#39;,
  },
  box: {
    width: 100,
    height: 100,
    borderColor: &#39;#111&#39;,
    borderWidth: 1,
  },
  bgRed: {
    backgroundColor: &#39;red&#39;,
  },
  bgBlue: {
    backgroundColor: &#39;blue&#39;,
  },
});

</code></pre>
<h4 id="예시-코드의-결과-화면">예시 코드의 결과 화면</h4>
<p><img src="https://velog.velcdn.com/images/tmdghks_dev/post/b44075e8-3442-47fd-99c9-309134bd1840/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] navigation typescript로 작성]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-navigation-typescript%EB%A1%9C-%EC%9E%91%EC%84%B1</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-navigation-typescript%EB%A1%9C-%EC%9E%91%EC%84%B1</guid>
            <pubDate>Sun, 28 May 2023 07:52:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>react navigation의 Type checking with TypeScript 를 참조하였습니다.<a href="https://reactnavigation.org/docs/typescript/">https://reactnavigation.org/docs/typescript/</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/tmdghks_dev/post/2201a51d-75f1-4a20-bd5e-265d6626f5a8/image.png" alt=""></p>
<p>일반적으로 navigation의 props는 위의 사진처럼 NavigationContainer 내부의 stack에 있는다면 자동으로 props를 전달해줍니다.
하지만 typescript 에서는 따로 타입을 지정해주지 않는 이상 error 표시로 남게 됩니다.</p>
<h1 id="navigation-type-작성">navigation type 작성</h1>
<p>navigationContainer 외에 다른 screen 컴포넌트에 명시할 타입을 작성해야합니다.
이때 RootStackParam을 작성합니다.
여기서 NativeStackScreenProps을 제외하고 모두 임의의 변수,타입명 입니다.
다음과같이 설정하였습니다.</p>
<pre><code class="language-ts">// src/navigation
//             |- navigation.tsx
//             |- type.ts &lt;&lt; 저는 여기에 작성

import { NativeStackScreenProps } from &#39;@react-navigation/native-stack&#39;;
...

type StartStackParamList = {
  Start: undefined;
  UserDetail?: { id: number };
};

type HomeStackParamList = {
  Home: undefined;
};

type StackParamList = StartStackParamList &amp; HomeStackParamList;

export type RootStackParamList = {
  [key in keyof StackParamList]: StackParamList[key] extends infer Param
    ? Param extends undefined
      ? undefined | StackParamList[key]
      : StackParamList[key]
    : never;
};


export type RootStackScreenProps&lt;Screen extends keyof RootStackParamList&gt; =
  NativeStackScreenProps&lt;RootStackParamList, Screen&gt;;</code></pre>
<h3 id="stackparamlist">StackParamList</h3>
<p>해당 stackParamList에는 이동할 화면의 이름을 선언하고 화면에 넘길 변수의 타입을 선언합니다.
Start처럼 넘길것이 없다면 undefined으로 명시
UserDetail처럼 넘겨야 할것이 있다면 Object 로 전달해야합니다.(optional도 가능)
위의 예시처럼 다수의 StackList를 사용한다면 StackParamList 처럼 하나의 타입으로 통합시켜 줍니다.</p>
<h3 id="rootstackparamlist">RootStackParamList</h3>
<p>StackParamList 에서 선언한 화면의 이름들을 사용하기위해 keyof로 선언한 Key값들을 가져옵니다.</p>
<h3 id="rootstackscreenprops">RootStackScreenProps</h3>
<p>실질적으로 화면을 구성하는 ScreenComponent에 사용하게될 타입니다. 작성해둔 RootStackParamList 를 위의 코드와 같이 명시해주시면 됩니다.</p>
<h1 id="작성한-타입-사용">작성한 타입 사용</h1>
<p>ex)
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/e1aa3835-e64b-42c3-8da3-0cb85b711cd9/image.png" alt=""></p>
<ol>
<li><p>작성해둔 <strong>RootStackScreenProps</strong> 를 부르고 key값으로 설정한 UserDetail을 선언하면 UserDetail에 선언한 타입과 navigation 기본 Props 모두 타입이 선언되어있습니다.</p>
</li>
<li><p>파라미터를 넘겼다면 route.params 로 확인이 가능합니다.</p>
</li>
</ol>
<p>다음과같이 작성할 수 있습니다.</p>
<pre><code class="language-tsx">import FC from &#39;react&#39;
import { RootStackScreenProps } from &#39;../../navigation/type&#39;;
...

const UserDetail: FC&lt;RootStackScreenProps&lt;&#39;UserDetail&#39;&gt;&gt; = ({
    navigation,
    route
}) =&gt; {
  return ...
}</code></pre>
<p>OR</p>
<pre><code class="language-tsx">import FC from &#39;react&#39;
import { RootStackScreenProps } from &#39;../../navigation/type&#39;;
...

const UserDetail: ({navigation, route}: &lt;RootStackScreenProps&lt;&#39;UserDetail&#39;&gt;&gt;) =&gt; {
    return ...
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] 스토어에 올라온 제품만 error가 나온 상황 해결 과정]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-%EC%8A%A4%ED%86%A0%EC%96%B4%EC%97%90-%EC%98%AC%EB%9D%BC%EC%98%A8-%EC%A0%9C%ED%92%88%EB%A7%8C-error%EA%B0%80-%EB%82%98%EC%98%A8-%EC%83%81%ED%99%A9-%ED%95%B4%EA%B2%B0-%EA%B3%BC%EC%A0%95</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-%EC%8A%A4%ED%86%A0%EC%96%B4%EC%97%90-%EC%98%AC%EB%9D%BC%EC%98%A8-%EC%A0%9C%ED%92%88%EB%A7%8C-error%EA%B0%80-%EB%82%98%EC%98%A8-%EC%83%81%ED%99%A9-%ED%95%B4%EA%B2%B0-%EA%B3%BC%EC%A0%95</guid>
            <pubDate>Fri, 26 May 2023 05:28:56 GMT</pubDate>
            <description><![CDATA[<h2 id="이슈-발생-내용">이슈 발생 내용</h2>
<hr>
<ul>
<li>합병관련 개인정보 이관 알림 업데이트 이후 앱이 종료되는 현상</li>
<li>개발할때는 아무 문제없었음</li>
<li>identifier가 각각 dev,qa,production의 파일들을 모두 dev, qa , production 로 모두 빌드 해보았으나 아무런 문제가 발생하지 않음</li>
<li>실제 출시된 제품에서만 터지는 현상</li>
<li>앱이 강제종료 되는 계정은 따로 있었는데 예약정보가 있는 계정이면 ios,andorid 모두 강제종료되었음</li>
</ul>
<p>[그 당시에 해결하면서 정리했던 노트]</p>
<p><img src="https://velog.velcdn.com/images/tmdghks_dev/post/668adbea-afe6-4e43-912c-0e999f4e895e/image.png" alt=""></p>
<h2 id="원인">원인</h2>
<hr>
<ul>
<li>기기마다 폰트 크기 호환성을 맞추기위해 추가한 useWindowDimension 때문에 오류발생
근데 useWindowDimension의 fontScale은 결국 사용하지 않았다</li>
</ul>
<pre><code class="language-jsx">import {… , useWindowDimension } from ‘react-native’;

...
...

{
    const { fontScale } = useWindowDimension();
}</code></pre>
<h2 id="해결">해결</h2>
<hr>
<ul>
<li>미사용 코드인 fontScale을 삭제하니 문제 해결</li>
</ul>
<h2 id="왜-수정까지-오래-걸렸는가">왜 수정까지 오래 걸렸는가?</h2>
<hr>
<ol>
<li>실제 제품이 아닌 개발중에서는 아무런 오류가 생기지 않았다.</li>
<li>실제 마켓제품의 Log도 출력해서 보았으나 제대로된 에러가 출력되지 않았다.</li>
<li>초반에 백엔드단에서 error code를 499를 내뱉어서 nginx오류로 오판</li>
</ol>
<h2 id="결론-및-마무리">결론 및 마무리</h2>
<hr>
<ul>
<li>모든 테스트 환경에서 고객에게 제공되는 앱환경에서만 발생하는 오류이기 때문에 해결까지의 상당한 시간이 걸렸다.</li>
<li>RN에서 제공해주는 Modal과 useWindowDimension이 충돌한거 아닐까 추측</li>
<li>미사용 코드가 있다면 꼭! 주석 처리를 하거나 라이브빌드 코드에선 지워서 이러한 상황을 미연에 방지하는 습관을 가져야겠다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript의 this에 대하여]]></title>
            <link>https://velog.io/@tmdghks_dev/JavaScript%EC%9D%98-this%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</link>
            <guid>https://velog.io/@tmdghks_dev/JavaScript%EC%9D%98-this%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</guid>
            <pubDate>Thu, 25 May 2023 04:34:01 GMT</pubDate>
            <description><![CDATA[<p>개발을 진행하다보면 this라는 키워드를 사용하면서 정확하게 이해를 하지 못하면서 사용하고 있었습니다.</p>
<p>이번 글로 한번 기초를 밟아보겠습니다.</p>
<h2 id="일단-this를-찍어본다면">일단 this를 찍어본다면?</h2>
<hr>
<p>F12나 Ctrl(=Command) + shift + c 를 눌러서
브라우저 콘솔에 일단 this를 찍어봅시다</p>
<pre><code class="language-jsx">&gt; this
&gt; Window {
    0: Window, 1: Window, 2: global, window: Window, 
    self: Window, document: document, name: &#39;&#39;, location: Location, … }</code></pre>
<p>그냥 this를 입력했을때 <strong>Window객체</strong>가 나옵니다.
Window객체는 일반적으로 브라우저의 요소와 자바스크립트 엔진과 관련된 모든 정보를 포함하고 있는 객체입니다.
그렇지만 단순히 this = Window 객체인건 아닙니다.</p>
<p>우선 <strong>실행 컨텍스트</strong> 라는걸 알아야 합니다.</p>
<h2 id="실행-컨텍스트execution-context">실행 컨텍스트(Execution Context)</h2>
<hr>
<p><strong>실행컨텍스트</strong>란 자바스크립트 코드가 실행되고 연산되는 범위를 나타내는 추상적인 개념입니다.</p>
<p>좀 더 쉽게 말하자면 <strong>실행 컨텍스트는 실행 가능한 코드가 실행되기 위해 필요한 환경</strong> 이라고 말할 수 있습니다.</p>
<p>여기서 말하는 실행 가능한 코드는 다음 세가지가 있습니다.</p>
<ul>
<li>전역 코드 : 전역 영역에 존재하는 코드</li>
<li>Eval 코드 : <a href="https://poiemaweb.com/js-built-in-object#2121-eval">eval 함수</a>로 실행되는 코드</li>
<li>함수 코드 : 함수 내에 존재하는 코드</li>
</ul>
<p>일반적으로 실행 가능한 코드는 전역코드와 함수코드입니다.</p>
<p>메인 주제가 this이니 전역(Global)과 함수(Function)의 실행 컨텍스트를 간단하게 설명하겠습니다.</p>
<h3 id="global-execution-context">Global Execution Context</h3>
<p>기본적으로 코드가 실행되는 영역이며, 여기서 글로벌 객체인 Window객체를 생성하며, this를 글로벌 객체(Window객체)로 설정해줍니다.</p>
<p>그래서 아까 브라우저 상에 <code>this</code> 를 찍었을 때, Window객체가 출력 된것입니다.</p>
<h3 id="functional-execution-context">Functional Execution Context</h3>
<p>각각의 함수가 가지는 실행 컨텍스트로, 함수가 호출될 때 해당 실행 컨텍스트가 생성됩니다.</p>
<pre><code class="language-jsx">function foo() {
    console.log(&#39;foo&#39;)
} //Funtioncal Execution Context

function boo() {
    const booVar = 8;
    const printVar = (value) =&gt; console.log(value); //Funtioncal Execution Context

    console.log(&#39;boo&#39;);
    foo();
    printVar(booVar);
}//Funtioncal Execution Context

const myNumber = 10;
boo();

/*Output*/ 
/*
//boo
//foo
//8
*/</code></pre>
<h2 id="언제-this-가-바뀌는가">언제 this 가 바뀌는가</h2>
<hr>
<p>this는 기본적으로 Window객체를 말합니다(Node.js는 Global 객체)</p>
<p>하지만 this의 값이 바뀌는 경우가 있습니다. 때문에 this 값이 어떻게 바뀌고 있는지, 
해당 this가 무슨값인지 알기 위해선 코드의 문맥을 살펴볼 필요가 있습니다.</p>
<h3 id="객체의-메소드를-호출하는-경우">객체의 메소드를 호출하는 경우</h3>
<pre><code class="language-jsx">const myObj = {
    myValue: 6,
    myWindow: this,
    myFunc: function() {
        console.log(this);
    },
    myArrow: () =&gt; {
        console.log(this);
    },
};

console.log(myObj.myFunc()); // myObj 객체
console.log(myObj.myArrow()); // Window 객체</code></pre>
<p>Regular Function과 Arrow Function에 따라 this 의 값이 바뀌었습니다.</p>
<p>MDN에서는 아래와 같이 설명하고 있습니다.</p>
<blockquote>
<p>— 함수를 어떤 객체의 메소드로 호출하면 this의 값은 그 객체를 사용합니다.
— ES2015는 스스로의 this 바인딩을 제공하지 않는 화살표 함수를 추가했습니다.
-MDN web docs-
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this</a></p>
</blockquote>
<p><code>function</code> 키워드는 해당 객체를 바인딩하여 <code>this</code> 의 값을 변경 하는 것이고,</p>
<p><code>() ⇒ {}</code> 는 상위 객체의 this를 그대로 이어받아 사용하는 것입니다. </p>
<h3 id="생성자를-통해-객체를-생성하는-경우">생성자를 통해 객체를 생성하는 경우</h3>
<pre><code class="language-jsx">function Programmer(name, age) {
    this.name = name;
    this.age = age;
}

// 생성자를 사용하지 않은 경우 - 단순 호출
const covy = Programmer(&#39;Covy&#39;, 20); // covy변수는 undefined
console.log(window.name, window.age); //Covy 20

// 생성자를 통한 객체 생성
const tony = new Programmer(&#39;Tony&#39;, 25);
console.log(tony.name, tony.age) // Tony 25 -&gt; this가 해당 객체에 바인딩됨</code></pre>
<p><code>new</code> 키워드를 통해 객체를 생성하면, <code>this</code> 가 해당 객체에 바인딩 되어 해당 값을 읽게 되는것입니다.</p>
<p>es6에 추가된 <code>class</code>  를 사용하면 동일하게 작동하는 것을 볼 수 있습니다.</p>
<h3 id="예외적인-경우">예외적인 경우</h3>
<p>Jquery, React등에 일부 라이브러리에서 엘리먼트에 이벤트를 추가할 때, 
콜백함수에서 <code>this</code> 를 사용하면 값이 바뀌는 경우가 있습니다.</p>
<pre><code class="language-jsx">//Jquery
#(&#39;div&#39;).on(&#39;click&#39;, function() {
    console.log(this) // &lt;div&gt;
    function normalFunc(){
        console.log(this); //Window 객체
    }
    const arrowFunc = () =&gt; {
        console.log(this); // &lt;div&gt;
    }
});</code></pre>
<p>위 코드 처럼 라이브러리 상에서 this를 바인딩 해주는 경우가 있기도 하니
<code>this</code> 를 사용할 때는 해당 라이브러리의 docs를 찾아보는것도 중요합니다.</p>
<p>(특히 Vue!!!! Vue는 stackOverflow나 공식문서를 적극적으로 봐야한다)</p>
<h2 id="applycallbind">apply(),call(),bind()</h2>
<hr>
<p>사실 <code>this</code> 는 이 3개를 이해하기 위한 발판입니다.</p>
<p>자바스크립트에서는 <code>this</code> 를 자유자제로 바꿀 수 있도록 해주는 메소드를 제공하는데,
바로 apply, call, bind 입니다.</p>
<blockquote>
<p>ES5는 함수를 어떻게 호출했는지 상관하지 않고 this값을 설정할 수 있는 bind메서드를 도입했습니다.
-MDN web docs- <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this</a></p>
</blockquote>
<pre><code class="language-jsx">const Tome = {
    age: 25,
    gender: &#39;man&#39;,
};

function printProfile(name) {
    console.log(name, this.age, this.gender);
}

printProfile.call(Tom, &#39;Tom&#39;); // Tom 25 man
printProfile.apply(Tom, [&#39;Tom&#39;]); // Tom 25 man
printProfile.bind(Tom, &#39;Tom&#39;).call(); // Tom 25 man</code></pre>
<ul>
<li>call : 객체를 바인딩 함과 동시에 호출을 합니다.</li>
<li>apply: <code>call</code> 함수와 유사하지만, 매개변수는 배열로 받는것에 있어 차이가 있습니다.</li>
<li>bind: 바인딩이 된 함수를 반환하며, 한번 더 호출시 함수를 실행합니다.</li>
</ul>
<h1 id="마치며">마치며</h1>
<hr>
<p>라이브러리나 프레임워크에 따라 쓰임세가 유동적으로 변하기 때문에 바닐라 JS를 쓰는게 아닌이상 약간의 차이를 감안하고 사용을 해야합니다.</p>
<p>개발을 하면 할수록 중급단계에서 사용빈도수가 높아지고 더 나아가 라이브러리 및 모듈 제작을 할때 적재적소로 활용될수 있으니 확실하게 개념을 짚고 넘어가는게 좋은것같습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] async-storage 를 사용하여 디바이스에 데이터 저장하기]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-async-storage-%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EB%94%94%EB%B0%94%EC%9D%B4%EC%8A%A4%EC%97%90-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%80%EC%9E%A5%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-async-storage-%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%EB%94%94%EB%B0%94%EC%9D%B4%EC%8A%A4%EC%97%90-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%80%EC%9E%A5%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 25 May 2023 03:53:46 GMT</pubDate>
            <description><![CDATA[<h2 id="asyncstorage란">AsyncStorage란?</h2>
<p>암호화 되지 않은 비동기적인 데이터를 관리하는 Key-Value 저장 시스템입니다.</p>
<p>앱 전역에서 사용할 수 있으며, LocalStorage 대신 사용합니다.</p>
<h2 id="사용하는-이유">사용하는 이유</h2>
<p>활용하는 이유와 방법에 대한건 요구사항에 따라 다르겠지만 저는 주로 다음과같은 목적과 이유때문에 사용합니다.</p>
<ol>
<li>redux, redux-toolkit 등의 상태관리와 달리 앱을 종료해도 저장한 값이 유지된다.</li>
<li>보안에 문제되지 않은 한의 저장값들에 대해 활용한다
ex) 로그인 상태 유지의 확인, 앱 설치시 최초1회만 실행되어질 로직에 대한 값</li>
</ol>
<h2 id="설치">설치</h2>
<p>원래는 react-native에서 공식적으로 지원해주었지만 deprecated 되었습니다.
이제는 자체 지원을 중단하고 community packages에 오픈 소스로 만들어진 AsyncStorage를 사용해야 합니다.</p>
<pre><code>npm install @react-native-async-storage/async-storage</code></pre><p>OR</p>
<pre><code>yarn add @react-native-async-storage/async-storage</code></pre><h2 id="사용-방법">사용 방법</h2>
<ol>
<li>AsyncStorage 를 호출하여 Key-Value를 저장하는 함수와 저장한 key 값을 호출하여 value를 불러오는 함수 두가지를 작성하겠습니다.<pre><code class="language-ts">import AsyncStorage from &#39;@react-native-async-storage/async-storage&#39;;
</code></pre>
</li>
</ol>
<p>export const setItem = async (key: string, value: string) =&gt; {
  try {
    await AsyncStorage.setItem(key, value);</p>
<pre><code>// 저장값 확인을 위한 console.log
console.log(`setItem... ${key} : ${value}`);</code></pre><p>  } catch (e) {
    throw e;
  }
};</p>
<p>export const getItem = async (key: string) =&gt; {
  try {
    const res = await AsyncStorage.getItem(key);
    return res || &#39;&#39;;
  } catch (e) {
    throw e;
  }
};</p>
<pre><code>key-value값을 저장하는 setItem 함수와
저장한 key의 value값을 불러오는 getItem 함수를 작성하였습니다.

작성 코드 git 

2. setItem을 호출하여
&#39;key&#39;라는 이름으로 value를 저장하여 asyncStorage에 저장하는 함수를 생성합니다.
```jsx
...
import { setItem } from &#39;src/storage/storage&#39;;

const [asyncValue, setAsyncValue] = useState(&#39;&#39;);
const [stoageValue, setStoageValue] = useState(&#39;&#39;);


const onPressSetAsyncStorage = async () =&gt; {
    try {
      await setItem(&#39;key&#39;, asyncValue);
      confirmAsyncValue();
    } catch (e) {
      console.log(e);
    }
  };

const confirmAsyncValue = async () =&gt; {
    const result = await getItem(&#39;key&#39;);
    setStoageValue(result);
  };
  useEffect(() =&gt; {
    confirmAsyncValue();
  });

  return (
      &lt;View&gt;
        ...
    &lt;/View&gt;
  )</code></pre><h2 id="적용-확인">적용 확인</h2>
<p><img src="https://velog.velcdn.com/images/tmdghks_dev/post/3cd1dd2f-fa24-4762-acd3-8a08ffec9cd7/image.gif" alt=""></p>
<p>다음과같이
redux-toolkit등을 이용한 상태관리 값인 count는 앱을 종료할 시에 값이 유지가 되지 않습니다.</p>
<p>&#39;key&#39;라는 string key값으로 input에 입력한 값을 value로 등록하여 async-storage에 등록한 값은 앱을 종료하여도 그 값이 유지가됨을 확인할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] adb를 이용한 안드로이드 무선 빌드]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EB%AC%B4%EC%84%A0-%EB%B9%8C%EB%93%9C</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EB%AC%B4%EC%84%A0-%EB%B9%8C%EB%93%9C</guid>
            <pubDate>Tue, 16 May 2023 05:45:15 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡 metro에서 ios와 달리 안드로이드는 직접 연결상태에서 빌드하여 그 연결이 끊어지면
실행중인 metro서버와 바로 끊어지는 불편함이 생깁니다.
이를 해결하기 위해 adb를 이용하여 무선연결을 하는 방법을 알아보겠습니다.</p>
</blockquote>
<hr>
<ol>
<li><p><code>adb devices</code> 를 이용하여 연결된 디바이스를 확인합니다.
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/ceb9c738-9c0d-4cd5-90de-2a58aa6fac3f/image.png" alt=""></p>
</li>
<li><p><code>adb tcpip [연결할 port 번호]</code>  를 입력합니다.
ex) adb tcpip 5555
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/a2f88f30-85f8-4408-be93-140e3dc8b586/image.png" alt=""></p>
</li>
<li><p><code>adb connect [metro서버와 Device에 연결된 ip주소]:[연결할 port 번호]</code>  를 입력합니다.port번호를 미입력하면 가장 처음에 설정하였던 port번호가 연결됩니다. 
이후 <code>adb device</code>를 입력하여 확인합니다.
ex) adb connect 192.0.0.0:5555
(= adb connect 192.0.0.0 )</p>
</li>
</ol>
<ul>
<li>주의사항 :  ip주소는 반드시 device의 네트워크에 연결된 ip주소를 적어야 합니다.
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/5ac41069-87a5-4d73-ae88-50f19b8f3d08/image.png" alt=""></li>
</ul>
<ol start="4">
<li>이후 모바일 디바이스와 컴퓨터의 연결을 해제하셔도 무선으로 빌드가 가능합니다.
각자 환경에 맞추어 안드로이드 빌드 하시면 됩니다.
ex) default build ⇒ 
<code>$ npx react-native android run-android</code></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] 폰트 적용 방법]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-%ED%8F%B0%ED%8A%B8-%EC%A0%81%EC%9A%A9-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-%ED%8F%B0%ED%8A%B8-%EC%A0%81%EC%9A%A9-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Thu, 11 May 2023 06:14:42 GMT</pubDate>
            <description><![CDATA[<p>React Native 에서 Custom Fonts를 사용하는 방법입니다.</p>
<h2 id="assets-에-폰트-파일-추가">Assets 에 폰트 파일 추가</h2>
<p>폰트파일을 지정한 위치에 복사하여 넣어줍니다.
(해당 위치는 임의로 설정하면 되고 저는 ~/src/assets/fonts 에 설정 하였습니다.)
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/4d43376e-4658-4902-b885-ca4cada3b954/image.png" alt=""></p>
<h2 id="react-nativeconfig-를-생성하고-font위치를-명시">react-native.config 를 생성하고 font위치를 명시</h2>
<p>프로젝트 루트위치에 react-native.config.js 파일을 만든 후 아래와 코드 같이 assts : { 폰트 저장위치 }를 명시해줍니다</p>
<pre><code>module.exports = {
  assets: [&#39;src/assets/fonts&#39;],
};</code></pre><h2 id="각-플렛폼ios-android에-적용">각 플렛폼(ios, android)에 적용</h2>
<p>그 후 터미널에 npx react-native-asset 를 입력하여 폰트를 적용합니다.</p>
<blockquote>
</blockquote>
<p>react-native의 버전
0.69 초과 :
터미널 내 npx react-native-asset 명령어 입력
0.69 이하 :
터미널 내react-native link 명령어 입력
(적용 후 새로 빌드해주세요)</p>
<h2 id="플랫폼-별-폰트-적용-확인">플랫폼 별 폰트 적용 확인</h2>
<h3 id="android">android</h3>
<p>안드로이드는 android/app/src/main/assets/fonts 에 폰트가 적용되어있는 것을 확인하면 됩니다.</p>
<p><img src="https://velog.velcdn.com/images/tmdghks_dev/post/a4276433-ebe3-4a71-898f-4f7b6f366210/image.png" alt=""></p>
<h3 id="ios">ios</h3>
<p>ios는 ios/{project-name}/Info.plist 에서 확인 할 수 있습니다.
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/59c9d20a-831f-423e-91cc-999aee96dd58/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native] 미사용 변수에 대하여 eslint의 no-unused-vars 규칙 에러 설정]]></title>
            <link>https://velog.io/@tmdghks_dev/React-Native-%EB%AF%B8%EC%82%AC%EC%9A%A9-%EB%B3%80%EC%88%98%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC-eslint-%EC%84%A4%EC%A0%95-%EB%B3%80%EA%B2%BD</link>
            <guid>https://velog.io/@tmdghks_dev/React-Native-%EB%AF%B8%EC%82%AC%EC%9A%A9-%EB%B3%80%EC%88%98%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC-eslint-%EC%84%A4%EC%A0%95-%EB%B3%80%EA%B2%BD</guid>
            <pubDate>Tue, 09 May 2023 08:13:32 GMT</pubDate>
            <description><![CDATA[<h2 id="상황">상황</h2>
<hr>
<p>프로젝트를 처음 설정하다보면 사용하고 있지않은 값에 대해 다음과 같이 경고가 표시되고 있습니다.
<img src="https://velog.velcdn.com/images/tmdghks_dev/post/54545b67-aef8-4f48-819c-95ba05b9e804/image.png" alt=""></p>
<p>기능과 성능상으로는 문제가 없지만 실제 문제가 생기는 부분과 햇갈릴수 있으므로 수정해보겠습니다.</p>
<h2 id="해결">해결</h2>
<hr>
<p>해당 경고문에 다음과 같은 문구가 있습니다.</p>
<pre><code>eslint(@typesript-eslint/no-unused-vars)</code></pre><p>다음 사이트에 TypeScript의 eslint 규칙을 참조해보니 해당 옵션으로 설정할 수 있을거같습니다.
<a href="https://typescript-eslint.io/rules/no-unused-vars/">https://typescript-eslint.io/rules/no-unused-vars/</a></p>
<p><img src="https://velog.velcdn.com/images/tmdghks_dev/post/b516ef21-0653-4582-afb1-79a4f7a7afad/image.png" alt=""></p>
<p>저는 package.json에서 eslint룰을 설정하여 해결 하였습니다.</p>
<pre><code>&quot;eslintConfig&quot;: {
    &quot;extends&quot;: [
      &quot;@react-native-community&quot;,
      &quot;prettier&quot;,
      &quot;plugin:react/jsx-runtime&quot;,
      &quot;plugin:@typescript-eslint/recommended&quot;
    ],
    &quot;rules&quot;: {
      &quot;no-unused-vars&quot;: &quot;off&quot;,
      &quot;@typescript-eslint/no-unused-vars&quot;: [
        &quot;warn&quot;
      ]
    }
  },</code></pre><p>그리고 다음 typescript-eslint를 설정하기 위해선 다음의 패키지(<strong>@typescript-eslint/parser @typescript-eslint/eslint-plugin</strong>)를 
devDependencies 에 추가해준 이후 reload하여 확인하면 됩니다.</p>
<pre><code>yarn add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin</code></pre><h4 id="적용이-된-이후에-경고가-없어진-화면">적용이 된 이후에 경고가 없어진 화면</h4>
<p><img src="https://velog.velcdn.com/images/tmdghks_dev/post/85094558-ae0d-4347-84fb-77e5a3f54286/image.png" alt=""></p>
<h1 id="추가">추가</h1>
<p>만약 모든 설정 적용후에도 설정이 되지않는다면
루트 폴더에 있는 .eslintrc.js 를 제거하고 리로드 해보세요!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React-Native]프로젝트 생성중 ruby 버전 불일치]]></title>
            <link>https://velog.io/@tmdghks_dev/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%83%9D%EC%84%B1%EC%A4%91-ruby-%EB%B2%84%EC%A0%84-%EB%B6%88%EC%9D%BC%EC%B9%98</link>
            <guid>https://velog.io/@tmdghks_dev/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%83%9D%EC%84%B1%EC%A4%91-ruby-%EB%B2%84%EC%A0%84-%EB%B6%88%EC%9D%BC%EC%B9%98</guid>
            <pubDate>Tue, 09 May 2023 06:29:04 GMT</pubDate>
            <description><![CDATA[<h2 id="에러메시지">에러메시지</h2>
<hr>
<p><code>react-native error Your Ruby version is 2.6.8, but your Gemfile specified 2.7.5</code></p>
<h2 id="원인">원인</h2>
<hr>
<p>mac은 기본적으로 ruby가 설치되어있지만 reactNative를 설치하기 위해서는 버전에 맞는 ruby가 설치되어 있어야 합니다.</p>
<h2 id="해결">해결</h2>
<hr>
<p>따로 ruby 패키지 매니저를 설치하여 버전을 맞춰주었다. 나는 rbenv 사용하였습니다.</p>
<ol>
<li>우선 rbenv로 원하는 버전을 설치합니다.</li>
</ol>
<pre><code class="language-bash">rbenv install 2.7.5
rbenv global 2.7.5
rbenv local 2.7.5</code></pre>
<p>그후 ruby —version 으로 버전을 확인해보면 여전히 2.6.8로 버전이 바뀌지 않았습니다.
아직 설치 경로가 그대로이기 때문입니다.
따라서 새로 설치된 루비 경로를 환경 변수에 추가해주어야 합니다,</p>
<p>제 경우는 ~/.zshrc 를 수정하였습니다.</p>
<ol>
<li>루비 환경변수 추가</li>
</ol>
<pre><code class="language-bash">[[ -d ~/.rbenv  ]] &amp;&amp; \
export PATH=${HOME}/.rbenv/bin:${PATH} &amp;&amp; \
eval &quot;$(rbenv init -)&quot;</code></pre>
<p>이후 저장하고 다시 루비 버전을 확인하면 2.7.5로 변경되있는것을 확인할 수 있습니다.</p>
]]></description>
        </item>
    </channel>
</rss>