<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>강디너의 개발 일지</title>
    <link>https://kdinner.tistory.com/</link>
    <description>주니어 개발자의 개발 일지</description>
    <language>ko</language>
    <pubDate>Sat, 13 Jun 2026 00:50:37 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>강디너</managingEditor>
    <item>
      <title>React Native + WebView + 카카오 지도 연동 삽질기 (with Expo)</title>
      <link>https://kdinner.tistory.com/129</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js로 만든 기존 서비스를 앱으로 확장하고 싶었다. 그래서 Expo를 선택했고, 그 과정에서 카카오 지도를 붙이며 겪은 문제들과 해결 방법을 정리해본다. 이 글은 완벽한 가이드라기보다는 내가 실제 겪은 시행착오를 기록하는 삽질기에 가깝다. (지금도 만들고 있는데 계속 작성할수도 있다...)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-end=&quot;307&quot; data-start=&quot;277&quot; data-ke-size=&quot;size23&quot;&gt;Next.js 서비스 &amp;rarr; 앱으로 만들기 시작&lt;/h3&gt;
&lt;p data-end=&quot;389&quot; data-start=&quot;309&quot; data-ke-size=&quot;size16&quot;&gt;부동산에 관심이 많았었기에 국토부 실거래 자료를 기반으로 한 웹 기반의 Next.js로 만든 서비스가 있었다.&lt;/p&gt;
&lt;p data-end=&quot;389&quot; data-start=&quot;309&quot; data-ke-size=&quot;size16&quot;&gt;&quot;이걸 앱으로 만들어보고 광고를 한번 붙여봐 ?&quot; 라고 결정하고, Expo를 사용해 개발을 시작했다. 이유는 단순했다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;462&quot; data-start=&quot;391&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;421&quot; data-start=&quot;391&quot;&gt;React 기반이라 코드 재사용이 쉬울 것 같았고,&lt;/li&gt;
&lt;li data-end=&quot;437&quot; data-start=&quot;422&quot;&gt;배포가 빠를 것 같았고,&lt;/li&gt;
&lt;li data-end=&quot;462&quot; data-start=&quot;438&quot;&gt;네이티브 개발을 하고 싶지 않았고,&lt;/li&gt;
&lt;li data-end=&quot;462&quot; data-start=&quot;438&quot;&gt;이전엔 CLI로 한번 개발을 했었는데, Expo도 한번 이참에 해보고 싶었기 때문.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;488&quot; data-start=&quot;469&quot; data-ke-size=&quot;size23&quot;&gt;Expo로 앱 개발 시작&lt;/h3&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;490&quot; data-ke-size=&quot;size16&quot;&gt;React Native 자체도 초보였던 나는 Expo로 빠르게 프로젝트를 시작했다. &lt;b&gt;Expo Go&lt;/b&gt;로 테스트할 수 있어서 서버 올릴 필요 없이 바로 앱에서 확인할 수 있는 점이 좋았다. CLI와 다르게 안드로이드 스튜디오, Xcode가 없이 테스트 가능하다는게 너무 좋았다. 세팅하는게 개발자의 최고의 귀차니즘이니깐...&lt;/p&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;490&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;624&quot; data-start=&quot;599&quot; data-ke-size=&quot;size23&quot;&gt;카카오 지도 연동 &amp;ndash; 시작부터 막힘&lt;/h3&gt;
&lt;p data-end=&quot;678&quot; data-start=&quot;626&quot; data-ke-size=&quot;size16&quot;&gt;문제는 카카오 지도였다. 기존 웹에서는 쉽게 붙였던 카카오 지도가 앱에서는 생각보다 어려웠다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;793&quot; data-start=&quot;680&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;718&quot; data-start=&quot;680&quot;&gt;Expo는 네이티브 SDK(안드로이드/iOS)를 사용할 수 없다.&lt;/li&gt;
&lt;li data-end=&quot;753&quot; data-start=&quot;719&quot;&gt;카카오에서 제공하는 React Native SDK도 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;855&quot; data-start=&quot;795&quot; data-ke-size=&quot;size16&quot;&gt;그래서 &lt;b&gt;WebView로 카카오 지도 웹 SDK를 불러서 띄우는 방식&lt;/b&gt;을 선택했다. 여기까지는 괜찮았다.&lt;/p&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;490&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;891&quot; data-start=&quot;862&quot; data-ke-size=&quot;size23&quot;&gt;마커 찍기 실패 &amp;ndash; Geocoder의 배신&lt;/h3&gt;
&lt;p data-end=&quot;1024&quot; data-start=&quot;893&quot; data-ke-size=&quot;size16&quot;&gt;문제는 &lt;b&gt;특정 주소에 마커를 찍는 것&lt;/b&gt;이었다. 기존 웹 서비스에서는 문제없이 성공했었다. 그래서 자연스럽게 카카오에서 제공하는 &lt;b&gt;kakao.maps.services.Geocoder&lt;/b&gt;를 사용했다.&lt;/p&gt;
&lt;p data-end=&quot;1040&quot; data-start=&quot;1026&quot; data-ke-size=&quot;size16&quot;&gt;하지만 결과는 계속 실패.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1121&quot; data-start=&quot;1042&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1061&quot; data-start=&quot;1042&quot;&gt;status 값은 항상 null&lt;/li&gt;
&lt;li data-end=&quot;1081&quot; data-start=&quot;1062&quot;&gt;result 값은 &quot;ERROR&quot;&lt;/li&gt;
&lt;li data-end=&quot;1121&quot; data-start=&quot;1082&quot;&gt;Web에서는 잘 되던 코드가 앱(WebView) 안에서는 실패했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-start=&quot;2059&quot; data-end=&quot;2092&quot; data-ke-size=&quot;size16&quot;&gt;WebView 안에서 지도를 띄우면서 이런 불편함도 있었다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;2094&quot; data-end=&quot;2240&quot;&gt;
&lt;li data-start=&quot;2094&quot; data-end=&quot;2133&quot;&gt;WebView에서는 DevTools가 안 보이므로 디버깅이 어렵다.&lt;/li&gt;
&lt;li data-start=&quot;2134&quot; data-end=&quot;2185&quot;&gt;로컬에서 지도 WebView가 보이지 않아서 테스트할 때 매번 핸드폰으로 확인해야 했다.&lt;/li&gt;
&lt;li data-start=&quot;2186&quot; data-end=&quot;2240&quot;&gt;React Native &amp;harr; WebView 통신도 postMessage로 일일이 처리해야 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-start=&quot;2242&quot; data-end=&quot;2300&quot; data-ke-size=&quot;size16&quot;&gt;그래도 메시지 핸들러를 만들어서 로그를 찍어가며 디버깅했다. AI한테도 자주 물어보면서 많은 시간을 아꼈다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-start=&quot;2242&quot; data-end=&quot;2300&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1179&quot; data-start=&quot;1155&quot; data-ke-size=&quot;size16&quot;&gt;정말 하루동안 세상에 나온 AI들을 다 괴롭혀본것 같다.&lt;/p&gt;
&lt;p data-end=&quot;1179&quot; data-start=&quot;1155&quot; data-ke-size=&quot;size16&quot;&gt;하지만 전부 실패하고야 말았고 아래와 같은 결론을 내렸다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1344&quot; data-start=&quot;1181&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1213&quot; data-start=&quot;1181&quot;&gt;&lt;b&gt;카카오 Geocoder는 서버 호출이 필요하다.&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1296&quot; data-start=&quot;1214&quot;&gt;그런데 WebView에서 실행되는 HTML의 origin은 보통 file://, about:blank, localhost로 인식된다.&lt;/li&gt;
&lt;li data-end=&quot;1344&quot; data-start=&quot;1297&quot;&gt;카카오 개발자센터에서 등록한 도메인이 아니면 Geocoder 호출 자체가 막힌다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1441&quot; data-start=&quot;1346&quot; data-ke-size=&quot;size16&quot;&gt;즉, 지도가 로컬에서 잘 보였던 것은 SDK 자체는 클라이언트에서 동작하기 때문이고, 좌표 검색(Geocoder)은 서버에서 동작하기 때문에 도메인 제한에 걸렸다고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;1441&quot; data-start=&quot;1346&quot; data-ke-size=&quot;size16&quot;&gt;(허용 도메인에 로컬호스트, file:// 등을 등록해봤지만 당연히 실패)&lt;/p&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;490&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;490&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1545&quot; data-start=&quot;1510&quot; data-ke-size=&quot;size16&quot;&gt;결국 카카오 문서를 다시 뒤져서 다른 API 방식을 찾았다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1725&quot; data-start=&quot;1547&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1592&quot; data-start=&quot;1547&quot;&gt;&lt;b&gt;카카오에서 제공하는 주소 &amp;rarr; 좌표 변환 WEB API&lt;/b&gt;를 쓰기로 결정.&lt;/li&gt;
&lt;li data-end=&quot;1632&quot; data-start=&quot;1593&quot;&gt;앱에서는 서버 통신이 허용되므로, 이 API는 문제없이 호출 가능.&lt;/li&gt;
&lt;li data-end=&quot;1665&quot; data-start=&quot;1633&quot;&gt;WebView 안에서 Geocoder 쓰기를 포기하고,&lt;/li&gt;
&lt;li data-end=&quot;1725&quot; data-start=&quot;1666&quot;&gt;React Native 코드 단에서 API로 좌표를 가져와서 WebView로 넘겨주기로 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1756&quot; data-start=&quot;1727&quot; data-ke-size=&quot;size16&quot;&gt;좌표를 받으면 WebView에 마커를 찍으면 되니까...&lt;/p&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;490&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;490&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;592&quot; data-start=&quot;490&quot; data-ke-size=&quot;size23&quot;&gt;REST API 호출 &amp;rarr; 비용 발생 &amp;rarr; 캐싱 도입&lt;/h3&gt;
&lt;p data-end=&quot;1839&quot; data-start=&quot;1798&quot; data-ke-size=&quot;size16&quot;&gt;테스트 중 API를 생각보다 너무 많이 쏘는 것 처럼 느껴졌다.&lt;/p&gt;
&lt;p data-end=&quot;1839&quot; data-start=&quot;1798&quot; data-ke-size=&quot;size16&quot;&gt;REST API 호출은 무료가 아니다. 호출이 늘어날수록 비용이 발생한다. 돈벌려고 시작했는데 돈쓰는 서비스가 된다면 섭종이다.&lt;/p&gt;
&lt;p data-end=&quot;1880&quot; data-start=&quot;1841&quot; data-ke-size=&quot;size16&quot;&gt;그래서 React Query를 도입했다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1994&quot; data-start=&quot;1882&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1917&quot; data-start=&quot;1882&quot;&gt;주소 &amp;rarr; 좌표는 거의 변하지 않으므로 캐싱해도 문제가 없다.&lt;/li&gt;
&lt;li data-end=&quot;1917&quot; data-start=&quot;1882&quot;&gt;다른 Kakao API들도 길게 캐싱해도 문제 없다.&lt;/li&gt;
&lt;li data-end=&quot;1941&quot; data-start=&quot;1918&quot;&gt;처음에는 App.tsx에서 설정했지만,&lt;/li&gt;
&lt;li data-end=&quot;1994&quot; data-start=&quot;1942&quot;&gt;Expo Router를 쓰면서 _layout.tsx에 적용해야 한다는 것도 알게 됐다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2021&quot; data-start=&quot;1996&quot; data-ke-size=&quot;size16&quot;&gt;덕분에 호출 비용도 아끼고, 속도도 개선됐다.&lt;/p&gt;
&lt;p data-end=&quot;2021&quot; data-start=&quot;1996&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;490&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;2323&quot; data-start=&quot;2307&quot; data-ke-size=&quot;size23&quot;&gt;마무리&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2575&quot; data-start=&quot;2325&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2386&quot; data-start=&quot;2325&quot;&gt;카카오 지도 SDK는 웹에서는 편하지만, 앱에서는 도메인 제한 때문에 일부 기능이 막힌다.&lt;/li&gt;
&lt;li data-end=&quot;2438&quot; data-start=&quot;2387&quot;&gt;지도는 WebView에서 띄우되, 좌표 변환은 REST API로 처리하는 것이 안전하다.&lt;/li&gt;
&lt;li data-end=&quot;2482&quot; data-start=&quot;2439&quot;&gt;REST API 호출은 캐싱이 중요하다. 비용이 실제로 발생하기 때문이다.&lt;/li&gt;
&lt;li data-end=&quot;2575&quot; data-start=&quot;2483&quot;&gt;WebView 안에서 마커, 정보창 등은 HTML/JS에서 처리하고, 부모 React Native와 통신은 postMessage로 단순화하는 게 유지보수에 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2704&quot; data-start=&quot;2593&quot; data-ke-size=&quot;size16&quot;&gt;React Native + WebView로 카카오 지도를 붙이는 건 생각보다 쉬웠지만,&lt;br /&gt;&lt;b&gt;주소 &amp;rarr; 좌표 변환이 막히면서 하루 넘게 삽질했다.&lt;/b&gt;&lt;br /&gt;다음에는 더 빠르게 해결할 수 있을 것 같다.&lt;/p&gt;
&lt;p data-end=&quot;2704&quot; data-start=&quot;2593&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2797&quot; data-start=&quot;2706&quot; data-ke-size=&quot;size16&quot;&gt;지금도 React Native에서 카카오 지도를 붙이려는 사람이 있다면&amp;hellip;&lt;br /&gt;&lt;b&gt;WebView 안에서 Geocoder 쓰지 말고, REST API로 처리하세요.&lt;/b&gt;&lt;/p&gt;</description>
      <category>Javascript/삽질</category>
      <author>강디너</author>
      <guid isPermaLink="true">https://kdinner.tistory.com/129</guid>
      <comments>https://kdinner.tistory.com/129#entry129comment</comments>
      <pubDate>Tue, 22 Jul 2025 16:00:25 +0900</pubDate>
    </item>
    <item>
      <title>테이블링으로 이직한 건에 대하여...</title>
      <link>https://kdinner.tistory.com/128</link>
      <description>&lt;div&gt;기술 블로그에 기술을 안적고 계속 회고만 하는 것 같다. 이게 나이를 먹으면 말만 많아진다는 것일까...&lt;b&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그래서 이번에는 어디에 갔는가 ?&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;테이블링이라는 맛집 줄서기 서비스 를 운영하는 회사에 갔다.&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;site.png&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;494&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcVHJr/btsIsuDuVKX/95DdY66uBpgqOwizNWOGA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcVHJr/btsIsuDuVKX/95DdY66uBpgqOwizNWOGA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcVHJr/btsIsuDuVKX/95DdY66uBpgqOwizNWOGA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcVHJr%2FbtsIsuDuVKX%2F95DdY66uBpgqOwizNWOGA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;365&quot; height=&quot;191&quot; data-filename=&quot;site.png&quot; data-origin-width=&quot;945&quot; data-origin-height=&quot;494&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그곳은 왜 갔는가 ?&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;먹을 것을 좋아하는 나는 맛집을 가는 것도 좋아한다. 가성비를 따지기는 하지만, 먹기 위해 돈버는 스타일? 이기 때문에 먹는 것에 아끼지 않는 편이다. 그렇기에 맛집에서 줄 서는 서비스인 테이블링을 이미 알고 있었다. (예전에는 웹으로도 봤었는데, 지금은 접었다고 한다.)&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;특히 면접 분위기가 너무 좋았고, 팀 분위기도 좋아 보였다. (이게 제일 컸던 것 같다)&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할은 무엇인가 ?&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;미들급 FE개발자? 의욕 빵빵한 개발자 ?&lt;/div&gt;
&lt;div&gt;팀장 말 잘듣고 열심히 개발하는 실무자?&lt;/div&gt;
&lt;div&gt;이런 역할이지 않을까 싶다.&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfJm7s/btsIpJCmOd5/MrGQjvADCyQ5ZaoZcdEqOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfJm7s/btsIpJCmOd5/MrGQjvADCyQ5ZaoZcdEqOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfJm7s/btsIpJCmOd5/MrGQjvADCyQ5ZaoZcdEqOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfJm7s%2FbtsIpJCmOd5%2FMrGQjvADCyQ5ZaoZcdEqOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;268&quot; height=&quot;268&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3개월간 무엇을 했는가 ?&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;맨 처음은 기존 프로젝트들 구경하면서 분위기 파악을 먼저 했다. 하지만 코드를 눈으로만 보면 졸린법&amp;hellip;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kYJ7f/btsIp8CbKnY/a89ERJVVZMUvHHTbv4sekk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kYJ7f/btsIp8CbKnY/a89ERJVVZMUvHHTbv4sekk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kYJ7f/btsIp8CbKnY/a89ERJVVZMUvHHTbv4sekk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkYJ7f%2FbtsIp8CbKnY%2Fa89ERJVVZMUvHHTbv4sekk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;407&quot; height=&quot;549&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;뭔가 내 손가락을 움직일만한 것을 찾아봤다. 마침 기존 vue 프로젝트들을 next로 마이그레이션 작업과 개선 작업을 진행하고 있었는데, next를 공부해 보고 싶어서 티켓들을 몇개 가져갔다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;이전 회사에서 문서로 적고, 공유했던 경험이 좋았어서 이번에도 문서 작성을 했는데 Next.js의 세션/인증 관리, tanstack-query 등등 관련 문서를 공유했고 다들 좋아해 주셨다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;자그마한 작업들을 진행하다가 결제라는 큰 프로젝트를 맡아버렸다. 어드민쪽만 주로 진행하다가 사용자쪽을 개발하려다 보니깐 어색했고, 더 꼼꼼히 봐야만 해서 부담이 있었다. 그래도 기획부터 디자인, QA까지 모두 꼼꼼하게 봐주셔서 큰 이슈 없이 진행되었다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;그 외로는 일 달라고 팀장님 조르는데 재미있다.&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;목표는 무엇인가 ?&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;다양한 상황들을 맞닥뜨리면서 시니어 개발자로 성장하고 싶다.&lt;/div&gt;
&lt;div&gt;앞으로도 계속 즐겁게 일하고 싶다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;보통 개발자 목표는 더욱 기술적으로 성장하고 싶다가 있을 것 같다. 하지만 나는 기술적으로 깊게 성장하고 싶나 ? 라는 생각이 요즘 든다. 나에게 필요한 경우에만 깊이 있게 파고드는 것 같다. 싫어하진 않지만 좋아하지도 않는 ? 원래 문서화도 별로 좋아하지 않았는데, 필요한 경우에 마음먹고 하는 것 같다. (포스팅도 비슷한가&amp;hellip;)&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;여전히 사람들과 커뮤니케이션을 하면서 작업하는 것이 좋기 때문에 문제 일으키지 않고 잘 ? 다니고 싶다.&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bT5lut/btsIpKuxfUd/OJ7Wy9NBYMxV5kdU6hQAl1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bT5lut/btsIpKuxfUd/OJ7Wy9NBYMxV5kdU6hQAl1/img.jpg&quot; data-alt=&quot;오늘도 개발자가 안된다고 말했다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bT5lut/btsIpKuxfUd/OJ7Wy9NBYMxV5kdU6hQAl1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbT5lut%2FbtsIpKuxfUd%2FOJ7Wy9NBYMxV5kdU6hQAl1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;362&quot; height=&quot;318&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;오늘도 개발자가 안된다고 말했다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3개월 후기는 ?&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;프레임워크만 바뀌었지 FE개발을 그대로 하는거라 일하는데에 특별히 어려움은 없었다. 히스토리를 계속 쌓아가면서 도메인 지식 도 늘리고 있어서 이 부분이 익숙해지면 더욱 잘 할 수 있을 것 같다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;한달에 한번 테이블링의 먹부심을 자극하는 개인/팀 회식이 있다. 개인회식은 인당 5만원까지 지원해주는데 최고다&amp;hellip;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;최소 인원 제한이 있어서 공개모집도 하기 때문에 친해지고 싶은(또는 먹고 싶은 음식) 파티에 가벼운 마음으로 참여가 가능하다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;회사 분위기가 매우 좋은 것 같다. 일도 즐겁게 하고 있어서 아내가 엄청 부러워한다. (기획자 자리 없냐고 묻는다.)&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;최근에 대표님이 팀별 미팅을 하셨는데, 24년 하반기가 정말 중요하니 잘 부탁한다고 하셨다. 그리고 일에 더욱 집중을 원한다고 하시며 &lt;b&gt;재택을 하루 더 늘려버리고 재택 근무시간을 자율&lt;/b&gt;로 바꿔버리셨다. &lt;b&gt;(아내가 또 기획자 자리 없냐고 묻는다.)&lt;/b&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아, 재택이 있다는 것을 미리 알고 있었기 때문에 고양이를 한 마리 입양했다. 고양이 두 마리와 같이 햄볶하게 일하고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_KakaoTalk_Photo_2024-07-08-15-32-09.jpeg&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;1074&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wWR9e/btsIqAkYmok/6FluAunmAklUBWeK2hYvJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wWR9e/btsIqAkYmok/6FluAunmAklUBWeK2hYvJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wWR9e/btsIqAkYmok/6FluAunmAklUBWeK2hYvJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwWR9e%2FbtsIqAkYmok%2F6FluAunmAklUBWeK2hYvJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;355&quot; height=&quot;473&quot; data-filename=&quot;edited_KakaoTalk_Photo_2024-07-08-15-32-09.jpeg&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;1074&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>회고록</category>
      <author>강디너</author>
      <guid isPermaLink="true">https://kdinner.tistory.com/128</guid>
      <comments>https://kdinner.tistory.com/128#entry128comment</comments>
      <pubDate>Tue, 9 Jul 2024 16:19:36 +0900</pubDate>
    </item>
    <item>
      <title>새로운 시작... feat. 시니어 개발자를 향하여</title>
      <link>https://kdinner.tistory.com/127</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;또 이직을 했다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약 2년 6개월 와디즈를 다녔고, 올해 3월 마무리를 했다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;(이제야&lt;span&gt;&amp;nbsp;&lt;/span&gt;회고를 적는다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 지식뿐만 아니라&lt;span&gt;&amp;nbsp;&lt;/span&gt;문서화, 개발 프로세스 등 개발자에게 필요한 많은 것들을 배우 며 성장했다고 생각한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이직이 확정되었을 때 기쁨보다 동료들에게 어떻게 말해야 하나 싱숭생숭했다. 그만큼 팀 분위기가 너무 좋아서 떠나는 게 맘 편하지 않았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMS4ms/btsHSvkBejJ/JgwRK2aGeOMX2IGogLwrFK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMS4ms/btsHSvkBejJ/JgwRK2aGeOMX2IGogLwrFK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMS4ms/btsHSvkBejJ/JgwRK2aGeOMX2IGogLwrFK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMS4ms%2FbtsHSvkBejJ%2FJgwRK2aGeOMX2IGogLwrFK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;398&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;224&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;왜 또 이직을 했는가?&lt;/b&gt;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;이력서를 정리하다 보니 벌써 8년 차가 되어버렸다. 쭈니어일때 10년차 개발자는 완전 능력자 + 시니어 개발자라고 생각했는데, 내가 곧 10년 차라는 생각에 덜컥 겁이 나버렸다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;와디즈에는 시니어 FE 분들이 많아 보살핌을 듬뿍 받고 자라서, 만약 이분들이 없어진 상태에서 10년 차가 넘어버린다면&amp;hellip;? 이라는 생각이 드는 순간 뭔가 준비를 해야 할 것 같았다. 이게 시작이었다.&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;
&lt;div&gt;다시 생각해 보면 딜리셔스에서 와디즈로 이직할 때에도 비슷했던 것 같다.&lt;/div&gt;
&lt;div&gt;2년 반 정도 일했었고, 일도 어느 정도 익숙해졌었으며 팀 동료들이 좋아서 이직하기 싫었다.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;다른 점이 있다면 딜리셔스 때에는 규모가 더 큰 곳에서, 더 많고 다양한 것들을 경험해 보고 싶어서 이직했었다.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;와디즈에서 이직할 때에는  연차만 찬 시니어 개발자가 되고 싶지 않았다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;와디즈를 떠날 때 팀원들에게 했던 말이 기억에 난다. 더 늦기 전에 이리저리 굴러다닌 &lt;b&gt;시니어 개발자&lt;/b&gt;가 되고 싶다고...&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;259&quot; data-origin-height=&quot;195&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b40yY3/btsHSTL5Ex1/fBkVEC7X7CrUVLmkAX9sE0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b40yY3/btsHSTL5Ex1/fBkVEC7X7CrUVLmkAX9sE0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b40yY3/btsHSTL5Ex1/fBkVEC7X7CrUVLmkAX9sE0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb40yY3%2FbtsHSTL5Ex1%2FfBkVEC7X7CrUVLmkAX9sE0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;301&quot; data-origin-width=&quot;259&quot; data-origin-height=&quot;195&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;b&gt;지원하는 회사 기준은 ?&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 내가 자주 사용할 수 있는 또는 평소에 관심이 있는 분야의 서비스에 지원했었다.&lt;/p&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;와디즈 때 이 부분이 매우 좋았다. 와디즈에서는 분기마다 25만 복지 포인트를 줬는데, 주로 좋아하는 먹거리를 많이 구매했다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;서비스를 사용하면서 몰랐었던 기능도 써보고, 버그도 찾고 개선도 하면서 애정이 많이 들어갔었다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;서비스가 크다 보면 내가 담당하지 않는 부분은 잘 모르게 되는데, 사용자가 되어보니 구석구석 보게 된 것 같았다.&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;2. 와디즈보다 규모가 작은 스타트업을 생각했다.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;규모가 큰 경우에는 의사결정을 해야 하는 관계자가 많고, 프로세스의 복잡성 때문에 마음껏 날뛸 수 없었다.&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;그래서 나는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;이리저리 굴러다니며 개발할 수 있으려면 규모가 조금 작아야 하지 않을까?&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;라는 생각을 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무 작으면 힘들 것 같았지만, 그건 그때 가서 생각해 보려고 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;3. 회사가 돈을 잘 벌었으면 하는 소망이 있었다.&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 나는 가정 있는 사람이라는 것을 잊지 말아야 했다. 내가 싱글이고, 도전정신이 뿜뿜하다면 완전 초기 스타트업에 도전할 수 있었겠지만... 지금은 사정이 달랐다. 그래서 돈도 잘 벌고 미래가 창창해 보이는 곳을 찾았다.&lt;/p&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSVLWl/btsHUSLu21r/5wzLWVXlm5pm1kjP0B3MG1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSVLWl/btsHUSLu21r/5wzLWVXlm5pm1kjP0B3MG1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSVLWl/btsHUSLu21r/5wzLWVXlm5pm1kjP0B3MG1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSVLWl%2FbtsHUSLu21r%2F5wzLWVXlm5pm1kjP0B3MG1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;391&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;b&gt;지원 결과&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;color: #000000; text-align: start;&quot;&gt;두  군데에 최종 합격했다. (최소 열 군데 이상 떨어졌다.)&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이력서는 꾸준히 관리를 하면서 나의 매력 어필을 많이 하려고 노력해서 그런지 서류 탈락은 적었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 알고리즘 공부를 게을리해서... 코딩테스트는 많이 떨어졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과제는 반반이었던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋았던 경험이 있었는데, 테스트 케이스가 다 준비되어 있어서 내가 작업한 것을 기반으로 테스트를 돌려서 성공/실패가 보이는 것이었다. 그리고 또 하나는 PR을 하나 주고, 해당 PR을 리뷰해달라는 과제였다. 주니어가 올린 PR이니 조언도 함께 해주라는 조건이 있었는데, 이 부분은 매우 신선했고 재미있게 과제를 진행했던 기억이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;합격한 두 군데 전부 먹거리 관련된 곳이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 합격한 곳은 M&amp;amp;A 를 고려해서 약 30인의 소규모 회사를 운영하고 있었고, 두 번째 합격한 곳은 100명 정도의 규모며, 내가 자주 본 서비스를 운영하는 회사였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 회사의 첫인상이 매우 좋았는데, 매우 솔직하게 전부 이야기 해주었다. 투자가 미뤄져 구조조정을 했지만, 다시 재투자를 받아서 필수 인원을 뽑는 것과 언제까진 안전하게 운영 가능한지 전부 알려주었다. 회사 입장에서 다 털어놓기 힘들었을 텐데 이 부분에서 감동을 받았었다. 하지만 여러 고민 끝에 불확실성이 너무 크다 판단해서 드랍하고, 두 번째 회사로 결정했다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;(사실 내가 사용했던 서비스라는 점도 가점에 들어갔다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이직 회고를 퇴사하고 두달이 넘어서야 겨우 마무리를 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 포스팅에는 합격한 곳에 대해 적어보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>회고록</category>
      <author>강디너</author>
      <guid isPermaLink="true">https://kdinner.tistory.com/127</guid>
      <comments>https://kdinner.tistory.com/127#entry127comment</comments>
      <pubDate>Mon, 10 Jun 2024 17:47:23 +0900</pubDate>
    </item>
    <item>
      <title>React Native로 앱 만들기 - 나에게 필요한 서비스 만들기</title>
      <link>https://kdinner.tistory.com/126</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;작년부터 난 만들고 싶은 서비스가 생겼었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 냉장고 관리 앱이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPnFRK/btsC2vCtYHw/Ak581eokcBUtmzn6KFBcH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPnFRK/btsC2vCtYHw/Ak581eokcBUtmzn6KFBcH0/img.png&quot; data-alt=&quot;작년 1월 16일에 처음글을 작성했었다...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPnFRK/btsC2vCtYHw/Ak581eokcBUtmzn6KFBcH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPnFRK%2FbtsC2vCtYHw%2FAk581eokcBUtmzn6KFBcH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;678&quot; height=&quot;231&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;작년 1월 16일에 처음글을 작성했었다...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혼자 살 때에는 냉장고에 김치밖에 없었는데, 결혼을 하고 나니 냉장고가 터지려고 했다. 특히 냉동실에 넣고 까먹은 재료들이 발굴될 때마다 너무 마음이 아팠다. 나는 이 문제를 해결하고자 냉장고 관리 앱들을 찾아봤지만 내가 만족스러운 앱이 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;내가 원하는 서비스가 없는데 직접 만들자&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;(기획자/개발자 부부의 고질병)&lt;/p&gt;
&lt;figure style=&quot;color: #333333; text-align: center;&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/niniz/large/035.gif&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-name=&quot;035&quot; data-emoticon-type=&quot;niniz&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;emoticon&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/niniz/large/035.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 나는 아이디어와 개발 능력만 있지 서비스를 기획/디자인 하지 못했다. 그렇기에 아내를 열심히 꼬셨다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;넘치는 아이디어와 왜 이 서비스를 써야 하는지 정리를 했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 서비스를 만들게 된 계기&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;결혼 후 집에서 밥을 많이 해 먹는다.&lt;/li&gt;
&lt;li&gt;냉장고/냉동실이 터지려고 한다.&lt;/li&gt;
&lt;li&gt;언제나 진수성찬을 해 먹는 것이 아닌 생존요리 &amp;amp; 잔반처리 용 요리를 자주 해 먹는다.&lt;/li&gt;
&lt;li&gt;매일 메뉴를 정하는 것은 고민거리다.&lt;/li&gt;
&lt;li&gt;가끔 별 5점짜리 메뉴가 종종 등장한다.&lt;/li&gt;
&lt;li&gt;이 메뉴의 레시피를 기록하지 않아서 다시 찾아봐야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우리 냉장고의 문제&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;냉장고에 무엇이 생존해 있는가&lt;/li&gt;
&lt;li&gt;냉장고에 무엇을 빨리 처리해야 하는가&lt;/li&gt;
&lt;li&gt;냉동실에 무엇을 넣었던가&lt;/li&gt;
&lt;li&gt;고기인 것 같은데 너는 어떤 부위인가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;어떤 앱을 만들고 싶은가&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자가 재료/레시피를 등록하면 관리를 도와주는 서비스다.&lt;/li&gt;
&lt;li&gt;서비스가 남아있는 재료 기준으로 적합한 레시피를 추천한다.&lt;/li&gt;
&lt;li&gt;서비스가 자동으로 유통기한을 트래킹 해준다.&lt;/li&gt;
&lt;li&gt;유통기한이 임박하면 알림이 온다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발 목표&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유지비가 들지 않는 것이 중요하다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;웹서버는 유지비가 들기 때문에 앱으로 개발하자&lt;/li&gt;
&lt;li&gt;React Native를 이용하면 러닝커브가 낮아서 금방 개발할 것 같다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;앱의 storage를 통해 데이터를 관리하면 DB를 따로 안 둬도 될 것 같다.&lt;/li&gt;
&lt;li&gt;새로운 시도를 하며 성장하자&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 2023년이 지나기 전에 출시하고 싶었지만... 성공하지 못하고 계속 개발 중이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 기록 겸 포스팅을 하려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;개발과정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결혼 후 첫 협업이기 때문에 체계가 있진 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맛있는 것을 만들어 먹다가 문득 냉장고 앱 만들어야지... 를 시작으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방향성 회의 &amp;gt; 기능 개발 &amp;gt; 기획 및 UI/UX 작업 &amp;gt; 화면 개발 &amp;gt; 디테일 다듬기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능 개발을 하면 아내에게 UI/UX 작업을 요청(이라 말하며 쪼기)하고 만들어진 피그마 작업물을 통해 화면을 구성했다. 물론 내가 React Native를 완벽하게 다루지 못해서 디자인을 100% 적용하지 못하는 경우가 생겨서 디자인 or 기능을 조율하는 과정이 필요했다. (부부싸움이 되지 않도록 조심조심)&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;friends2&quot; data-emoticon-name=&quot;002&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends2/large/002.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends2/large/002.png&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;디자인... 해줄 수 있오...?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;React Native&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter와 React Native 둘 중 고민을 많이 했는데, 웹 친화적인 React Native를 선택했다. 초기 셋팅이 Hell이라 매우 고통받았는데, 강의도 들으며 고난의 시기를 잘 넘겼었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 안드로이드, IOS가 호환이 잘 되며, 특이하게 각 OS에 맞는 라이브러리들이 따로 있는 경우도 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kdinner.tistory.com/125&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kdinner.tistory.com/125&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704453000699&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;React Native로 앱을 만들고, 고통 받으며 적는 글&quot; data-og-description=&quot;좋았던 점. react로 앱을 만든다. 자바스크립트다. 타입스크립트도 가능하다. 힘들었던 점. 초기 세팅이 제일 힘들다. 재설치만 몇 번한 것 같다. 무엇이 잘못된 건지도 모르겠다. 왜 잘되는지 모&quot; data-og-host=&quot;kdinner.tistory.com&quot; data-og-source-url=&quot;https://kdinner.tistory.com/125&quot; data-og-url=&quot;https://kdinner.tistory.com/125&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ZRwF7/hyUXKIfjrL/uJBU7ond7ZsGB2K0UMOQkK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/byCqQV/hyUXKuMudl/rWCoRjmyHX0RJvkXdZtkek/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b8B5dY/hyUXR1GUJb/PcuiOSjoqTXophQmGpB7KK/img.png?width=2600&amp;amp;height=710&amp;amp;face=0_0_2600_710&quot;&gt;&lt;a href=&quot;https://kdinner.tistory.com/125&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kdinner.tistory.com/125&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ZRwF7/hyUXKIfjrL/uJBU7ond7ZsGB2K0UMOQkK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/byCqQV/hyUXKuMudl/rWCoRjmyHX0RJvkXdZtkek/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b8B5dY/hyUXR1GUJb/PcuiOSjoqTXophQmGpB7KK/img.png?width=2600&amp;amp;height=710&amp;amp;face=0_0_2600_710');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;React Native로 앱을 만들고, 고통 받으며 적는 글&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;좋았던 점. react로 앱을 만든다. 자바스크립트다. 타입스크립트도 가능하다. 힘들었던 점. 초기 세팅이 제일 힘들다. 재설치만 몇 번한 것 같다. 무엇이 잘못된 건지도 모르겠다. 왜 잘되는지 모&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kdinner.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;트러블 슈팅&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹과 다른 앱의 움직임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stack이라는 개념과 Navigation이라는 개념이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stack은 웹의 history처럼 1 &amp;gt; 2 &amp;gt; 3 으로 쌓이고 뒤로 가면 3 &amp;gt; 2 &amp;gt; 1 으로 흘러가는데, Navigation은 그런 형식이 아니었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스타일&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 주로 사용하고 있는 css기법인 module css를 사용하고 싶었지만, 설정해야 하는 것이 많고 장점이 크게 없어서 react native 에서 대부분 사용하는 CSS-in-JS 기법을 사용했다. 이 기법의 장점은 JS를 통해 앱의 넓이, 높이를 계산한 값을 들고 적용하기 편하다는 점이다. styled-component랑 비슷했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 특이한 점이 display가 none 또는 flex 밖에 없다는 점이다. 강제로 flex에 익숙해질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;태그&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹에도 HTML 태그가 있어서 적재적소에 사용하는 것을 추천하지만, react native에서는 태그의 의미가 컸다. 여러가지의 태그가 있으며 onClick이 아닌 onPress로 클릭 이벤트가 주어진다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1704560462625&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 오류 - 텍스트는 Text 태그로 감싸야합니다.
&amp;lt;View&amp;gt;
  안녕 !      
&amp;lt;/View&amp;gt;

// 오류 - Text 태그는 누를 수 없습니다. 
// 누를 수 있는 태그로 감싸야합니다. ex) Pressable, TouchableOpacity
&amp;lt;Text onPress={onPress}&amp;gt; 
 텍스트 !
&amp;lt;/Text&amp;gt;

// HTML 태그와 속성들이 조금씩 다릅니다.
&amp;lt;TextInput
  placeholder=&quot;레시피 이름, 재료로 검색할 수 있어요.&quot;
  placeholderTextColor=&quot;#B1B8C0&quot;
  returnKeyType=&quot;search&quot;
  value={text}
  onChangeText={(val) =&amp;gt; setText(val)}
  onEndEditing={() =&amp;gt; onSearch(text)} // 앱 키보드에서 검색 버튼 누를 경우
/&amp;gt;

// 스크롤 가능하게 하려면 ScrollView 태그를 사용해야합니다.
&amp;lt;ScrollView&amp;gt;
  &amp;lt;View&amp;gt;&amp;lt;/View&amp;gt;
  &amp;lt;View&amp;gt;&amp;lt;/View&amp;gt;
&amp;lt;/ScrollView&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;불편했던 점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초기 세팅이 매우 힘들었다. 공식 문서, 블로그 포스팅만으로 오류를 해결할 수 없어서 결국 강의의 도움을 받아서 겨우 해결했었다. (셋팅의 고비만 넘으면 개발의 반은 해결한 것이다)&lt;/li&gt;
&lt;li&gt;라이브러리들이 많진 않았다. IOS 전용 라이브러리만 있을 때가 있으며, 라이브러리 개발자가 잠수를 타서 깃헙이슈를 통해 어떻게 해결했다는 토론이 활성화되어 그것을 보고 해결한 적도 있었다.&lt;/li&gt;
&lt;li&gt;앱의 설정을 건드려야 할 때 지식이 부족해서 힘들었다. 스플래시 화면은 react를 건드리는 것이 아닌, 안드로이드는 자바 IOS는 xocode에서 수정해야 하는 상황이 생겼었다.&lt;/li&gt;
&lt;li&gt;Input을 누르면 키보드가 노출되는데, 이 부분을 컨트롤하기 매우 불편했다. 웹에서는 키보드가 올라오지 않아서 몰랐는데, 모바일에서는 당연히 보여야 하는 것이 맞아서 이 부분이 매우 생소했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;디자인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기획자 / 개발자 부부이기 때문에 디자인 보는 눈은 있으나, 투자할 리소스가 부족했다. 그렇다고 서비스 출시가 목표인데 디자인을 완전 배제할 수 없었다. 여기서 아내가 좋은 제안을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;AI로 디자인을 뽑아보자&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;niniz&quot; data-emoticon-name=&quot;040&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/niniz/large/040.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/niniz/large/040.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;미드저니(&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;Midjourney)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미드저니란 텍스트를 입력하면 AI가 이미지를 생성해 주는 모델로, &lt;span style=&quot;background-color: #ffffff; color: #373a3c; text-align: start;&quot;&gt;사실적인 묘사에 강하면서도 추상적 표현을 잘해 예술적인 부분에 특화되어 있지만 만화류의 선화도 키워드 입력에 따라 뽑아낼 수 있다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #373a3c; text-align: start;&quot;&gt; 보통 일러스트적인 작업물을 원할 때 많이 선호된다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #373a3c; text-align: start;&quot;&gt;&lt;b&gt;출처: 나무위키&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #373a3c; text-align: start;&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=thsXGOkcGGg&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=thsXGOkcGGg&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=thsXGOkcGGg&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bLAns5/hyU2k89XuF/KRtCHnjQ1voKfr5fWa4c2K/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-original-url=&quot;&quot; data-video-title=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/thsXGOkcGGg&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아내는 유료버전까지 사용하면서 흥미롭게 AI를 고문했다...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xbjbc/btsC7tXTaIW/Kdxc6Si7M8H7LtLUZFzO0k/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xbjbc/btsC7tXTaIW/Kdxc6Si7M8H7LtLUZFzO0k/img.webp&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;599&quot; data-filename=&quot;game.png.webp&quot; width=&quot;415&quot; height=&quot;415&quot; data-widthpercent=&quot;42.47&quot; style=&quot;width: 41.9803%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xbjbc/btsC7tXTaIW/Kdxc6Si7M8H7LtLUZFzO0k/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXbjbc%2FbtsC7tXTaIW%2FKdxc6Si7M8H7LtLUZFzO0k%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;599&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBMEQk/btsC8T9QUCs/POWYcN7Q1hqwCCyrHjM7CK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBMEQk/btsC8T9QUCs/POWYcN7Q1hqwCCyrHjM7CK/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;824&quot; data-filename=&quot;화면 캡처 2023-12-10 141540.png&quot; width=&quot;559&quot; height=&quot;413&quot; style=&quot;width: 56.8569%;&quot; data-widthpercent=&quot;57.53&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBMEQk/btsC8T9QUCs/POWYcN7Q1hqwCCyrHjM7CK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBMEQk%2FbtsC8T9QUCs%2FPOWYcN7Q1hqwCCyrHjM7CK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1116&quot; height=&quot;824&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미드저니는 내가 원하는 것이 명확하지 않을 때, 아이데이션 하면서 가다듬고 그럴듯한 결과물을 만들어 내는 데는 뛰어났다. 예를 들어 우리는 귀여운 느낌의, 고양이가 있는, 냉장고를 원해서 여러 가지 명령어를 입력하면서 그럴듯한 결과물을 만들어 냈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스테이블 디퓨전 (Stable Diffusion)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스테이블은 미드저니와 비슷하게 텍스트 및 이미지 프롬프트에서 이미지를 생성하는 생성형 인공 지능 모델이다. 이미지 외에도 모델을 사용해서 비디오 및 애니메이션을 만들 수 있다. 출처: &lt;a href=&quot;https://aws.amazon.com/ko/what-is/stable-diffusion/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://aws.amazon.com/ko/what-is/stable-diffusion/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스테이블 디퓨전을 사용한 계기는 귀여운 느낌의 식재료 아이콘을 만들고 싶은 &lt;b&gt;명확한 방향성&lt;/b&gt;이 있고, 원하는 화풍, 스타일 이 있는데 그 부분을 세부 컨트롤 하기 위해서 사용했다. (이 부분도 아내가... 난 잘 지켜봤고...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 방향의 데이터가 존재하고 그쪽으로 가이드(학습) 시킬 수 있고 이런 생성과정에 더 적극적으로 개입할 수 있어 좋았다.(고 한다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/79Qno/btsC8RRLp7U/Agk4RKdKQjE0bkHTdDebdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/79Qno/btsC8RRLp7U/Agk4RKdKQjE0bkHTdDebdk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;863&quot; data-filename=&quot;화면 캡처 2023-12-10 143730.png&quot; width=&quot;659&quot; height=&quot;394&quot; style=&quot;width: 43.4842%; margin-right: 10px;&quot; data-widthpercent=&quot;44&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/79Qno/btsC8RRLp7U/Agk4RKdKQjE0bkHTdDebdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F79Qno%2FbtsC8RRLp7U%2FAgk4RKdKQjE0bkHTdDebdk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1444&quot; height=&quot;863&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SJqWa/btsC34ER2we/9hginNPpIz1E770OJWVWA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SJqWa/btsC34ER2we/9hginNPpIz1E770OJWVWA0/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1836&quot; data-origin-height=&quot;862&quot; data-filename=&quot;화면 캡처 2023-12-11 003146.png&quot; style=&quot;width: 55.353%;&quot; data-widthpercent=&quot;56&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SJqWa/btsC34ER2we/9hginNPpIz1E770OJWVWA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSJqWa%2FbtsC34ER2we%2F9hginNPpIz1E770OJWVWA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1836&quot; height=&quot;862&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발 현황&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나에게 필요한 서비스를 만든다는 것은 매우 매력적이다. 열정이 뿜뿜해지면서 현재에 안주하지 않으려고, 성장하기 위해 한 발자국 나아가는 기분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아! 그리고 아내와의 협업이 매우 즐거워서 자주 하자고 할 것 같다&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;niniz&quot; data-emoticon-name=&quot;013&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/niniz/large/013.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/niniz/large/013.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;</description>
      <category>Javascript/토이프로젝트</category>
      <author>강디너</author>
      <guid isPermaLink="true">https://kdinner.tistory.com/126</guid>
      <comments>https://kdinner.tistory.com/126#entry126comment</comments>
      <pubDate>Sun, 7 Jan 2024 02:01:37 +0900</pubDate>
    </item>
    <item>
      <title>React Native로 앱을 만들고, 고통 받으며 적는 글</title>
      <link>https://kdinner.tistory.com/125</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;좋았던 점.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react로 앱을 만든다. 자바스크립트다. 타입스크립트도 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;힘들었던 점.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 세팅이 제일 힘들다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재설치만 몇 번한 것 같다. 무엇이 잘못된 건지도 모르겠다. 왜 잘되는지 모르겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;라이브러리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;react-native-navigation&lt;/b&gt;을 통해 화면이 이동하는데, &lt;b&gt;Stack&lt;/b&gt;이라는 개념과 &lt;b&gt;Navigation이라는&lt;/b&gt; 개념이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Stack은 웹의 히스토리나 자료구조처럼 1 &amp;gt; 2 &amp;gt; 3 으로 쌓이고 뒤로 가면 3 &amp;gt; 2 &amp;gt; 1 이런 형식이고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Navigation은 쌓이지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱을 껐다 켜도 데이터가 유지되려면 storage를 사용해야한다. (&lt;a href=&quot;https://github.com/react-native-async-storage/async-storage&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/react-native-async-storage/async-storage&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;React-Native 특성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react-native에서 지원하는 Text, View 태그 등등을 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;display 속성에 flex 또는 none 밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스타일컴포넌트와 비슷한 형식으로 스타일을 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스타일 속성명이 카멜 케이스다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 View는 스크롤되지 않는다. 그래서 ScrollView라는 태그를 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이 ScrollView라는 나쁜 것이 flex: 1이 먹히지 않아 화면을 확보하지 못하는 경우가 많은데, 찾아 &lt;b&gt;contentContainerStyle&lt;/b&gt; 이란 것을 사용해야지만 스타일이 정상적으로 잘 들어간다. ScrollView 특성상 콘텐츠 내용의 길이가 적을 때에는 적은 확보 해서 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SafeAreaView를 스크린의 최상위에 적어줘야 IOS에서 잘리지 않고 이쁘게 보인다.(안드로이드는 그냥 평범한 View로 보인다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SafeAreaView에도 flex:1을 해줘야지 전체화면을 잡아준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디버깅하기 너무 힘들다. 디버깅 라이브러리를 쓰는 게 맘 편하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;로컬에서 IOS는 안 되는 게 너무 많다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- http로 되어있는 웹을 띄우려 했는데 https가 아니라 보안 때문에? 막힌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 디버깅 툴에 연결을 못한다..(내가 못하는 건지...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 자바스크립트 모듈을 설치하면 pod-install이라는 명령어를 항상 해줘야 한다. (IOS 의존성 설치.. 이걸 몰라서 한동안 접은 적도 있었다. 안드로이드는 자동이던데...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript/React.js</category>
      <author>강디너</author>
      <guid isPermaLink="true">https://kdinner.tistory.com/125</guid>
      <comments>https://kdinner.tistory.com/125#entry125comment</comments>
      <pubDate>Wed, 4 Oct 2023 00:18:04 +0900</pubDate>
    </item>
    <item>
      <title>나의 강점 찾기</title>
      <link>https://kdinner.tistory.com/124</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근 팀 내 주니어끼리 모여 &amp;lsquo;나의 강점 찾기&amp;rsquo; 스터디를 하고 있다. (feat. 내년 연협을 잘하자.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;자신의 강점을 찾고 강화하자&amp;rdquo; 라는 목표를 갖고 매주 모여서 짧게 이야기를 나누기 시작했지만, 강점 찾기란 매우 힘든 일이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강점을 찾기 위해 이력서도 다시 써보고, 서로가 생각하는 강점에 대해 이야기를 나누며 생각보다? 유익한 시간이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 나의 강점을 3가지로 정리해 보았다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;생산성이 높은 개발자&lt;/li&gt;
&lt;li&gt;먼저 나서서 시도하고 도전한다.&lt;/li&gt;
&lt;li&gt;긍정적이며, 동료들과 의견을 잘 나누며 잘 받아들인다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;생산성이 높은 개발자&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생산성이 높은 개발자는 업그레이드된 버전인데, 그전에는 &amp;lsquo;빠르게 개발해서 빠르게 피드백받아 개선하는 것&amp;rsquo;이 내가 자신 있게 말할 수 있는 강점이었다.(말이 고급져졌다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 강점을 오랫동안 밀고 나갔었는데, 최근 매니저님과 1대1 미팅을 하며 많은 생각이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 장점에 대해 이야기를 나누었는데, &amp;lsquo;빠르게 개발이란 무엇인가&amp;rsquo; 가 나를 고민하게 만들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lsquo;객관적으로 빠르게 개발한다&amp;rsquo; 를 표현하기가 너무 애매했던 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;손이 빠르다 ?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 손이 빠르다는 건 주관적이다. 어떻게 증명할 것인가.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UI를 먼저 개발해서 기획자/디자이너에게 보여주고, 빠르게 피드백을 받으며 개발한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 오히려 더 오래 걸리는 것이 아닌가? 오히려 수정이 잦으면 느려지는 거 아닌가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 느낌의 이야기였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 나의 장점에 대해 심도 있게 생각해보지 않았었는데, 한번 더 생각해 보는 자리였던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퇴근하고 아내에게 나의 장점에 대해 이야기하며 말문이 막혔었다고, 증명하지 못했다고 말하자 아내가 내가 가진 장점이 얼마나 큰지 스스로 모른다며 나도 몰랐던 장점에 대한 명언을 엄청 날렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;아내의 반문&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;처음부터 완벽한 기획/디자인은 없다고 생각한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;기획자나 디자이너는 일차적으로 머릿속에서 좋다고 생각하는 방향으로 기획서 혹은 시안을 만들지만, 실제로 움직이는 결과물을 보게 되면 앞서 고려하지 못한 부분이나 유저의 눈에서 보이는 이슈들이 눈에 띄게 되고, 이를 수정해 나가면서 최초의 기획보다 훨씬 더 좋은 결과물로 개선할 수 있다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그런데 기획과 디자인이 나온 단계가 100% 확정이라고 생각하고 딱 맞춰진 개발을 하면, 필연적으로 최종 단계에서 빈틈이 나온다. 이건 실제 결과물을 볼 수 없이 상상해서 작업해야 하는 기획 특성상 필연적인 일인데도, 수정할 시간이 없어서 빈틈을 그대로 두고 (혹은 급하게 때우고) 출시해야 하거나 더 나쁘게는 &quot;중간에 기획이 바뀌었다&quot; 며 개발자와 트러블을 경험하게 되는 경우도 많다. 이렇게 되면 당연히 팀 케미에도 부정적일뿐더러 결과물도 만족스럽지 않다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;반면에, 손이 빠른 개발자와 협업하면 중요한 것부터 얼른 개발하여 동작실물을 보여줄 수 있고, 이를 개선할 수 있는 시간도 충분하다. 실제 제품의 초안을 보면서 개발자와 함께 완성도를 높여가는 단계를 거칠 수 있다면&amp;nbsp; 그렇지 않은 제품보다 결과물의 퀄리티가 더 좋은 것은 당연한 일이다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;개인적으로 생각할 때, 함께 일하기에 좋은 개발자에는 두 가지의 유형이 있다고 생각한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1) 심사숙고하는 개발자&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2) 손이 빠른 개발자&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;심사숙고하는 개발자는 기획서를 꼼꼼히 읽고 의도를 이해한다. 어떻게 개발해야 할지에 대해 조사하고, 방법을 숙고한다. 때문에 개발 진행 과정에서 상대적으로 많은 시간을 요구할 수 있지만, 대신 나중에 가서 놓친 부분을 계속 고쳐야 할 일이 없고 가끔은 기획자가 놓친 부분마저 캐치하여 제안하는 듬직한 모습을 보인다. 시간을 들인 만큼 신뢰할 수 있는 결과물을 준다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;손이 빠른 개발자는 어떻게 만들지 쉽게 쉽게 파악하고, 세부사항들은 생략하면서도 전체적인 flow가 눈에 보일 수 있도록 빠르게 UI 개발을 한다. 분명 중간중간 놓치는 부분이 있지만, 중요한 부분은 고려되어 있기 때문에 빠른 수정이 가능하다.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;프로젝트를 진행할 때 둘의 장점에 어울리는 프로젝트들이 있겠지만 이 둘의 공통점은 프로젝트에서의 중요한 것이 무엇인지 아는 것 같다.&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 프로젝트에서 중요한 것이 무엇인지 잘 캐치해서 빠르게 구현하고, 협업하는 사람들과 소통하며 더욱 완벽한 제품을 만드는 것이 장점이라고 해주었다. 생산성이 높은 개발자라는 단어도 이 대화 중에 나왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에 강점에 대해 이야기하면 잘 기억해 놨다가 말해야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;먼저 나서서 시도하고 도전한다. &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;긍정적이며, 동료들과 의견을 잘 나누며 잘 받아들인다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;태니지먼트라고, 사내 워크샵을 진행한 적이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 워크샵을 진행 후 팀원들이 나의 강점이라고 말해주었는데, 맘에 들어서 적었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Bdc9R/btsrfghZnV6/oK0wnN2jQEBOvpcIdkP5i0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bdc9R/btsrfghZnV6/oK0wnN2jQEBOvpcIdkP5i0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bdc9R/btsrfghZnV6/oK0wnN2jQEBOvpcIdkP5i0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBdc9R%2FbtsrfghZnV6%2FoK0wnN2jQEBOvpcIdkP5i0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;662&quot; height=&quot;258&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 강점과 재능이 무엇인지 발견하고, 더욱 강화할 수 있도록 도와주는 프로그램이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리 팀 전체가 다 같이 워크샵을 진행하며 서로의 강점과 재능에 대해 알아보는 시간을 가졌는데, 매우 재미있었다.(아내에게도 추천했다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MBTI 같은 느낌으로 문항 체크하고, 나중에 결과지 받는 형태인데 결과가 딱 나를 보는 것 같아서 한번 놀라고, 팀원들의 결과도 딱 그 팀원들을 표현하는 단어라 두 번 놀랐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의&lt;span&gt; &lt;/span&gt;재능은&lt;span&gt; &lt;/span&gt;&lt;b&gt;유연&lt;/b&gt;이며&lt;span&gt;, 강점은 창조였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;유연이란.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;변화하는 상황을 즐기며 계획되지 않은 상황이 발생해도 그 상황에 맞게 유동적으로 대처한다.&lt;br /&gt;미래는 언제나 변할 수 있는 것으로 생각하기 때문에 예상치 못한 상황에 당황하거나 화내지 않는다.&lt;br /&gt;갑작스러운 요청이나 변경에도 침착하게 대처한다. 변화가 많은 환경일수록 빠르게 일을 처리한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;창조란.&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;낯선 환경이나 상황에 부딪혀도 당황하지 않고 적절하게 반응하며, 상황에 대한 통찰력은 팀에 활력을 가져다주거나 새로운 것에 도전할 수 있는 발판을 마련한다.&amp;nbsp;&amp;nbsp;&lt;br /&gt;현재에 안주하지 않고 새로운 자극으로 팀원들에게 활력을 넣는다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 것을 경험하는 걸 좋아해서 토이 프로젝트도 다양하게 해 보고, 강의, 멘토링 등 여러 범위로 뻗어가는 나를 잘 표현한 것 같아서 마음에 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 다양한 것을 경험하고 싶어 하기 때문에 '&lt;b&gt;먼저 나서서 시도하고 도전한다'&lt;/b&gt; 라는 말을 들을 수 있었던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zyhM7/btsq5Xp5dcf/WXjNLUlIJ5KLESmicfKGrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zyhM7/btsq5Xp5dcf/WXjNLUlIJ5KLESmicfKGrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zyhM7/btsq5Xp5dcf/WXjNLUlIJ5KLESmicfKGrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzyhM7%2Fbtsq5Xp5dcf%2FWXjNLUlIJ5KLESmicfKGrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;715&quot; height=&quot;425&quot; data-origin-width=&quot;703&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 재능과 강점을 서로 돌아보며 팀원들과 대화를 하고 내가 생각하는 팀원들의 강점도 같이 이야기해 보는 좋은 시간이었어서, 기록을 하고 싶었다.&lt;/p&gt;</description>
      <category>회고록</category>
      <author>강디너</author>
      <guid isPermaLink="true">https://kdinner.tistory.com/124</guid>
      <comments>https://kdinner.tistory.com/124#entry124comment</comments>
      <pubDate>Mon, 14 Aug 2023 17:40:38 +0900</pubDate>
    </item>
    <item>
      <title>개발자로서 성장을 잘 하고 있는걸까 ?</title>
      <link>https://kdinner.tistory.com/123</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;작년과 올해는 나에게 중요한 시간이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작년은 이직한 곳에 나를 증명해야 했고, 결혼 준비와 함께 올해 초 결혼을 했기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 그 와중에 강의도 찍어보고, 간간히 블로그를 적었었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마침 회사에서 성장했는지, 나의 강점은 무엇인지 자꾸 물어봐서 이번 기회에 한번 되돌아보기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;나는 성장 하였는가?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;남자로서, 남편으로서 성장을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;집도 같이 보러 다니고, 면허도 따고, 결혼도 잘 마무리 지었다. 아내는 매우 만족해한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 개발자로서는 크게 성장하지 못한 것 같다. 주어진 업무는 잘 해내었지만, 새로운 기술 서칭이나 개선 업무를 앞장서서 하지 못했다.(결혼준비라는 핑계로...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블로그도 꾸준히 작성하지 못한 것도 아쉬움이 크다. 내가 일하면서 배운 것과 혼자 공부하며 정리해야 기억에 남는데, 이번에는 많이 놓친 것 같아 꾸준한 게 중요하다는 것을 느꼈다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 강의를 찍으면서 한 단계 성장한 것 같다. 이론이 약했던 나에게 다시 복습하게 되는 계기가 되었고, 문서를 더 찾아보게 되는 시간이었다. 강의를 찍는 것도 처음에 쉽게 생각했는데, 약 40시간 정도의 강의를 녹화하는데 들어간 시간은 두 배 이상이었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 새로운 도메인을 맡게 되었는데 다양한 상황에서의 개발을 하고 있고, 고통을 받으면서 성장? 하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도... 기억에 남는 개선건이 하나 있는데, 어드민을 타입스크립트로 전환하는 건이었다. 스터디로 진행했던 타입스크립트를 좀 더 고민하고, 활용할 수 있다는 점에서 팀원들이 좋아해줘 기억에 남는다. (일부 프로젝트만 타입스크립트였는데, 현재는 전부 타입스크립트로 전환하고 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;나의 강점이란 무엇일까.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강점이라... 활발하다 ? 맡은 일은 문제없이 잘 끝낸다 ? 배포일을 잘 맞춘다 ?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서는 당연히 해야 한다고 생각하기 때문에 내가 내세울만한 강점을 찾기 어려운 것 같다.(당연하다고 생각하는 게 가장 힘든 건데...ㅠㅜ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그나마 요즘 내세우고 있는 건 행동력이 있는 점과 디자인이 따로 나오지 않는 상황에서도 대처를 잘한다는 점 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어드민에 경우 기능이 중요하기 때문에 보통 기획자나 기능 요구하는 쪽에서 대략적으로 만들어주시는데, 관련해서 사용자(동료들)가 편하게 사용할 수 있도록 고민하고 빠르게 피드백받아서 무난하게 잘 해결하는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(무슨 자기소개서 쓰는 것 같다...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와디즈를 사용하는 사용자들보다 와디즈 내부 동료들이 좋아하는 것이 난 더 보람느낀다. 더 가깝게 느껴져서 그런 것 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;앞으로의 계획&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맡은 도메인이 바뀌어서 적응해가고 있다. 어드민도 개선해야 할 것이 많지만 회사에서는 다른게 더 중요하다고 생각한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외주로 만들어진 프로젝트를 내제화하고 있는데, 코드가 왜 이렇게 되있을까 ~ 라고 생각하며 열심히 개선하고 있다. (이런 걸 보면 나름 성장했다고 생각한다.) 남은 반년 동안 도메인 적응 + 개선을 할 것 같은 느낌이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블로그도 다시 열심히 쓸 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>회고록</category>
      <category>회고록</category>
      <author>강디너</author>
      <guid isPermaLink="true">https://kdinner.tistory.com/123</guid>
      <comments>https://kdinner.tistory.com/123#entry123comment</comments>
      <pubDate>Sun, 25 Jun 2023 23:27:52 +0900</pubDate>
    </item>
    <item>
      <title>코드로 대화하자 - HTTP 상태 코드</title>
      <link>https://kdinner.tistory.com/122</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnxwPk/btsfg3HVgcI/Ffv8ElvU2ZidZMoECZi7O0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnxwPk/btsfg3HVgcI/Ffv8ElvU2ZidZMoECZi7O0/img.jpg&quot; data-alt=&quot;https://http.cat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnxwPk/btsfg3HVgcI/Ffv8ElvU2ZidZMoECZi7O0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnxwPk%2Fbtsfg3HVgcI%2FFfv8ElvU2ZidZMoECZi7O0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;520&quot; data-origin-width=&quot;750&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://http.cat&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 상태 코드는 웹 서버와 클라이언트 간의 통신 과정에서 클라이언트 요청에 대한 서버의 응답 결과를 전달하는 코드입니다. 이 코드는 HTTP 응답의 일부로 사용되며, 성공, 클라이언트 오류, 서버 오류 등의 여러 상황을 나타낼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드 팀과 백엔드 팀이 HTTP 상태 코드를 기준으로 특정 상황에 대한 코드 값을 약속하게 된다면 &lt;b&gt;불필요한 커뮤니케이션&lt;/b&gt;을 줄일 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예를 들어&lt;/b&gt; HTTP 상태 코드가 401인 경우 로그인이 필요한 상태라고 약속합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백엔드에서는 인증이 필요한 사용자일 경우 401로 내려주고, 프론트엔드에서는 401 코드만 딱 잡아서 로그인이 필요하다고 사용자에게 보여주거나, 로그인 페이지로 이동시킬 수 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백엔드에서 HTTP 상태 코드로 구분시키는 게 아닌 response 값으로도 구분가능하게 할 수 있지만, 이런 상황이 많아질수록 관리하기 힘들어질 것입니다. 그리고 백엔드 팀이 많을수록, 프론트엔드 팀이 많을 수록 다양한 조건들이 나올 수 있습니다. (a다르고 A가 다른데...) &lt;b&gt;예시를 먼저 보여드리겠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 상태 코드에 담겨있는 경우입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1684679293247&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;try {
    const data = await  axios.get(&amp;lsquo;/userInfo&amp;rsquo;);
    //  API가 성공했기 때문에 유저 정보가 있을 것으로 예상
    console.log(data);
    return data;
} catch (err) {
    // 4xx 또는 5xx 일 경우 (실패할 경우) err에 나올 것으로 예상
    console.log(err);
    if (err.status === 401) {
    	alert('로그인이 필요합니다.');
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 axios interceptor에서 공통으로 처리할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 할 경우 try catch 문마다 if문을 달 필요가 없게 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1684679293250&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 응답 인터셉터 추가하기
axios.interceptors.response.use(function (response) {
    // 2xx 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
    // 응답 데이터가 있는 작업 수행
    return response;
  }, function (error) {
    // 2xx 외의 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
    
    if (error.response.status === 401) {
    	alert('로그인 필요 !!');
    }
    // 응답 오류가 있는 작업 수행
    return Promise.reject(error);
  });&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만&amp;nbsp;API가&amp;nbsp;200&amp;nbsp;성공했지만&amp;nbsp;data에서&amp;nbsp;실패한&amp;nbsp;값을&amp;nbsp;준다고&amp;nbsp;가정하면&lt;br /&gt;try catch문으로 핸들링할 수 없이 data에서&amp;nbsp;에러를&amp;nbsp;한번&amp;nbsp;더&amp;nbsp;찾아야 하는&amp;nbsp;작업이&amp;nbsp;필요합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1684679293252&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;try {
    const data = await  axios.get(&amp;lsquo;/userInfo&amp;rsquo;);
    //  API가 성공했기 때문에 유저 정보가 있을 것으로 예상
    console.log(data);
    
    // 우린 오류를 data 안에 넣어줄꺼야 !
    if(data.code === 500 || data.code === 400) {
		throw(&amp;lsquo;오류래요&amp;rsquo;)
	}
    return data;
} catch (err) {
    // 4xx 또는 5xx 일 경우 (실패할 경우) err에 나올 것으로 예상
    console.log(err);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GET userInfo 에 추가된 건 단 3줄이지만, API 통신코드가 많아질수록 중복코드가 늘어납니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분도 axios interceptors를 이용해서 똑같이 적용할 순 있지만, 성공했을 때의 인터셉터를 하기 때문에 이 부분을 잘 모르는 팀원이 보면 의문을 가질 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;500, 400 뿐만 아니라 다양한 케이스가 발생할 것이기 때문에 관리가 잘 된다면 상관없지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그것이&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;아니라면&lt;span&gt;&amp;hellip;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;여기부터는 이론적인 거!!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;HTTP&amp;nbsp;상태&amp;nbsp;코드는&amp;nbsp;3자리&amp;nbsp;숫자로&amp;nbsp;이루어져&amp;nbsp;있으며,&amp;nbsp;첫&amp;nbsp;번째&amp;nbsp;숫자는&amp;nbsp;응답의&amp;nbsp;성격을&amp;nbsp;나타냅니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5개의 그룹&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정보를 제공하는 응답 (1xx)&lt;/li&gt;
&lt;li&gt;성공 응답 (2xx)&lt;/li&gt;
&lt;li&gt;리다이렉트 응답 (3xx)&lt;/li&gt;
&lt;li&gt;클라이언트 에러 응답 (4xx)&lt;/li&gt;
&lt;li&gt;서버 에러 응답 (5xx)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://http.cat/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://http.cat/&lt;/a&gt; 이라는 HTTP 코드에 대한 귀여운 사이트도 있습니다.&lt;/p&gt;
&lt;figure id=&quot;og_1684080217035&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;HTTP Cats&quot; data-og-description=&quot;API for HTTP Cats&quot; data-og-host=&quot;http.cat&quot; data-og-source-url=&quot;https://http.cat/&quot; data-og-url=&quot;https://http.cat&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/tqdKP/hySBzig7aV/K5mg95GNIvwgbmYI2TPBAK/img.jpg?width=750&amp;amp;height=600&amp;amp;face=0_0_750_600,https://scrap.kakaocdn.net/dn/WwV3I/hySBB8eUSm/hzKAB1qzLMVhKU9Y5EJFu1/img.jpg?width=750&amp;amp;height=600&amp;amp;face=0_0_750_600&quot;&gt;&lt;a href=&quot;https://http.cat/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://http.cat/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/tqdKP/hySBzig7aV/K5mg95GNIvwgbmYI2TPBAK/img.jpg?width=750&amp;amp;height=600&amp;amp;face=0_0_750_600,https://scrap.kakaocdn.net/dn/WwV3I/hySBB8eUSm/hzKAB1qzLMVhKU9Y5EJFu1/img.jpg?width=750&amp;amp;height=600&amp;amp;face=0_0_750_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;HTTP Cats&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;API for HTTP Cats&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;http.cat&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/HTTP_%EC%83%81%ED%83%9C_%EC%BD%94%EB%93%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;위키백과&lt;/a&gt; 기준&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1xx&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #202122; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;100(계속): 요청자는 요청을 계속해야 한다. 서버는 이 코드를 제공하여 요청의 첫 번째 부분을 받았으며 나머지를 기다리고 있음을 나타낸다.&lt;/li&gt;
&lt;li&gt;101(프로토콜 전환): 요청자가 서버에 프로토콜 전환을 요청했으며 서버는 이를 승인하는 중이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2xx&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #202122; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;200(성공): 서버가 요청을 제대로 처리했다는 뜻이다. 이는 주로 서버가 요청한 페이지를 제공했다는 의미로 쓰인다.&lt;/li&gt;
&lt;li&gt;201(작성됨): 성공적으로 요청되었으며 서버가 새 리소스를 작성했다.&lt;/li&gt;
&lt;li&gt;202(허용됨): 서버가 요청을 접수했지만 아직 처리하지 않았다.&lt;/li&gt;
&lt;li&gt;203(신뢰할 수 없는 정보): 서버가 요청을 성공적으로 처리했지만 다른 소스에서 수신된 정보를 제공하고 있다.&lt;/li&gt;
&lt;li&gt;204(콘텐츠 없음): 서버가 요청을 성공적으로 처리했지만 콘텐츠를 제공하지 않는다.&lt;/li&gt;
&lt;li&gt;205(콘텐츠 재설정): 서버가 요청을 성공적으로 처리했지만 콘텐츠를 표시하지 않는다. 204 응답과 달리 이 응답은 요청자가 문서 보기를 재설정할 것을 요구한다(예: 새 입력을 위한 양식 비우기).&lt;/li&gt;
&lt;li&gt;206(일부 콘텐츠): 서버가 GET 요청의 일부만 성공적으로 처리했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3xx&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #202122; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;300(여러 선택항목): 서버가 요청에 따라 여러 조치를 선택할 수 있다. 서버가 사용자 에이전트에 따라 수행할 작업을 선택하거나, 요청자가 선택할 수 있는 작업 목록을 제공한다.&lt;/li&gt;
&lt;li&gt;301(영구 이동): 요청한 페이지를 새 위치로 영구적으로 이동했다. GET 또는 HEAD 요청에 대한 응답으로 이 응답을 표시하면 요청자가 자동으로 새 위치로 전달된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4xx&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;400(잘못된 요청): 서버가 요청의 구문을 인식하지 못했다.&lt;/li&gt;
&lt;li&gt;401(권한 없음): 이 요청은 인증이 필요하다. 서버는 로그인이 필요한 페이지에 대해 이 요청을 제공할 수 있다. 상태 코드 이름이 권한 없음(Unauthorized)으로 되어 있지만 실제 뜻은 인증 안됨(Unauthenticated)에 더 가깝다.&lt;/li&gt;
&lt;li&gt;402(결제&amp;nbsp;필요):&amp;nbsp;이&amp;nbsp;요청은&amp;nbsp;결제가&amp;nbsp;필요합니다.&lt;/li&gt;
&lt;li&gt;403(Forbidden,&amp;nbsp;금지됨):&amp;nbsp;서버가&amp;nbsp;요청을&amp;nbsp;거부하고&amp;nbsp;있다.&amp;nbsp;예를&amp;nbsp;들자면,&amp;nbsp;사용자가&amp;nbsp;리소스에&amp;nbsp;대한&amp;nbsp;필요&amp;nbsp;권한을&amp;nbsp;갖고&amp;nbsp;있지&amp;nbsp;않다.&amp;nbsp;(401은&amp;nbsp;인증&amp;nbsp;실패,&amp;nbsp;403은&amp;nbsp;인가&amp;nbsp;실패라고&amp;nbsp;볼&amp;nbsp;수&amp;nbsp;있음)&lt;/li&gt;
&lt;li&gt;404(Not&amp;nbsp;Found,&amp;nbsp;찾을&amp;nbsp;수&amp;nbsp;없음):&amp;nbsp;서버가&amp;nbsp;요청한&amp;nbsp;페이지(Resource)를&amp;nbsp;찾을&amp;nbsp;수&amp;nbsp;없다.&amp;nbsp;예를&amp;nbsp;들어&amp;nbsp;서버에&amp;nbsp;존재하지&amp;nbsp;않는&amp;nbsp;페이지에&amp;nbsp;대한&amp;nbsp;요청이&amp;nbsp;있을&amp;nbsp;경우&amp;nbsp;서버는&amp;nbsp;이&amp;nbsp;코드를&amp;nbsp;제공한다.&lt;/li&gt;
&lt;li&gt;405(허용되지&amp;nbsp;않는&amp;nbsp;메소드):&amp;nbsp;요청에&amp;nbsp;지정된&amp;nbsp;방법을&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;없다.&amp;nbsp;예를&amp;nbsp;들어&amp;nbsp;POST&amp;nbsp;방식으로&amp;nbsp;요청을&amp;nbsp;받는&amp;nbsp;서버에&amp;nbsp;GET&amp;nbsp;요청을&amp;nbsp;보내는&amp;nbsp;경우,&amp;nbsp;또는&amp;nbsp;읽기&amp;nbsp;전용&amp;nbsp;리소스에&amp;nbsp;PUT&amp;nbsp;요청을&amp;nbsp;보내는&amp;nbsp;경우에&amp;nbsp;이&amp;nbsp;코드를&amp;nbsp;제공한다.&lt;/li&gt;
&lt;li&gt;406(허용되지&amp;nbsp;않음):&amp;nbsp;요청한&amp;nbsp;페이지가&amp;nbsp;요청한&amp;nbsp;콘텐츠&amp;nbsp;특성으로&amp;nbsp;응답할&amp;nbsp;수&amp;nbsp;없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5xx&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #202122; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;500(내부 서버 오류): 서버에 오류가 발생하여 요청을 수행할 수 없다.&lt;/li&gt;
&lt;li&gt;501(구현되지 않음): 서버에 요청을 수행할 수 있는 기능이 없다. 예를 들어 서버가 요청 메소드를 인식하지 못할 때 이 코드를 표시한다.&lt;/li&gt;
&lt;li&gt;502 (Bad Gateway, 불량 게이트웨이): 서버가 게이트웨이나 프록시 역할을 하고 있거나 또는 업스트림 서버에서 잘못된 응답을 받았다.&lt;/li&gt;
&lt;li&gt;503(서비스를 사용할 수 없음): 서버가 오버로드되었거나 유지관리를 위해 다운되었기 때문에 현재 서버를 사용할 수 없다. 이는 대개 일시적인 상태이다.&lt;/li&gt;
&lt;li&gt;504(게이트웨이 시간초과): 서버가 게이트웨이나 프록시 역할을 하고 있거나 또는 업스트림 서버에서 제때 요청을 받지 못했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTTP/Status&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/HTTP/Status&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://axios-http.com/kr/docs/handling_errors&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://axios-http.com/kr/docs/handling_errors&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript/이것저것</category>
      <author>강디너</author>
      <guid isPermaLink="true">https://kdinner.tistory.com/122</guid>
      <comments>https://kdinner.tistory.com/122#entry122comment</comments>
      <pubDate>Sun, 21 May 2023 23:30:01 +0900</pubDate>
    </item>
    <item>
      <title>React setState를 동기적으로 사용해야할 때</title>
      <link>https://kdinner.tistory.com/121</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;React에서 useState는 state값이 변경 될 때마다 해당 컴포넌트가 다시 렌더링을 하는 특성이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 동기적으로 실행되는 자바스크립트 코드에서 setState를 실행하고 해당 state를 가지고 무슨짓을 하려고 할 때 이슈가 되는 경우가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1682150664368&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const [fruit, setFruit] = useState({
    banana: 0,
    apple: 0,
});

const [errors, setErrors] = useState({
    banana: false,
    apple: false,
})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러가지 과일들이 있고, 과일이 있는지 여부를 체크할 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가볍게 보면 banana와 apple이 0이라서 해당 조건문에 걸리고 setErrors를 하게됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 checkError에 { banana: true, apple: true } 값이 나오는 것으로 예상되죠.&lt;/p&gt;
&lt;pre id=&quot;code_1682152029191&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const validate = () =&amp;gt; {
	console.log('검증시작');
    const { apple, banana } = fruit;

    if (banana === 0) {
        setErrors(prev =&amp;gt; ({ ...prev, banana: true }));
    }
    if (apple === 0) {
        setErrors(prev =&amp;gt; ({ ...prev, apple: true }));
    }
    // errors에 아직 반영이 되어있지 않다.
    const checkError = Object.values(errors).filter(i =&amp;gt; i).length;
    console.log('checkError : ', errors, checkError);
    if (checkError &amp;gt; 0) {
      console.log('에러 확인');
      return;
    }
    
    // 검증을 통과하면 그대로 API 통신
    console.log('검증 통과');
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 콘솔은 아래와 같이 false false가 나옵니다. &lt;b&gt;(리렌더링 전이고)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 한번 더 클릭해야지 true값이 나오는 것을 볼 수 있습니다. &lt;b&gt;(리렌더링 후라서)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;359&quot; data-origin-height=&quot;131&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nK5Ui/btsddHOYdOE/KgyRtxSTBXRZRtptLYDcp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nK5Ui/btsddHOYdOE/KgyRtxSTBXRZRtptLYDcp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nK5Ui/btsddHOYdOE/KgyRtxSTBXRZRtptLYDcp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnK5Ui%2FbtsddHOYdOE%2FKgyRtxSTBXRZRtptLYDcp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;359&quot; height=&quot;131&quot; data-origin-width=&quot;359&quot; data-origin-height=&quot;131&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 오류인 경우에도 검증이 통과되었다고 이후의 로직을 타게되면 예상하지 못한 문제가 발생 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우 플래그 값을 하나 두고 검증 성공 여부를 알 수 있도록 하는 방법이 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1682846960988&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const validate = () =&amp;gt; {
    console.log('검증시작');
    const { apple, banana } = fruit;

    const data = {
      apple: apple === 0,
      banana: banana === 0,
    };
    console.log(data);
    
    // 사용자에게 디테일한 오류를 보여주기 위해서
    // setErrors를 통해 apple, banana가 오류라는 것을 알려줘야한다.
    setErrors(prev =&amp;gt; ({ ...prev, data}));
    
    const checkError = Object.values(data).filter(i =&amp;gt; i).length;
    console.log('checkError : ', errors, checkError);
    if (checkError &amp;gt; 0) {
      console.log('에러 확인');
      setFinishValidate(false);
      return;
    }

    console.log('검증 통과');
    setFinishValidate(true);
  };

  useEffect(() =&amp;gt; {
    if (finishValidate) {
      console.log('오류 검증 통과');
      // 검증을 통과했으니그대로 API 통신
    }
  }, [finishValidate]);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;finishValidate라는 플래그를 주고, 성공할 경우에 값을 true로 변경합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 후 useEffect를 통해서 finishValidate가 true가 되었을 때 오류 검증 통과 후 로직을 적어줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cS9ErI/btsddZBMXel/P2WtQUdbB5Vm5nlSPKDufk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cS9ErI/btsddZBMXel/P2WtQUdbB5Vm5nlSPKDufk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cS9ErI/btsddZBMXel/P2WtQUdbB5Vm5nlSPKDufk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcS9ErI%2FbtsddZBMXel%2FP2WtQUdbB5Vm5nlSPKDufk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;362&quot; height=&quot;91&quot; data-origin-width=&quot;362&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apple과 banana의 값을 변경 후 테스트하면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;381&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1fc9G/btsdeIl5izW/UBAUl6H9dg2AEnqfMP9eh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1fc9G/btsdeIl5izW/UBAUl6H9dg2AEnqfMP9eh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1fc9G/btsdeIl5izW/UBAUl6H9dg2AEnqfMP9eh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1fc9G%2FbtsdeIl5izW%2FUBAUl6H9dg2AEnqfMP9eh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;381&quot; height=&quot;120&quot; data-origin-width=&quot;381&quot; data-origin-height=&quot;120&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주석에도 적었지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자에게 디테일한 오류를 보여주기 위해서는 setErrors를 통해서 apple, banana 값을 같이 변경해줘야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 후 apple 오류에 대한 메시지를, banana 오류에 대한 메시지를 사용자에게 노출시킬 수 있습니다.&lt;/p&gt;</description>
      <category>Javascript/React.js</category>
      <category>react</category>
      <category>useState</category>
      <author>강디너</author>
      <guid isPermaLink="true">https://kdinner.tistory.com/121</guid>
      <comments>https://kdinner.tistory.com/121#entry121comment</comments>
      <pubDate>Sun, 30 Apr 2023 18:42:50 +0900</pubDate>
    </item>
    <item>
      <title>Next.js 데이터 가져오는 방법 (Data Fetching)</title>
      <link>https://kdinner.tistory.com/120</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js 에서 데이터를 가져오는 방법이 여러 가지 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;getServerSideProps&lt;/li&gt;
&lt;li&gt;getStaticPaths&lt;/li&gt;
&lt;li&gt;getStaticProps&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js에서는 서비스에 따라 다양한 방식으로 콘텐츠를 렌더링 할 수 있도록 지원해주는데 SSR, SSG, CSR, ISR 이 있습니다. 이러한&amp;nbsp;방식에 따라 데이터 패칭 하는 방식이 다릅니다.(사용하는 함수도 달라요.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #8a3db6;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;getServerSideProps&amp;nbsp;&lt;/span&gt;&lt;/b&gt;- &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;SSR &lt;/span&gt;&lt;/b&gt;&lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식문서&lt;/a&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서만 실행되고, 브라우저에서는 실행되지 않기 때문에 브라우저에 로그가 찍히지 않습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1661078016522&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
    context object 에 있는 데이터
    
    params: 페이지가 동적 경로일 경우 - 페이지 이름이 [id].js일 경우 params는 { id: 값 }
    req: HTTP request object
    res: HTTP response object
    query: 동적 경로 매개변수를 포함한 query의 값
    preview: 페이지가 Preview Mode일 경우 true
    previewData: setPreviewData에서 설정한 데이터
    등등...
*/

export async function getServerSideProps(context) {
  return {
    props: {}, 				// 컴포넌트가 받을 props
    revalidate: 0, 			// 페이지가 재생성될 지연 시간
    notFound: false,			// true일 경우 404
    redirect: { 			// 리다이렉트할 페이지의 경로
    	destination: '/'   		// 리다이렉트 경로
    },
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*pre-render&lt;/b&gt;란 빌드할 때 특정 페이지를 미리 HTML을 만들어주는 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;getServerSideProps&amp;nbsp;&lt;/span&gt;&lt;/b&gt;는 &lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;페이지&lt;/b&gt;만 사용 가능합니다. 페이지가 아닌 파일에서는 사용할 수 없습니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;(_app, _document, _error 등 / 문서에서는 페이지 내에서만 export 할 수 있다고 적혀있네요.)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;getServerSideProps&amp;nbsp;&lt;/span&gt;&lt;/b&gt;는 서버에서만 실행되어서 브라우저에서 로그를 확인할 수 없습니다.(불편...)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;getServerSideProps&amp;nbsp;&lt;/span&gt;&lt;/b&gt;가 선언된 페이지는 빌드와 상관없이 매번 페이지에 들어올 때마다 데이터를 서버에 요청합니다. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;그리고 반환한 props를 이용해서 렌더링 합니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;(next/link, next/router를 이용한&amp;nbsp; 페이지 이동인 경우)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;getServerSideProps&amp;nbsp;&lt;/span&gt;&lt;/b&gt;는 데이터 변경이 잦고, 개인화된 사용자 경험이 필요할 때 사용합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;(예를 들면 와디즈의 홈처럼 새로운 데이터가 중요하고, AI 추천 같이 사용자마다 보여줘야 하는 경우가 다를 경우)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;getServerSideProps&amp;nbsp;&lt;/span&gt;&lt;/b&gt;는 자주 업데이트가 필요한 데이터가 포함되어있는데, pre-render 할 필요가 없는 경우 &lt;b&gt;추천하지 않습니다.&lt;/b&gt; 문서에서는 클라이언트 측에서 데이터를 가져오라고 권합니다. 이런 경우를 예를 든 것이 대시보드 페이지입니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;SEO가 필요 없기 때문에 pre-render 할 필요도 없고, 데이터도 자주 업데이트되기 때문에 useEffect를 이용한 클라이언트 사이드 데이터 패칭을 추천합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt; &lt;b&gt;- SSG &lt;/b&gt;&lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching/get-static-props&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식문서&lt;/a&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에서만 실행되고, 브라우저에서는 실행되지 않기 때문에 브라우저에 로그가 찍히지 않습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1661088743718&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
    context object 에 있는 데이터
    
    params: 페이지가 동적 경로일 경우 - 페이지 이름이 [id].js일 경우 params는 { id: 값 }
    req: HTTP request object
    res: HTTP response object
    query: 동적 경로 매개변수를 포함한 query의 값
    preview: 페이지가 Preview Mode일 경우 true
    previewData: setPreviewData에서 설정한 데이터
*/


export async function getStaticProps(context) {
  return {
    props: {}, 				// 컴포넌트가 받을 props
    revalidate: 10, 			// 페이지가 재생성될 지연 시간
    notFound: false,			// true일 경우 404
    redirect: { 			// 리다이렉트할 페이지의 경로
    	destination: '/'   		// 리다이렉트 경로
    },
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt;&amp;nbsp;는 SSG로 만들기 위해 사용하며, 프로젝트가 빌드될 때 데이터를 가져옵니다.(SEO에 유리)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;빌드 시 데이터를 미리 받아오기 때문에 매우 빠른 속도로 페이지에 렌더링 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt;&amp;nbsp;를 사용하면 서버 측에서만 실행되기 때문에 JS 번들에도 포함되지 않고, 데이터베이스 쿼리를 작성할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;도&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;b&gt;페이지&lt;/b&gt;만 사용 가능합니다. 페이지가 아닌 파일에서는 사용할 수 없습니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;(_app, _document, _error 등)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt;&amp;nbsp;는 &lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;getServerSideProps&amp;nbsp;&lt;/span&gt;&lt;/b&gt;와 다르게 매번 데이터를 요청하지 않기 때문에 업데이트가 잦지 않은 static한 페이지일 경우 추천합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt;&amp;nbsp;는 유저 단위가 아닌 공통으로 캐시가 될 수 있는 데이터를 사용할 때 유리합니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;예를 들어 블로그 포스트 같이 이미 데이터는 정해져 있고, 페이지에서는 해당 포스트만 보여주고 변동이 많이 없을 때 추천합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;getStaticPaths&lt;/span&gt;&lt;/b&gt; &lt;b&gt;- SSG&lt;/b&gt; &lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching/get-static-paths&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식문서&lt;/a&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동적 경로를 이용해서 페이지를 만들고 싶은데 SSG를 사용하고 싶다. &lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt; 를 같이 사용하면서 빌드 타임 때 정적으로 렌더링 할 path를 설정해줍니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1661092131539&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// pages/posts/[id].js

export async function getStaticPaths() {
	const res = await fetch(...);
    const posts = await res.json();
    
    const paths = posts.map((post)) =&amp;gt; ({
    	params: { id: post.id }
    });
    return {
	paths,			// 빌드타임에 pre-render 할 경로들
        fallback: false,	// ture or 'blocking'   -&amp;gt; 자세한건 아래에서 설명
    }
}

// `getStaticPaths` requires using `getStaticProps`
export async function getStaticProps(context) {
  return {
    // Passed to the page component as props
    props: { post: {} },
  }
}

// router.isFallback를 이용해서 Fallback이 렌더링되고 있는지 감지
export default function Post({ post }) {
  const router = useRouter()

  // If the page is not yet generated, this will be displayed
  // initially until getStaticProps() finishes running
  if (router.isFallback) {
    return &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;
  }

  // Render post...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;getStaticPaths&lt;/span&gt;&lt;/b&gt; 는 &lt;b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;getServerSideProps &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와 사용할 수 없습니다. 무조건 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt; 와 함께 사용해야 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;getStaticPaths&lt;/span&gt;&lt;/b&gt;&amp;nbsp;는 paths와 fallback을 반환하는데, paths는 빌드 타임에 pre-render 할 경로들이고, &lt;b&gt;fallback&lt;/b&gt;은 &lt;b&gt;false&lt;/b&gt;, &lt;b&gt;true,&lt;/b&gt;&amp;nbsp;'&lt;b&gt;blocking&lt;/b&gt;'를 반환합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;fallback&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;false &lt;/b&gt;인 경우&amp;nbsp; paths에 등록되지 않은 경로로 들어가면 404 페이지가 됩니다. 이 옵션은 생성할 path가 적거나 새로운 페이지가 자주 추가되지 않는 경우에 유용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;true&lt;/b&gt; 인 경우 paths에 등록되지 않은 경로로 들어가면 404 페이지가 되는 대신에 별도의 컴포넌트를 보여줄 수 있습니다.(router.isFallback으로 감지) 그 후 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; 를 통해 데이터를 가져오고 props를 가져오면 정적 페이지를 생성합니다. 당시에는 pre-render가 되지 않지만 한번 렌더링 후부터는 pre-render에 포함됩니다. (와디즈의 펀딩처럼 계속적으로 상품이 등록될 때 유용한 기능입니다.)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;'blocking' &lt;/b&gt;인 경우 paths에 포함되지 않은 경로는 SSR과 동일하게 생성합니다. &lt;b&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;getStaticPaths&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; 가 될 때까지 기다린 다음 성공하면 해당 페이지 경로를 캐싱한 후 다음 요청 시에는 캐싱된 데이터를 리턴합니다. true와 동일하게 한번 렌더링 후부터는 pre-render가 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;Incremental Static Regeneration&lt;/b&gt;&lt;/span&gt; &lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식문서&lt;/a&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ISR&lt;/span&gt; 방식이 무엇이냐.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; 함수를 이용해서 SSG 방식으로 만들면 빌드 시점에 페이지가 생성되지만, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;ISR&lt;/b&gt; &lt;/span&gt;방식은 일정 주기마다 데이터의 최신 여부를 검사하고 업데이트된 데이터로 페이지를 다시 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;ISR &lt;/b&gt;방식을 이용하면 전체 사이트를 다시 빌드할 필요 없이 최신 데이터로 정적 페이지를 만들 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1661096900057&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Blog({ posts }) {
  return (
    &amp;lt;ul&amp;gt;
      {posts.map((post) =&amp;gt; (
        &amp;lt;li key={post.id}&amp;gt;{post.title}&amp;lt;/li&amp;gt;
      ))}
    &amp;lt;/ul&amp;gt;
  )
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    // Next.js will attempt to re-generate the page:
    // - When a request comes in
    // - At most once every 10 seconds
    revalidate: 10, // In seconds
  }
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// the path has not been generated.
export async function getStaticPaths() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // Get the paths we want to pre-render based on posts
  const paths = posts.map((post) =&amp;gt; ({
    params: { id: post.id },
  }))

  // We'll pre-render only these paths at build time.
  // { fallback: blocking } will server-render pages
  // on-demand if the path doesn't exist.
  return { paths, fallback: 'blocking' }
}

export default Blog&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;getStaticProps&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt; 의 props에 revalidate를 추가하고, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #ef6f53;&quot;&gt;getStaticPaths&lt;/span&gt;&lt;/b&gt; 는 'blocking' 이어야 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;revalidate 값이 10이면 모든 사용자는 10초 동안 생성된 동일한 버전의 사이트를 봅니다. 캐시를 초기화하는 방법은 10초가 지난 후 누군가가 해당 페이지를 방문하면 캐시가 초기화되어서 새로 업데이트된 페이지를 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(상품의 가격, 성명, 리뷰 등)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ISR&lt;/span&gt; &lt;/b&gt;방식은 SSG의 성능상 이점을 챙기면서도 사용자에게는 업데이트된 콘텐츠를 제공할 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript/React.js</category>
      <category>CSR</category>
      <category>ISR</category>
      <category>Next.js</category>
      <category>SSR</category>
      <author>강디너</author>
      <guid isPermaLink="true">https://kdinner.tistory.com/120</guid>
      <comments>https://kdinner.tistory.com/120#entry120comment</comments>
      <pubDate>Mon, 22 Aug 2022 01:09:34 +0900</pubDate>
    </item>
  </channel>
</rss>