<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>honey_bee.log</title>
        <link>https://velog.io/</link>
        <description>미래의 개발자!</description>
        <lastBuildDate>Wed, 29 Mar 2023 14:58:48 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>honey_bee.log</title>
            <url>https://velog.velcdn.com/images/honey_bee/profile/68278492-5aec-4e76-ad73-beff9ac4bfa5/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. honey_bee.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/honey_bee" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[TIL]CS:CORS]]></title>
            <link>https://velog.io/@honey_bee/TIL2-zfhzzqlw</link>
            <guid>https://velog.io/@honey_bee/TIL2-zfhzzqlw</guid>
            <pubDate>Wed, 29 Mar 2023 14:58:48 GMT</pubDate>
            <description><![CDATA[<h3 id="corscross-origin-resource-sharing">CORS(cross origin resource sharing)</h3>
<p>다른 도메인(리소스: 프로토콜,호스트,포트)의 자원을 쓰려면 자원의 주인이 허락한 규약을 지켜야하는데 이러한 규약을 표준한 것이 CORS 입니다.</p>
<p>(기존 브라우저 정책은 서로 다른 도메인으로부터 리소스가 칠요한 경우 보안상의 이유로 다른 도메인의 리소스를 가져오는 것이 불가능했으나 이를 해결하고자 등장한 표준 기술이 CORS이며 리소스를 요청할때 접근 권한을 부여하는 작동하는 원리(매커니즘))</p>
<p>  <strong>참고: 왜 필요할까?</strong></p>
<p>  (CORS가 없이 모든 곳에서 데이터를 요청할 수 있게 된다면, 다른 사이트에서 원래 사이트를 흉내낼 수 있게 된다.
  만약 기존 사이트와 완전히 동일하게 동작하도록 하여 사용자가 로그인을 하도록 하고, 로그인했던 세션 또는 토큰을 탈취하여 악의적으로 정보를 꺼내오거나 다른 사용자의 정보를 입력하는 등 헤킹을 할 수 있다. 
  하지만 이런 공격을 할 수 없도록 브라우저에서 보호하고, 필요한 경우에만 서버와 협의하여 요청할 수 있도록 하기 위해서 필요한 것이다.)</p>
<p><strong>CORS는 어떻게 동작하나?</strong>
Simple requests인 경우..</p>
<p>서버로 요청을 합니다. 서버의 응답이 왔을 때 브라우저가 요청한 <code>Origin</code>과 응답한 헤더 <code>Access-Control-Request-Headers</code>의 값을 비교하여 유효한 요청이라면 리소스를 응답합니다. 만약 유효하지 않은 요청이라면 브라우저에서 이를 막고 에러가 발생합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]CS: 배열과 링크드리스트]]></title>
            <link>https://velog.io/@honey_bee/TIL1</link>
            <guid>https://velog.io/@honey_bee/TIL1</guid>
            <pubDate>Wed, 29 Mar 2023 14:58:39 GMT</pubDate>
            <description><![CDATA[<h1 id="🤓-what-i-learned-today">🤓 What I Learned Today</h1>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/247f2b46-3425-491c-b84a-81c0f8688a60/image.png" alt="">
(참고서적)</p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/7e5f9725-33af-4431-a2ed-7789952fad8c/image.png" alt=""></p>
<h4 id="배열array">배열(Array)</h4>
<p>미리 크기를 정해 놓은 정적 자료구조여서 해당 크기 만큼의 연속된 메모리 주소를 할당 받습니다. 크기를 미리 정해 놓았기 때문에 수정하는 것이 불가하며 이미 크기를 정해 놓아 해당 배열 크기 이상의 데이터를 저장할 수 없다는 단점이 있습니다.</p>
<p>→ 배열은 정보 저장할 때 많이 쓰이는데 불규칙 정보를 저장하거나 이후에 다시 사용할 정보를 저장 할때…</p>
<br>
**+index**

<p>  연속된 메모리 주소를 할당 받고 있기 때문에 인덱스 라는 것을 갖게 되는데 배열에 접근할 때 대괄호 안에 숫자가 인덱스입니다. 인덱스를 갖게 된다는 것은 접근과 탐색에 용이하다는 것이기도 합니다.</p>
<br>
<br>
<br>


<h4 id="링크드-리스트linked-list">링크드 리스트(Linked List)</h4>
<p>연결리스트라고 불리며 크기를 정할 필요가 없는 동적 자료 구조 이며 추가와 삭제에 용이 합니다. (연속된 메모리 주소 할당 안받음.)</p>
<p>→ 음악 플레이어 앱에 이전 곡과 다음 곡이 연결되어 있는 연결 리스트로 많이 활용 혹은 포토샵의 히스토리 기능</p>
<br>
**+Node**

<p>  Node라는 게 존재하며 노드안에 데이터가 있고 다음 데이터를 가리키는 주소를 가지고 있는 연결되어 이어진 형태 </p>
<p>  크기가 정해져있지 않기 때문에 제한이 없고 데이터 추가,삭제가 자유롭다는 장점</p>
<p>  반면 배열처럼 연속적인 메모리 주소를 할당 받지 않았기 때문에 임의로 접근이 불가하여 데이터를 탐색할때 순차적으로 접근해야합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]CS: 스택,큐]]></title>
            <link>https://velog.io/@honey_bee/TIL2</link>
            <guid>https://velog.io/@honey_bee/TIL2</guid>
            <pubDate>Tue, 28 Mar 2023 14:47:32 GMT</pubDate>
            <description><![CDATA[<h3 id="스택stack">스택(Stack)</h3>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/864068ed-6d19-4f77-b262-60e9c84e7316/image.png" alt=""></p>
<p>스택(Stack) 자료구조는 벽돌 쌓듯이 차곡차곡 쌓아 올린 형태이고</p>
<p>내부의 데이터는 최근(마지막)에 들어온 자료인 ‘top’을 통해 접근할 수 있습니다. 즉 시간 순서에 따라 데이터가 쌓이고 </p>
<p>데이터를 삽입할 때는, (top) 위에 쌓게 됩니다.(push 연산) </p>
<p>또한 스택에서 데이터를 삭제할때는 가장 마지막에 삽입 된 데이터가 가장 먼저 삭제됩니다.(pop 연산)</p>
<p> 이러한 스택의 구조를 후입 선출 자료구조 라고 합니다.</p>
<p>+스택의 활용 예시를 하나 들어주세요!</p>
<ul>
<li><p><strong>웹 브라우저 방문기록 (뒤로 가기)</strong></p>
<ul>
<li>가장 마지막에 열린 페이지부터 다시 보여준다.</li>
</ul>
</li>
<li><p><strong>실행 취소 (undo)</strong></p>
<ul>
<li>가장 마지막에 실행된 것부터 실행을 취소한다.</li>
</ul>
</li>
<li><p><strong>역순 문자열 만들기</strong></p>
<ul>
<li>가장 마지막에 입력된 문자부터 출력한다.</li>
</ul>
</li>
<li><p><strong>후위 표기법 계산</strong></p>
<ul>
<li>연산자가 피연산자들의 뒤에 위치.</li>
</ul>
</li>
<li><p><strong>수식의 괄호 검사</strong></p>
<ul>
<li><p>연산자 우선순위 표현을 위한 괄호 검사</p>
<h3 id="큐queue">큐(Queue)</h3>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/6dbb0460-358a-4e41-9c28-98d767b4477b/image.png" alt=""></p>
</li>
</ul>
<pre><code>큐의 자료구조는 가장 먼저 삽입된 데이터가 먼저 삭제 된다는 특징을 가진 선입선출방식입니다. 

큐는 삽입과 삭제가 다른 방향에서 이루어지는데 리어(rear)에서 이루어지는 삽입 연산을 인큐(enQueue) 라고 하며 프론트(front)에서 이루어지는 삭제 연산을 디큐(dnQueue) 라고 합니다.

+큐의 활용 예시를 하나 들어주세요!

- **큐는 주로, 데이터가 입력된 순서에 따라 처리되어야 할 때 사용된다.**
    - 일상생활에서, 줄을 서서 기다려야하는 모든 행동
        - 은행 업무
        - 콜센터 고객 대기시간
        - 놀이동산
    - 프로세스 관리
    - 너비 우선 탐색(BFS, Breadth-First Search) 구현
    - 캐시(Cache) 구현</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] CS: 알고리즘과 시간복잡도 Big-O(빅오)]]></title>
            <link>https://velog.io/@honey_bee/TIL</link>
            <guid>https://velog.io/@honey_bee/TIL</guid>
            <pubDate>Tue, 28 Mar 2023 14:47:05 GMT</pubDate>
            <description><![CDATA[<h1 id="🤓-what-i-learned-today"><strong>🤓 What I Learned Today</strong></h1>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/32ba268e-f536-45b4-a087-afb91718f410/image.png" alt="">
(참고서적)</p>
<h3 id="알고리즘">알고리즘</h3>
<p>매일 알고리즘을 풀지만 알고리즘에 대한 정의는 제대로 알아보지 않았다. 알고리즘이란 문제,목적을 달성하기 위해 여러 과정을 거치게 되는데 당연히 효율적이고 사용 환경에 최적인 알고리즘을 선택하여 풀어야한다. </p>
<p>알고리즘 시간은 코드를 실행하는 속도에 의존하는데 이 속도는 컴퓨터의 처리속도, 언어 종류, 컴파일러 속도에 따라 달려있다.</p>
<p>여기서 어제 배운 복잡도가 나오는데 알고리즘의 성능 분석은 실행에 필요한 <code>공간 측면</code>에서 분석하는 <code>공간 복잡도</code>와 <code>실행 소요시간</code> 측면에서 분석하는 <code>시간 복잡도</code>를 추정하여 평가한다. 따라서 시간 복잡도가 낮은 알고리즘을 선택하여 사용한다.</p>
<hr>
<h3 id="빅오표기법">빅오표기법</h3>
<p>알고리즘 성능을 수학적으로 표기해주는 표기법으로 알고리즘의 데이터나 사용자 증가률에 따른 알고리즘 성능을 예측하는게 목표여서 중요하지 않은 부분인 상수와 같은 숫자는 모두 제거한다. 즉, 불필요한 연산을 제거하고 알고리즘 분석을 쉽게 할 목적으로 사용된다. <strong>알고리즘이 해당 차수이거나 그보다 낮은 차수의 시간복잡도를 가진다는 의미이기도 한다.</strong></p>
<p>여기서 측정되는 복잡성에는 시간 복잡도와 공간 복잡도가 있다.</p>
<ul>
<li>시간 복잡도: 입력되는 n의 크기에 따라 실행되는 조작의 수</li>
<li>공간 복잡도: 알고리즘이 실행될 때 사용하는 메모리 양</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]CS : 복잡도 - 시간복잡도? 공간복잡도?]]></title>
            <link>https://velog.io/@honey_bee/TILCS-%EB%B3%B5%EC%9E%A1%EB%8F%84-%EC%8B%9C%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84-%EA%B3%B5%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84</link>
            <guid>https://velog.io/@honey_bee/TILCS-%EB%B3%B5%EC%9E%A1%EB%8F%84-%EC%8B%9C%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84-%EA%B3%B5%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84</guid>
            <pubDate>Sun, 26 Mar 2023 14:48:44 GMT</pubDate>
            <description><![CDATA[<h1 id="🤓-what-i-learned-today"><strong>🤓 What I Learned Today</strong></h1>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/33b0f8fd-d78e-45b9-93b2-ad1de6bd029d/image.png" alt="">
(참고서적)</p>
<h3 id="시간복잡도와-공간복잡도"><strong>시간복잡도와 공간복잡도</strong></h3>
<p>Q. 
<strong>시간복잡도와 공간복잡도가 무엇인지 설명해주실 수 있을까요?</strong></p>
<p>A.
알고리즘을 평가하는 지표로  </p>
<p><code>시간 복잡도</code>는 <strong>알고리즘의 수행시간</strong>을 평가하고 </p>
<p><code>공간 복잡도</code>는 알고리즘 수행에 필요한 <strong>메모리 사용량</strong>을 평가 합니다.</p>
<p>여기서 <code>복잡도</code>란 가독성와 다른 의미로 쓰입니다. 불특정한 함수의 성능적인 측면에서 복잡도를 의미합니다.동일한 기능을 수행하는 알고리즘이 있다면 일반적으로 복잡도가 낮은 알고리즘이 좋은 알고리즘입니다.</p>
<hr>
<p><strong>추가개념❗️</strong></p>
<p><code>시간 복잡도(Time Complexity)</code> 
(알고리즘의 수행시간을 분석할 때 시간 복잡도를 사용하는데 수행시간은 실행환경.)</p>
<p>*<em>왜 시간 복잡도를 쓸까? *</em>
효율적으로 코드를 개선하는 데 쓰이는 척도가 된다.</p>
<p>시간 복잡도는 3가지 경우로 나타낸다.</p>
<ol>
<li><p>최선의 경우 (Best Case)</p>
<ul>
<li>빅 오메가 표기법 사용</li>
<li>최선의 시나리오로 최소 이만한 시간이 걸림</li>
</ul>
</li>
<li><p>최악의 경우 (Worst Case)</p>
<ul>
<li>빅 오 표기법 사용</li>
<li>최악의 시나리오로 아무리 오래 걸려도 이 시간보다 덜 걸림</li>
</ul>
</li>
<li><p>평균적인 경우 (Average Case)</p>
<ul>
<li>빅 세타 표기법 사용</li>
<li>평균 시간을 나타냄</li>
</ul>
</li>
</ol>
<p>평균적인 경우를 가장 많이 사용할 것 같지만 알고리즘이 복잡해질수록 평균적인 경우는 구하기가 매우 어려워 지기 때문에 <strong>최악의 경우</strong>로 알고리즘의 성능을 파악</p>
<p><code>공간 복잡도(Space Complexity)</code>
(공간 복잡도는 알고리즘에서 사용하는 메모리 양)</p>
<p>공간 복잡도는 보조공간(Auxiliary Space)과 입력 공간(input size)을 합친 포괄적인 개념</p>
<p>보조 공간(Auxiliary Space)은 알고리즘이 실행되는 동안 사용하는 임시 공간이기 때문에 입력 공간(input size)을 고려하지 않고  공간 복잡도도 시간 복잡도와 유사하게 빅오 표기법을 사용</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[회고]항해99 수료 ..앞으로 진짜 시작!]]></title>
            <link>https://velog.io/@honey_bee/%ED%9A%8C%EA%B3%A0%ED%95%AD%ED%95%B499-%EC%88%98%EB%A3%8C-..%EC%95%9E%EC%9C%BC%EB%A1%9C-%EC%A7%84%EC%A7%9C-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@honey_bee/%ED%9A%8C%EA%B3%A0%ED%95%AD%ED%95%B499-%EC%88%98%EB%A3%8C-..%EC%95%9E%EC%9C%BC%EB%A1%9C-%EC%A7%84%EC%A7%9C-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Sun, 26 Mar 2023 07:35:22 GMT</pubDate>
            <description><![CDATA[<p><strong>[항해99 수료]22.12.05 ~ 23.03.22</strong></p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/243dc464-38bb-4a26-93d4-f9c0468ddba0/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/7d119dee-eea4-4877-af74-6c60c6ef28a7/image.png" alt=""></p>
<p>마지막 순간까지 &quot;내가 잘 하고 있나?&quot; &quot;이게 맞나?&quot; 하고 의문이 가득이었던 99일이 끝이 났다. 도중에 하차한 팀원들도 있어서 그때마다 마음이 흔들렸지만 담당 매니저님한테 쪼르륵 달려가서 하소연도 하고 코드라도 한번 더 보고 새벽에 남은 팀원들이랑 고민상담도 하고 실없는 얘기도 하면서 버텼던 것 같다...(담당 매니저님하고 팀원들에게 너무 감사하다. 덕분에 버틸 수 있었다.😣)</p>
<p>프로젝트를 참여하면서도 다른 사람들과 실력이 비교되서 나 혼자 울면서 모니터를 바라보다가 아는 부분이 나와서 풀리면 헤헤 웃고 울다가 웃다가 약간 미친 사람처럼 지냈던것 같다. </p>
<p>수료하고 추가적으로 인텔리픽에서 진행하는 취업특강을 듣고 이력서 초안과 CS준비를 하면서 금요일에 오프라인 모각지(모여서 각자 지원)을 참여하고나니 이제 정말 나홀로 준비해야하는 구나 라는 마음에 무섭기도 하고 앞으로 뭘 더 준비해야할까 고민이 많이 됐다.</p>
<p>살짝 번아웃이 왔었지만 지금은 멈출때가 아니라 더 열심히 달려야할때이니 
정신차리고 앞으로 계획은 잘 해서 부족한 부분을 채우고 남들보다 더 공부해서 
개발자 전직 성공해야지..! </p>
<p>항상 다짐하기...</p>
<p>1.내가 하고 싶은 것은?(목적)
2.그것을 하기 위해서 코드 짜다가 발생한 문제는 어떤것?(문제 정의)
3.그 문제를 해결하기 위해 노력한 것(구글 검색, 시도한 코드)
4.해결이 안된다면 새로운 문제 정의가 필요한가?를 생각해보고 처음 설정한 문제 정의가 맞다면 다시 해결하려고 노력</p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/11a2df80-18bf-4753-b8c5-d5423df2af76/image.jpeg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]CS: var,let TDZ 그리고 호이스팅?]]></title>
            <link>https://velog.io/@honey_bee/TIL230311-%EC%A7%9C%ED%88%AC%EB%A6%AC-%EC%A7%80%EC%8B%9D..varlet-TDZ-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85</link>
            <guid>https://velog.io/@honey_bee/TIL230311-%EC%A7%9C%ED%88%AC%EB%A6%AC-%EC%A7%80%EC%8B%9D..varlet-TDZ-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85</guid>
            <pubDate>Fri, 10 Mar 2023 16:19:44 GMT</pubDate>
            <description><![CDATA[<h1 id="🤓-what-i-learned-today"><strong>🤓 What I Learned Today</strong></h1>
<p>JavaScript에서 <strong>호이스팅</strong>(hoisting)이란 *인터프리터가 *변수와 함수의 메모리 공간 선언 전에 할당하는 것을 의미한다.</p>
<p>좀 더 쉽게 말하자면 자바스크립트에서 물 흐르는 것처럼 위에서 아래로 실행되는데  호이스팅이란 미리 선언한 변수와 함수를 쭉 읽으며 가져가서 메모리에 기억을 해둔다. 즉, 함수가 실행되기 전에 안에 있는 변수들을 범위의 최 상단으로 끌어올리는 것이다.</p>
<p>*<em>var *</em></p>
<p>호이스팅시 변수의 선언과 초기화(undefinded) 같이 시키고 값 할당은 나중에 그 줄 가서 할당을 한다.</p>
<pre><code class="language-jsx">console.log(a) //undefinded
var a = 1
console.log(a)//1</code></pre>
<p>전역변수(블락 밖에서 선선을 한 어디든 쓰일 수 있는 변수)와 지역변수(블락 안에서 선언된 변수, 블락 안에서만 쓸 수 있음)의 개념이 확실치 않고 <code>함수만 지역변수로 호이스팅이 되고  나머지는 다 전역변수로 올려버린다.</code> 변수의 이름이 중복이 된다.</p>
<p><strong>let</strong></p>
<p>let 도 호이스팅이 된다. 다만, let 의 변수는 TDZ(Temporal Death Zone)라는 일시적으로 죽은 범위의 개념을 만들어서 #선언문이 나오기 전까지 #에 접근할수 없도록 했다.</p>
<hr>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/377a1ffe-7e03-49d3-afbf-2fa4d386e743/image.png" alt=""></p>
<ul>
<li><p>인터프리터? interpret 라는 단어는 해석하다라는 뜻으로 프로그램에서의 뜻은 언어의 소스 코드를 바로 실행하는 컴퓨터 프로그램 또는 환경</p>
<ul>
<li><p>단점으로는</p>
<ul>
<li>컴파일러와 다르게 한번에 한 문장씩 읽고 번역하여 실행시키는 과정을 반복하다보니 실행이 느리다.</li>
<li>한번에 한 문장씩 읽기때문에 프로그램을 실행해봐야지만 오류 발견이 가능</li>
</ul>
</li>
<li><p>장점으로는</p>
<ul>
<li>메모리 효율이 좋다.</li>
<li>코드 변경시 빌드 과정없이 바로 실행이 가능</li>
</ul>
<p>→<strong>대표적인 언어에는 Python, R, Ruby</strong></p>
</li>
</ul>
</li>
</ul>
<ul>
<li><p>컴파일? compile 단어의 자체 뜻은 모아서 묶음으로 만든다고 하는데 프로그램에서의 단어의 뜻은 프로그램 전체를 스캔하여 이를 모두 ~ 기계어로 번역한다는 뜻이 있다.</p>
<ul>
<li>단점으로는<ul>
<li>1.프로그램을 실해하는데 필요한 모든 파일을 스캔하기 때문에 초기 스캔 시간이 오래걸린다.</li>
</ul>
<ol>
<li>컴파일러는 기계어로 번역시 오브젝트 코드 라는 파일을 만드는데 이 오브젝트 코드를 다시 묶어서 하나의 실행 파일로 만드는 링킹 작업을 한다. 이 과정에서 메모리를 많이 사용</li>
</ol>
</li>
<li>장점으로는<ul>
<li>1.초기 스캔은 오래 걸리지만 한번 스캔하면 실행 파일을 만들어 놓고 계속 사용하기 때문에 실행 속도는 인터프리터보다 빠르다.</li>
</ul>
<ol>
<li>컴파일러는 오류 메세지를 생성할때 전체 코드를 검사한 후 오류 메시지를 생성하는데 프로그램 실행 전에 오류 발견이 가능하다.</li>
</ol>
</li>
</ul>
<p>→ <strong>컴파일러(Comiler)를 사용하는 대표적인 언어에는 C, C++, C#, CLEO, COBOL 등 있고 게 컴파일러를 사용하여 실행하는 언어를 컴파일러형 언어(Compiled Language) 라고 한다!</strong></p>
</li>
</ul>
<hr>
<p>*변수?데이터를 저장하기 위해 프로그램에 의해 이름을 할당받은 메모리 공간</p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/c6f89417-e463-49cc-b3be-6336b69c63e5/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React Native]react-navigation/bottom-tabs]]></title>
            <link>https://velog.io/@honey_bee/React-Nativereact-navigationbottom-tabs</link>
            <guid>https://velog.io/@honey_bee/React-Nativereact-navigationbottom-tabs</guid>
            <pubDate>Tue, 21 Feb 2023 20:10:26 GMT</pubDate>
            <description><![CDATA[<p><strong>하단 탭 내비게이터 라이브러리 설치</strong></p>
<pre><code class="language-jsx">npm install @react-navigation/bottom-tabs</code></pre>
<pre><code class="language-jsx">import React from &#39;react&#39;;
import {createBottomTabNavigator} from &#39;@react-navigation/bottom-tabs&#39;;

const Tab = createBottomTabNavigator();

import Home from &#39;../screens/Home&#39;;
import Profile from &#39;../screens/Profile&#39;;

const App = ({navigation}) =&gt; {
  return (
    &lt;Tab.Navigator initialRouteName=&quot;Home&quot;&gt;
      &lt;Tab.Screen name=&quot;Home&quot; component={Home} /&gt;
      &lt;Tab.Screen name=&quot;Profile&quot; component={Profile} /&gt;
    &lt;/Tab.Navigator&gt;
  );
};

export default App;
</code></pre>
<p>이렇게 사용하면 되고  네이티브 스택 내비게이터와 하단 탭 내비게이터를 같이 사용하고 싶으면</p>
<p>하단 내비를 컴포넌트화 한 이후  App.js 에 넣어주면 된다.
<br>
<br>
<br></p>
<p><strong>App.js</strong></p>
<pre><code class="language-jsx">import {NavigationContainer} from &#39;@react-navigation/native&#39;;
import {createNativeStackNavigator} from &#39;@react-navigation/native-stack&#39;;

const Stack = createNativeStackNavigator();
.
.
생략
.
.
const App = () =&gt; {
  return (
    &lt;&gt;
      &lt;StatusBar style=&quot;light&quot; /&gt;
      &lt;NavigationContainer&gt;
        &lt;Stack.Navigator&gt;
          &lt;Stack.Screen
            name=&quot;Main&quot;
            component={BottomTabNav} //BottomTabNav.js 컴포넌트해주고 넣기
            options={{headerShown: false}} 
                        //만약 위의 {headerShown: false}  값을 설정해주지 않는다면 두 개의 헤더가 나타나는 문제가 발생하여
                        // 하단 탭 내비게이터를 네이티브 스택 내비게이터 내부에서 사용할 때 이 설정을 해주는 것이 중요!
          /&gt;
          &lt;Stack.Screen name=&quot;Home&quot; component={Home} /&gt;
          &lt;Stack.Screen name=&quot;Profile&quot; component={Profile} /&gt;
          &lt;Stack.Screen name=&quot;Calendars&quot; component={Calendars} /&gt;
        &lt;/Stack.Navigator&gt;
      &lt;/NavigationContainer&gt;
    &lt;/&gt;
  );
};</code></pre>
<br>
<br>
<br>

<p><strong>스타일 넣기! 참고 :</strong></p>
<p><a href="https://stackoverflow.com/questions/59304281/create-custom-bottom-tab-navigator-in-react-native">Create custom bottom tab navigator in React native</a></p>
<pre><code class="language-jsx">const customTabBarStyle = {
    activeTintColor: &#39;#0091EA&#39;,
    inactiveTintColor: &#39;gray&#39;,
    style: {backgroundColor: &#39;white&#39; },
}
return (
    &lt;Tab.Navigator
    initialRouteName=&quot;Home&quot;
    activeColor=&quot;#fff&quot;
    tabBarOptions={customTabBarStyle}
    shifting=&quot;false&quot;&gt;
    &lt;Tab.Screen
    name=&quot;Home&quot;
    options={{
        tabBarLabel: &#39;&#39;,
        tabBarIcon: ({ color }) =&gt; (
            &lt;Icon name=&quot;home&quot; color={color} size={26} /&gt;
        )
    }}
    component={HomeScreen} /&gt;
    &lt;Tab.Screen
    name=&quot;Workout&quot;
    options={{
        tabBarLabel: &#39;&#39;,
        tabBarIcon: ({ color }) =&gt; (
            &lt;Icon name=&quot;fitness-center&quot; color={color} size={26} /&gt;
        )
    }}
    component={WorkoutTabScreen} /&gt;
    &lt;Tab.Screen
    name=&quot;Add&quot;
    options={{
        tabBarLabel: &#39;&#39;,
        tabBarIcon: ({ color }) =&gt; (
            &lt;View
            style={{
                position: &#39;absolute&#39;,
                bottom: 0, // space from bottombar
                height: 68,
                width: 68,
                borderRadius: 68,
                justifyContent: &#39;center&#39;,
                alignItems: &#39;center&#39;,
            }}
            &gt;
            &lt;Icon name=&quot;add-circle-outline&quot; color=&quot;grey&quot; size={68}/&gt;
            &lt;/View&gt;
        )
    }}
    component={PayScreenComponent}/&gt;
    &lt;Tab.Screen
    name=&quot;Store&quot;
    options={{
        tabBarLabel: &#39;&#39;,
        tabBarIcon: ({ color }) =&gt; (
            &lt;Icon name=&quot;store&quot; color={color} size={26} /&gt;
        )
    }}
    component={StoreLandingScreen} /&gt;
    &lt;Tab.Screen
    name=&quot;Profile&quot;
    options={{
        tabBarLabel: &#39;&#39;,
        tabBarIcon: ({ color }) =&gt; (
            &lt;Icon name=&quot;perm-identity&quot; color={color} size={26} /&gt;
        )
    }}
    component={ProfileScreen} /&gt;
    &lt;/Tab.Navigator&gt;
);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]230211 ]]></title>
            <link>https://velog.io/@honey_bee/TIL230211</link>
            <guid>https://velog.io/@honey_bee/TIL230211</guid>
            <pubDate>Sat, 11 Feb 2023 13:55:06 GMT</pubDate>
            <description><![CDATA[<h1 id="🤓-what-i-learned-today"><strong>🤓 What I Learned Today</strong></h1>
<p><a href="https://velog.io/@honey_bee/React-NativeReact-Navigation">React Navigation</a></p>
<p>이렇게 Navigation 을 만들어주었다만… 헤더에 제목이 기본값으로 들어가 있어서 그런지 매우 거슬렸다. 찾아보니 이 부분도 설정을 따로 해주면 된다고 하여 찾아보았다.</p>
<br>
<br>

<hr>
<h1 id="-🤔-code-snippets-">** 🤔 Code Snippets **</h1>
<p><strong>헤더를 숨기고 싶으면..!</strong></p>
<pre><code class="language-jsx">&lt;Stack.Screen name=&quot;Home&quot; component={Home} options={{headerShown: false}}/&gt;</code></pre>
<p>옵션을 넣어주면 된다.</p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/02aadd3a-693a-4ab1-ae9a-e83c10ee3aa2/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/7cc33cd0-9264-4f5d-abc2-20715b35cf34/image.png" alt=""></p>
<br>
<br>

<hr>
<h1 id="-🚀-challenges-experienced-">** 🚀 Challenges Experienced **</h1>
<br>

<p>라이브러리가 있어 기본 설정만 바꿔주면 되는 부분이라 생각보다 간단하였다. 
이 외에 다양한 설정이 있었는데…</p>
<p>헤더에 제목만 변경해 주려면</p>
<pre><code class="language-jsx">&lt;Stack.Screen name=&quot;Home&quot; component={Home} options={{title: &quot;홈&quot;}}/&gt;</code></pre>
<br>
<br>
이렇게 해주면 된다. 그러면 스타일도 변경하고 싶다면?

<pre><code class="language-jsx">&lt;Stack.Screen 
    name=&quot;Home&quot; 
    component={Home} 
    options={{
        title: &quot;홈&quot; , 
        headerStyle: {
            backgroundColor: &quot;#ffffff&quot;
        },
        headerTintColor: &quot;#ffffff&quot;,
        headerTitleStyle: {
            fontWeight:&#39;bold&#39;,
            fontSize: 20,
        },
    }}
/&gt;</code></pre>
<br>
<br>
그 외…

<p>화면 컴포넌트에서 navigation.setOptions 함수를 이용해도 된다고 한다.</p>
<pre><code class="language-jsx">function Home({navigation}) {
    useEffect(() =&gt; {
        navigation.setOption({title:&#39;홈&#39;})
},[navigation]);
}</code></pre>
<br>
<br>

<p>음… 여기에서 헤더의 제목만 숨기고 뒤로가기는 만들어 주고 싶다면?(iOS)</p>
<p>버튼으로 뒤로가기를 만들어 주는 방법도 있다.</p>
<br>
<br>

<pre><code class="language-jsx">&lt;Button onPress={() =&gt; navigation.pop()} title=&quot;뒤로가기&quot; /&gt;</code></pre>
<br>
<br>

<p>(iOS) 에서 이렇게 했다가는 StatusBar 영역을 침범…<SafeAreaView> 컴포넌트 이용해서 이렇게 고쳐준다.</p>
<pre><code class="language-jsx">import {SafeAreaView} from &#39;react-native-safe-area-context&#39;

&lt;SafeAreaView&gt;
    &lt;Button onPress={() =&gt; navigation.pop()} title=&quot;뒤로가기&quot; /&gt;
&lt;/SafeAreaView&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React Native]React Navigation]]></title>
            <link>https://velog.io/@honey_bee/React-NativeReact-Navigation</link>
            <guid>https://velog.io/@honey_bee/React-NativeReact-Navigation</guid>
            <pubDate>Sat, 11 Feb 2023 13:52:38 GMT</pubDate>
            <description><![CDATA[<p><strong>Navigation 이란?</strong></p>
<p>웹 브라우저에서 내비게이션은 URL을 입력해서 특정 페이지에 도달하고 링크를 사용하여 하위 페이지로 이동하는 개념이지만</p>
<p>앱에서는 버튼을 눌러서 한 화면에서 다른 화면으로 이동하거나 이전 화면으로 돌아가는 식</p>
<p>보통 *서드 파티 패키지인 react navigation을 사용한다. 라우팅 및 내비게이션을 추가하기 위해 만들어진 패키지이다.</p>
<p>(*서드 파티 패키지? 주로 편한 개발을 위해 플러그인이나 라이브러리 혹은 프레임워크를 이용하는 데 이처럼 제 3자로 중단다리 역할로 도움을 주는 것이 서드 파티라고 볼 수 있다.)</p>
<p>컴포넌트 기반의 라이브러리이므로 내비게이션 구성을 설정할 수 있는 다양한 컴포넌트를 제공한다.</p>
<p>공식 문서로 가서 상황에 맞게 터미널로 설치먼저 해주어야 한다.</p>
<p><a href="https://reactnavigation.org/docs/getting-started"></a></p>
<pre><code class="language-jsx">import { StatusBar } from &#39;expo-status-bar&#39;;
import { NavigationContainer } from &#39;@react-navigation/native&#39;;

export default function App() {
     return (
            &lt;&gt;
//상태표시줄은 감쌀 필요가 없는데 상태 표시줄의 스타일링만 조정하는 유틸리티 컴포넌트 이기 때문이다.
                &lt;StautusBar /&gt;
                &lt;NavigationContainer&gt;
                    &lt;MainScreen&gt;
                &lt;/NavigationContainer&gt;
            &lt;/&gt;

    )
}
</code></pre>
<p>이렇게 준비가 끝났다면 다양한 내비게이션 중에 필요한 기능을 골라 터미널로 설치 후 추가 패키지를 실행해 주어야한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]230208]]></title>
            <link>https://velog.io/@honey_bee/TIL230208</link>
            <guid>https://velog.io/@honey_bee/TIL230208</guid>
            <pubDate>Wed, 08 Feb 2023 21:00:41 GMT</pubDate>
            <description><![CDATA[<h1 id="🤓-what-i-learned-today"><strong>🤓 What I Learned Today</strong></h1>
<br>
세로방향으로 맞춰 화면을 구성하고 만들었는데 생각해보니 웹과 다르게 앱은 가로 방향으로도 많이 보기도 한다는걸 생각하지 못 했다. 

<p>그러면 기기크기에 맞춰 그냥 demensions 를 사용해서 동적화면을 구성하면 되겠다라고 생각해서 생각없이 화면만 바꿨는데 문제가 생기고 말았다..</p>
<p>안드로이드는 괜찮은데 ios 화면에서 가로 방향으로 돌리면 키보드가 화면을 다 가려버리는 것 이었다.</p>
<br>

<p>링크로 따로 정리해둔 개념 ➡️ <a href="https://velog.io/@honey_bee/React-Native%EA%B0%80%EB%A1%9C%ED%81%AC%EA%B8%B0%EC%A1%B0%EC%A0%95">가로크기로 방향전환하기</a></p>
<br>
<br>


<hr>
<h1 id="-🚀-challenges-experienced-">** 🚀 Challenges Experienced **</h1>
<br>
<br>



<p><strong>ios에서의 문제</strong></p>
<p>세로방향에서는 잘 나오던 키보드가 가로방향으로 바꾸면 화면을 가려 앱을 사용할 수 없게 되었다.🥲</p>
<p>세로방향이고</p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/6003fe54-122e-4b54-adf8-2422b825e1c7/image.png" alt=""></p>
<br>
<br>

<p>가로방향으로 바꾸면 내 화면 어디갔담...?
<br>
<br></p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/0410621a-de1b-4d32-ad82-e58205bf86ed/image.png" alt=""></p>
<br>
<br>

<hr>
<h1 id="-🤔-code-snippets-">** 🤔 Code Snippets **</h1>
<br>
<br>


<p>해결 방법은 KeyboardAvoidingView, ScrollView 사용하기...!</p>
<pre><code class="language-jsx">import { KeyboardAvoidingView, ScrollView } from &quot;react-native&quot;;
//keyboardAvoidingView는 다른 콘텐츠 또는 입력란을 포함하는
//다른 콘텐츠를 감싸는데 사용할 수 있는 컴포넌트

//키보드가 열릴때마다 입력 요소 및 다른 요소가 화면 위로 올라가 키보드가 열려도 엑세스할 수 있다.

//ScrollView 를 사용하여 스크롤링을 추가할 수 있다.
//공간이 부족할 경우 스크롤링이 되는 사용자 인터페이스가 명확히 정의되어 있다.

function Start()  {

    const { width, height } = useWindowDimensions();

    const marginTopDistance = height &lt; 380 ? 30 : 100;

    return (
        ...생략
    &lt;ScrollView style={styles.screen}&gt;
        &lt;KeyboardAvoidingView style={styles.screen} behavior=&quot;position&quot;&gt;
            &lt;View style={[styles.rootCantainer, {marginTop: marginTopDistance}]&gt;
        &lt;/KeyboardAvoidingView&gt;    
    &lt;/ScrollView&gt;
)

}

const styles = StyleSheet.create({
    screen: {
        flex:1,
    }
})</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React Native]가로크기조정]]></title>
            <link>https://velog.io/@honey_bee/React-Native%EA%B0%80%EB%A1%9C%ED%81%AC%EA%B8%B0%EC%A1%B0%EC%A0%95</link>
            <guid>https://velog.io/@honey_bee/React-Native%EA%B0%80%EB%A1%9C%ED%81%AC%EA%B8%B0%EC%A1%B0%EC%A0%95</guid>
            <pubDate>Wed, 08 Feb 2023 20:59:40 GMT</pubDate>
            <description><![CDATA[<p>app.json 에서 기본으로 세로방향으로 고정되어 있는데 이부분을 수정해줘야했다.</p>
<pre><code class="language-jsx">&quot;orientation&quot; : &quot;portrait&quot;

-&gt;

&quot;orientation&quot; : &quot;defalut&quot;</code></pre>
<p>방향을 수정하면 앱이 깨지는 현상이 발생한다. 이럴경우 수정해줘야할 부분이 많다.</p>
<p>사용중 방향 전환이 필요할 경우…기기의 방향 변경에 맞게 화면의 방향이 조정되는 반응형 코드를 작성하는 것이 좋은데..</p>
<pre><code class="language-jsx">import { useWindowDimensions } from &quot;react-native&quot;;

function Start()  {
    //이 훅을 호출하기만 하면 객체를 반환할 수 있고 객체 구조 분해를 통해 기기의 너비와 높이를 얻을 수 있다.
    //예를 들면 기기가 회전할 경우의 변경 사항이 발생할 때마다 이 컴포넌트 함수가 재실행되고 폭과 길이가 업데이트 된다.
    //컴포넌트 내의 상단 여백의 값을 동적으로 구할 수 있고 이 동적 높이 또는 너비를 JSX코드에서 사용할 수 있는 것

    const { width, height } = useWindowDimensions();
    //이미지크기 조정

    let imageSize = 300;

    if(width &lt; 380) {
        imageSize = 150;
    }

    if(height &lt; 400) {
        imagesSize = 80;
    }

    const imageStyle = {
        width: imageSize,
        height: imageSize,
        borderRadius: imageSize /2 ,
    }
    const marginTopDistance = height &lt; 380 ? 30 : 100;

    return (
        ...생략
        &lt;View style={[styles.rootCantainer, {marginTop: marginTopDistance}]&gt;
    )

}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React Native]Dimensions API]]></title>
            <link>https://velog.io/@honey_bee/React-NativeDimensions-API</link>
            <guid>https://velog.io/@honey_bee/React-NativeDimensions-API</guid>
            <pubDate>Wed, 08 Feb 2023 20:57:38 GMT</pubDate>
            <description><![CDATA[<p><strong>Dimensions ???</strong></p>
<p>JSX코드에서 사용하는 컴포넌트는 아니고 JavaScript 객체라서 styles를 포함한 JavaScript 코드 어디에서나 정보 추출을 위해 사용할 수 있다.</p>
<p>사용법은 react-native 로 부터 Dimensions 을 불러온다.</p>
<hr>
<p><strong>무슨 정보를 추출할 수 있을까?</strong>🤔
기기의 너비와 높이를 추출할 수 있다.</p>
<p>(⚠️ 주의 : 기기 화면 방향에 관한 정보를 얻을 수 없으며 기기 화면의 너비와 높이에 관한 정보만 제공)</p>
<pre><code class="language-jsx">import { Dimensions } from &quot;react-native&quot;;

//get 메서드가 문자열 타입 인수로서 화면이나 윈도우의 치수를 지닌다. 
const deviceWidth = Dimensions.get(&#39;&#39;)</code></pre>
<p>( ⚠️주의 : ios 에서는 두 개념이 다르지 않은데 안드로이드의 경우 화면은 상태 표시줄을 포함한 너비와 높이고 윈도우는 상태 표시줄을 제외한 너비와 높이라서 UI가 실제로 표시되는 화면이다. )</p>
<p>fontScale 을 사용하여 사용자가 원하는 앱의 스케일을 파악하고 해당 스케일에 글꼴 크기를 곱하면 된다. </p>
<p>ex.</p>
<pre><code class="language-jsx">import { View, Text, StyleSheet, Dimensions } from &quot;react-native&quot;;
.
.

생략
.
.
//get 메서드가 문자열 타입 인수로서 화면이나 윈도우의 치수를 지닌다. 
const deviceWidth = Dimensions.get(&#39;window&#39;).width;

const styles = StyleSheet.create({
  container: {
    borderWidth: 4,
    borderColor: Colors.primary300, 
    //deviceWidth가 450px 보다 크면 24를 설정 즉, 작은 화면의 안쪽 여백은 12픽셀이고 큰 화면에는 24픽셀이라는 뜻
    padding: deviceWidth &lt; 380 ? 12 : 24,
    margin: deviceWidth &lt; 380 ? 12 : 24,
    borderRadius: 8,
    alignItems: &quot;center&quot;,
    justifyContent: &quot;center&quot;,
  },
  numberText: {
    color: Colors.primary300,
    fontSize: deviceWidth &lt; 380 ? 28 : 36,
  },
    imageContainer: {
        //380픽셀보다 작다면 이미지의 폭을 150픽셀로 설정하고 큰 화면일 경우 300픽셀로 설정
        width: deviceWidth &lt; 380 ? 150 : 300,
        height:  deviceWidth &lt; 380 ? 150 : 300,
        borderRadius:  deviceWidth &lt; 380 ? 75 : 150,
    },
    image: {
        width:~
        height:~
    },
});</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React Native-Expo] ScrollView vs FlatList]]></title>
            <link>https://velog.io/@honey_bee/React-Native-Expo-ScrollView-vs-FlatList</link>
            <guid>https://velog.io/@honey_bee/React-Native-Expo-ScrollView-vs-FlatList</guid>
            <pubDate>Tue, 07 Feb 2023 20:26:24 GMT</pubDate>
            <description><![CDATA[<p><strong>ScrollView</strong></p>
<p>콘텐츠에 스크롤을 추가할때 유용하다.</p>
<p>예를 들어 기사가 너무 길어 화면에 다 안들어가거나 사용자가 어떤 장치를 이용할 지 모르는 상태에서 기사를 스크롤 할 수 있도록 설정해야 하는 상황에서 사용</p>
<p>전체 UI가 렌더링될 때마다 안에 있는 항목을 전부 렌더링 한다. 즉 모든 자식 항목을 렌더링한다.  성능에 문제가 생김 앱이 느려짐 끝이 정해진 분량이 제한된  콘텐츠에서만 사용 권장</p>
<pre><code class="language-jsx">import { useState } from &quot;react&quot;;
import {
  StyleSheet,
  Text,
  View,
  Button,
  TextInput,
  ScrollView,
  FlatList
} from &quot;react-native&quot;;

export default function App() {
  const [enteredGoalText, setEnteredGoalText] = useState(&quot;&quot;);
  const [courseGoals, setCourseGoals] = useState([]);

  function goalInputHandler(enteredText) {
    setEnteredGoalText(enteredText);
  }

  function addGoalHandler() {
    setCourseGoals((currentCourseGoals) =&gt; [
      ...currentCourseGoals,
      enteredGoalText,
    ]);
  }

  return (
    &lt;View style={styles.appContainer}&gt;
      &lt;View style={styles.inputContainer}&gt;
        &lt;TextInput
          style={styles.textInput}
          placeholder=&quot;Your course goal!&quot;
          onChangeText={goalInputHandler}
        /&gt;
        &lt;Button title=&quot;Add Goal&quot; onPress={addGoalHandler} /&gt;
      &lt;/View&gt;
      &lt;View style={styles.goalsContainer}&gt;
        &lt;ScrollView alwaysBounceVertical={false}&gt;
          {courseGoals.map((goal) =&gt; (
            &lt;View style={styles.goalItem} key={goal}&gt;
              &lt;Text style={styles.goalText}&gt;{goal}&lt;/Text&gt;
            &lt;/View&gt;
          ))}
        &lt;/ScrollView&gt;
      &lt;/View&gt;
    &lt;/View&gt;
  );
}

</code></pre>
<hr>
<p><strong>FlatList</strong></p>
<p>화면에 보이는 부분만 렌더링하고 화면 밖의 항목은 사용자가 스크롤해야 로딩 및 렌더링 된다.</p>
<p>내부적으로 항목이 보이기 전에 로딩과 렌더링을 시작하도록 작은 임계값은 가지는데 사용자가 목록을 스크롤하면서 항목에 가까워질 때만 해당 항목을 렌더링한다. 필요할 때 데이터를 로딩하는 최적화 작업을 제외하면 내부적으로 구현 방식은 거의 유사</p>
<p>위의 코드와 다른 점은 ScrollView 를 FlatList로 대치하였고 데이터를 수동으로 매핑하는 커스텀 매핑 코드를 삭제하고 해당 작업을 FlatList 로 전달해서 필요한 사항만 렌더링하는 방식으로 목록을 효율적으로 렌더링 작업 해준다.</p>
<pre><code class="language-jsx">import { useState } from &quot;react&quot;;
import {
  StyleSheet,
  Text,
  View,
  Button,
  TextInput,
  ScrollView,
  FlatList,
} from &quot;react-native&quot;;

export default function App() {
  const [enteredGoalText, setEnteredGoalText] = useState(&quot;&quot;);
  const [courseGoals, setCourseGoals] = useState([]);

  function goalInputHandler(enteredText) {
    setEnteredGoalText(enteredText);
  }

  function addGoalHandler() {
    setCourseGoals((currentCourseGoals) =&gt; [
      ...currentCourseGoals,
      enteredGoalText,
    ]);
  }

  return (
    &lt;View style={styles.appContainer}&gt;
      &lt;View style={styles.inputContainer}&gt;
        &lt;TextInput
          style={styles.textInput}
          placeholder=&quot;Your course goal!&quot;
          onChangeText={goalInputHandler}
        /&gt;
        &lt;Button title=&quot;Add Goal&quot; onPress={addGoalHandler} /&gt;
      &lt;/View&gt;
      &lt;View style={styles.goalsContainer}&gt;
        &lt;FlatList
          //필수 프로퍼티 data  : 목록에서 출력할 데이터를 지정하는 역할로 현재 코드에서는 courseGoals 으로 목록으로 출력할 데이터니까 데이터에 값으로 전달
          //필수 프로퍼티 render Item : 개별 데이터 항목을 렌더링하는 방법을 FlatList에 지시하는 함수를 값으로 갖는 프로퍼티 함수는 자동으로 개별항목을 매개변수로 받는다.
          //(itemData)로 정하는 이유는 값뿐만 아니라 메타데이터까지 포함하는 객체니까
          //temData.index는 index 프로퍼티 접근 권한도 제공ㅡ렌더링 되는 다른 항목의 인덱스 포함
          //중괄호안에 주어진 항목에 대해 렌더링할 JSX코드로 반환

          data={courseGoals}
          renderItem={(itemData) =&gt; {
            itemData.index
            return (
              &lt;View style={styles.goalItem} key={goal}&gt;
                {/* 여기서 중요한부분 {itemData.item} 으로 렌더링되는 각 목록 항목에 대해 실제 데이터 항목을 하나씩 가짐,여기 있는 다양한 데이터 항복에 itemData.item으로 접근*/}
                &lt;Text style={styles.goalText}&gt;{itemData.item}&lt;/Text&gt;
              &lt;/View&gt;
            );
          }}
          alwaysBounceVertical={false}
        /&gt;
      &lt;/View&gt;
    &lt;/View&gt;
  );
}

</code></pre>
<p>여기서 ..key 값 빠졌는데 목록항목에 키를 추가하는 주요 방법은 두 가지가 있다.</p>
<p>첫번째,</p>
<p>데이터의 값을 여기있는 문자열 같은 원시 값에서 key 프로퍼티를 포함하는 객체로 변경</p>
<pre><code class="language-jsx">import { useState } from &quot;react&quot;;
import {
  StyleSheet,
  Text,
  View,
  Button,
  TextInput,
  ScrollView,
  FlatList,
} from &quot;react-native&quot;;

export default function App() {
  const [enteredGoalText, setEnteredGoalText] = useState(&quot;&quot;);
  const [courseGoals, setCourseGoals] = useState([]);

  function goalInputHandler(enteredText) {
    setEnteredGoalText(enteredText);
  }

  function addGoalHandler() {
    setCourseGoals((currentCourseGoals) =&gt; [
      ...currentCourseGoals,
      // 여기에 실제 목표 테스트를 포함하는 text프로퍼티를 넣어주고 unique key를 넣어준다.
      //데이터 배열의 데이커가 객체 목록일 때 더 잘 작동함
      {text:enteredGoalText, key: Math.random().toString()},
    ]);
  }

  return (
    &lt;View style={styles.appContainer}&gt;
      &lt;View style={styles.inputContainer}&gt;
        &lt;TextInput
          style={styles.textInput}
          placeholder=&quot;Your course goal!&quot;
          onChangeText={goalInputHandler}
        /&gt;
        &lt;Button title=&quot;Add Goal&quot; onPress={addGoalHandler} /&gt;
      &lt;/View&gt;
      &lt;View style={styles.goalsContainer}&gt;
        &lt;FlatList
          //필수 프로퍼티 data  : 목록에서 출력할 데이터를 지정하는 역할로 현재 코드에서는 courseGoals 으로 목록으로 출력할 데이터니까 데이터에 값으로 전달
          //필수 프로퍼티 render Item : 개별 데이터 항목을 렌더링하는 방법을 FlatList에 지시하는 함수를 값으로 갖는 프로퍼티 함수는 자동으로 개별항목을 매개변수로 받는다.
          //(itemData)로 정하는 이유는 값뿐만 아니라 메타데이터까지 포함하는 객체니까
          //itemData.index는 index 프로퍼티 접근 권한도 제공ㅡ렌더링 되는 다른 항목의 인덱스 포함
          //중괄호안에 주어진 항목에 대해 렌더링할 JSX코드로 반환

          data={courseGoals}
          renderItem={(itemData) =&gt; {
            itemData.index;
            return (
              &lt;View style={styles.goalItem}&gt;
                {/* 여기서 중요한부분 {itemData.item} 으로 렌더링되는 각 목록 항목에 대해 실제 데이터 항목을 하나씩 가짐,여기 있는 다양한 데이터 항복에 itemData.item으로 접근*/}
                &lt;Text style={styles.goalText}&gt;{itemData.item.text}&lt;/Text&gt;
              &lt;/View&gt;
            );
          }}
          alwaysBounceVertical={false}
        /&gt;
      &lt;/View&gt;
    &lt;/View&gt;
  );
}

</code></pre>
<p>두번째 API에서 데이터를 가져와서 변형할 수 없는 상황에서 입력 데이터에 key프로퍼티 설정</p>
<pre><code class="language-jsx">import { useState } from &quot;react&quot;;
import {
  StyleSheet,
  Text,
  View,
  Button,
  TextInput,
  ScrollView,
  FlatList,
} from &quot;react-native&quot;;

export default function App() {
  const [enteredGoalText, setEnteredGoalText] = useState(&quot;&quot;);
  const [courseGoals, setCourseGoals] = useState([]);

  function goalInputHandler(enteredText) {
    setEnteredGoalText(enteredText);
  }

  function addGoalHandler() {
    setCourseGoals((currentCourseGoals) =&gt; [
      ...currentCourseGoals,
      //id : 고유한 id 를 만들고(하지만 잘 못된 이름 일 수도 있다. 여기 목록은 id 프로퍼티가 아닌 key프로퍼티를 찾기 때문!~)
      { text: enteredGoalText, id: Math.random().toString() },
    ]);
  }

  return (
    &lt;View style={styles.appContainer}&gt;
      &lt;View style={styles.inputContainer}&gt;
        &lt;TextInput
          style={styles.textInput}
          placeholder=&quot;Your course goal!&quot;
          onChangeText={goalInputHandler}
        /&gt;
        &lt;Button title=&quot;Add Goal&quot; onPress={addGoalHandler} /&gt;
      &lt;/View&gt;
      &lt;View style={styles.goalsContainer}&gt;
        &lt;FlatList
          //렌더링되는 목록 항목마다 이 함수를 호출
          data={courseGoals}
          renderItem={(itemData) =&gt; {
            itemData.index;
            return (
              &lt;View style={styles.goalItem}&gt;
                {/* 여기서 중요한부분 {itemData.item} 으로 렌더링되는 각 목록 항목에 대해 실제 데이터 항목을 하나씩 가짐,여기 있는 다양한 데이터 항복에 itemData.item으로 접근*/}
                &lt;Text style={styles.goalText}&gt;{itemData.item.text}&lt;/Text&gt;
              &lt;/View&gt;
            );
          }}
          //keyExtractor프로퍼티는 모든 항목에서 키를 가져오려고 호출하는 함수로 함수를 값으로 취하는데
          //이 함수가 자동으로 수신하는 두 매개변수의 값 item 과 index는 FlatList가 함수를 호출할때 제공하는 값
          //따라서 여기에서 키를 반환
          keyExtractor={(item, index) =&gt; {
            return item.id;
          }}
          alwaysBounceVertical={false}
        /&gt;
      &lt;/View&gt;
    &lt;/View&gt;
  );
}

</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React Native]스타일링]]></title>
            <link>https://velog.io/@honey_bee/React-Native%EC%8A%A4%ED%83%80%EC%9D%BC%EB%A7%81</link>
            <guid>https://velog.io/@honey_bee/React-Native%EC%8A%A4%ED%83%80%EC%9D%BC%EB%A7%81</guid>
            <pubDate>Tue, 07 Feb 2023 20:23:04 GMT</pubDate>
            <description><![CDATA[<p>React Native 는 CSS를 지원하지 않지만 Reac Native 스타일링은 CSS의 영향을 받아 만들어졌다.
(유사한 프로퍼티의 이름과 값을 사용)
대신,인라인 스타일(Inline Style)을 추가해서 스타일 객체를 프로퍼티로 전달하거나</p>
<p>별도의 객체를 정의해서 그걸 프로퍼티로 전달한다.
스타일은 JavaScript에서 정의하지만 CSS의 프로퍼티와 기능 일부만 지원한다.</p>
<p><strong>Style property</strong></p>
<p>모든 요소에서가 아닌 일부에서만 지원하는데 예를 들면 View , Text 에서 지원된다.</p>
<pre><code class="language-jsx">import { StatusBar } from &quot;expo-status-bar&quot;;
import { StyleSheet, Text, View, Button, TextInput } from &quot;react-native&quot;;

export default function App() {
  return (
    &lt;View style={styles.appContainer}&gt;
      &lt;View style={styles.inputContainer}&gt;
        &lt;TextInput placeholder=&quot;Your Course Goal!&quot; style={styles.textInput} /&gt;
        &lt;Button title=&quot;Add Goal&quot; /&gt;
      &lt;/View&gt;
      &lt;View&gt;
        &lt;Text&gt;List of goals...&lt;/Text&gt;
      &lt;/View&gt;
    &lt;/View&gt;
  );
}

//이렇게 쓰는 이유는 StyleSheet를 통해 유효성 검증도 할 수 있고 성능향상에도 도움

const styles = StyleSheet.create({
  appContainer: {
    padding: 50,
  },
  inputContainer: {
    // borderWidth: 2,
    // borderColor: &quot;black&quot;,
    flexDirection: &quot;row&quot;,
    justifyContent: &quot;space-between&quot;,
  },
  textInput: {
    borderWidth: 1,
    borderColor: &quot;black&quot;,
    width: &quot;70%&quot;,
    marginRight: 3,
    padding: 5,
  },
});</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]230204_랜더링과 리랜더링 memo , useMemo]]></title>
            <link>https://velog.io/@honey_bee/TIL230204%EB%9E%9C%EB%8D%94%EB%A7%81%EA%B3%BC-%EB%A6%AC%EB%9E%9C%EB%8D%94%EB%A7%81-memo-useMemo</link>
            <guid>https://velog.io/@honey_bee/TIL230204%EB%9E%9C%EB%8D%94%EB%A7%81%EA%B3%BC-%EB%A6%AC%EB%9E%9C%EB%8D%94%EB%A7%81-memo-useMemo</guid>
            <pubDate>Tue, 07 Feb 2023 19:10:48 GMT</pubDate>
            <description><![CDATA[<h1 id="🤓-what-i-learned-today"><strong>🤓 What I Learned Today</strong></h1>
<h4 id="용어설명">용어설명</h4>
<p><code>랜더링</code> : 컴포넌트가 현재 props와 state의 상태에 기초해 UI를 어떻게 구성할지 컴포넌트에게 작업을 요청하는 것을 의미</p>
<p><code>리랜더링</code> :React가 데이터 변화에 따라서 화면을 다시 그리는 현상 element Type / state 혹은 props 등이 변하는 것을 관찰하고 있다가 변하면 그때 맞춰서 다시 그려주는 것</p>
<h4 id="리액트가-dom에-업데이트하는-과정">리액트가 DOM에 업데이트하는 과정</h4>
<ol>
<li>render 단계: React.createElement로 생성</li>
<li>reconciliation 단계: 이전 elements 와 새로 생성된 elements를 비교</li>
<li>commit 단계:DOM update(필요에 따라)</li>
</ol>
<p><strong>리랜더링 발생 조건</strong></p>
<ul>
<li>부모 컴포넌트가 랜더링 되었을때</li>
<li>props가 변경되었을때</li>
<li>state가 변경되었을때</li>
<li>forceUpdate(강제로 리랜더링 시킬때)→사용하지 않는 것을 더 권장한다.</li>
</ul>
<p><strong>불필요한 리랜더링 피하는 방법</strong></p>
<p>→왜? 사이트의 효율성을 위해서 필요한 작업으로 useMemo 와 useCallback 은 미리 값을 기억하여 값의 변화가 없을 경우에는 리랜더링 되지 않도록 막아 최적화를 도와준다.</p>
<p><br><br></p>
<h1 id="-🤔-code-snippets-">** 🤔 Code Snippets **</h1>
<pre><code class="language-jsx">import React, { useState, memo } from &quot;react&quot;;
import { useDispatch, useSelector } from &quot;react-redux&quot;;

//재렌더링 막는 memo, useMemo

//자식 컴포넌트 재렌더링 막기
// const Child = () =&gt; {
//  console.log(&quot;재렌더링됨&quot;)
//   return &lt;&gt;자식&lt;/&gt;;
// };
// 2.꼭 필요할 때만 재렌더링해주는 memo 사용 그렇지만 코드를 다르게 작성해야한다.
let Child = memo(function () {
  console.log(&quot;재렌더링됨&quot;);
  return &lt;&gt;자식&lt;/&gt;;
});
//memo의 원리: props가 변할때만 재렌더링 해주며 memo로 재렌더링 오래걸리는 컴포넌트 감싸놓으면 좋음
//렌더링 되기전에 기본 props == 신규 props 와 계속 비교

//버튼을 누르면 재렌더링됨
const Cart = () =&gt; {
  const state = useSelector((state) =&gt; state);
  const dispatch = useDispatch();
  const [count, setCount] = useState(0);

  return (
    &lt;&gt;
      {/* 자식 컴포넌트도 재렌더링됨 */}
      {/* 1.그러면 꼭 필요할 때만 재렌더링해주고 싶으면? */}
      &lt;Child count={count}&gt;&lt;/Child&gt;

      &lt;button
        onClick={() =&gt; {
          setCount(count + 1);
        }}
      /&gt;
    &lt;/&gt;
  );
};

export default Cart;</code></pre>
<p><br><br></p>
<h1 id="-🚀-challenges-experienced-">** 🚀 Challenges Experienced **</h1>
<p><strong>useEffect 와 useMemo의 실행 시점의 차이</strong></p>
<p><code>useEffect</code> : return 문에 끝나고 실행
<code>useMemo</code> : 렌더링 될 때 같이 실행</p>
<pre><code class="language-jsx">

const 함수 = () =&gt; {
  return 반복문10억번 돌린결과 
}

const Cart = () =&gt; {
//컴포넌트 렌더링시 1회만 실행해줌
  let result =  useMemo(()=&gt;{return 함수()},)

  //state가 변화 할때만 코드 실행
  // let result =  useMeno(()=&gt;{return 함수()},[state])

  const state = useSelector((state) =&gt; state);
  const dispatch = useDispatch();

  return &lt;&gt;&lt;/&gt;;
};

export default Cart;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[WIL+프로젝트 회고]230125 ~ 230201]]></title>
            <link>https://velog.io/@honey_bee/WIL%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0230125-230201</link>
            <guid>https://velog.io/@honey_bee/WIL%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0230125-230201</guid>
            <pubDate>Wed, 01 Feb 2023 20:32:05 GMT</pubDate>
            <description><![CDATA[<p>프로젝트 기간: 2023.01.25 ~ 2023.02.01</p>
<h3 id="프로젝트를-시작하면서">프로젝트를 시작하면서</h3>
<pre><code>👤 프론트엔드(2명): Bootstrap, React, axios 

🩻 백엔드(3명): typeORM, Nest JS, socket.io, swagger, SSL, http2 AWS Service (RDS, EC2, S3, FrontCloud, Elastic Cache, Redis, )

🛠️ 도구: Git, excalidraw, drawSQL, Notion, Pigma,

🔊 배포 : vercel, AWS EC2, AWS S3, pm2</code></pre><p>기본개념 주차를 끝나고 미니프로젝트를 거쳐 본격적으로 실전프로젝트 들어가기 전에 기존에 있는 사이트를 클론코딩하는 프로젝트를  했다. 나 포함 프론트엔드 2명 백엔드 3명으로 구성되어 프로젝트를 시작하였다.</p>
<p>본격적으로 실전프로젝트 시작 전에 워밍업한다고 생각하고 시작했는데 생각보다 구현할 부분도 많고 공부해야할   부분도 많고 백엔드와 소통도 중요했다.</p>
<hr>
<h3 id="주제-선정-및-기획">주제 선정 및 기획</h3>
<p>*<em>🤔 무엇을 할까? *</em></p>
<p><strong>인스타그램 클론 코딩</strong></p>
<p>기본 기능에 소셜로그인,DM,파일업로드의 다양한 기능이 들어가 있고 필요한 기술 내용에 대한 정보가 다양하여 실제 서비스의 디자인과 작동 방식을 구현하는데 있어 수월할 것으로 보여 해당 사이트를 클론 코딩 하기로 했다.</p>
<p>먼저 1안,2안으로 나눠 필수로 구현해야하는 기능과 추가적으로 구현하고 싶은 기능을 중요도 순서대로 나눠 구현을 하기로 했다.</p>
<p><br><br></p>
<p>🎨 <strong>와이어프레임</strong>
<img src="https://velog.velcdn.com/images/honey_bee/post/c9918ffd-9ffb-4b02-967d-393660c8aef4/image.png" alt=""></p>
<p>(<strong>⭐️ : 1안)</strong></p>
<ol>
<li><strong>회원가입⭐️ : 쉽게 접근이 가능하고 로그인과 회원 가입이 쉽도록 구현 목표</strong>
1-1. 로컬로그인
1-2. 소셜로그인 (카카오 / 구글 / 애플)</li>
<li><strong>전체 피드 페이지⭐️</strong>
2-1. 좋아요 COUNT
2-2. 댓글 일부 공개
2-3. 무한 스크롤</li>
<li><strong>상세 피드 조회 및 쓰기⭐️</strong>
3-1. 댓글 (보기 쓰기)
3-2. 좋아요 3-2-1. 좋아요 알람
3-3. 팔로우
3-4. 수정 및 삭제
3-5. 피드 작성</li>
<li><strong>DM</strong>
4-1. 실시간 DM
4-2. DM 알람</li>
<li><strong>프로필</strong>
5-1. 프로필 수정</li>
<li><strong>팔로잉 / 팔로워 조회 및 편집</strong></li>
</ol>
<hr>
<h3 id="프로젝트-진행-완료피드백">프로젝트 진행 완료(피드백)</h3>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/a1cc2bf1-a77a-471f-9d70-b2e2aac1f485/image.png" alt=""></p>
<p><strong>🤓 완성된 기능구현</strong>
<img src="https://velog.velcdn.com/images/honey_bee/post/416689d5-9b18-478e-a3ae-f7e01aab4896/image.png" alt=""></p>
<ol>
<li><strong>회원가입</strong>
1-1. 로컬로그인
1-2. 소셜로그인 (카카오 / 구글 )</li>
<li><strong>전체 피드 페이지</strong>
2-1. 좋아요 COUNT
2-2. 댓글 일부 공개</li>
<li><strong>상세 나의</strong></li>
<li><strong>DM</strong>
4-1. 실시간 DM </li>
</ol>
<p>기술적 기능구현은 완료했으나 다른 컴포넌트랑 잘 작동이 되는 지 확인해야하는 기능도 있었고 유료로 구매하고 사용해야하는 기술도 있었그며 기능은 어렵지 않으나 더 중요한 기능을 구현해봐야 하는 것 때문에 몇가지 기능은 삭제하고 완성.</p>
<h3 id="💥-나의-트러블-슈팅ppt-발표자료로-대체">💥 나의 트러블 슈팅(PPT 발표자료로 대체)</h3>
<p>요약🍀</p>
<p><strong>에러발생이유 &gt;</strong></p>
<p>react modal 라이브러리의 기본 사용 코드는 useState 로 지역변수여서 컴포넌트를 나눠 컨트롤 하지 못하여서 모달 오픈 버튼을 사이드 바에서 사용하고 메인에서 모달창을 확인해주고 싶을 때 에러가 발생</p>
<p><strong>해결 &gt;</strong></p>
<p>모달이 열렸다 닫혔다하는 다른 상태 값(true /false) 를 전역으로 변경</p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/5e0ea921-bcb6-434f-98c5-3cddd8e516ce/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/0664e54e-ec8e-4576-9207-1a2ba6235d10/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/b3f18006-7b22-456b-9008-1871b7532a1b/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/b5844468-c382-4e54-84e9-30f7a36706cc/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]230126_비동기(async await )]]></title>
            <link>https://velog.io/@honey_bee/TIL230126</link>
            <guid>https://velog.io/@honey_bee/TIL230126</guid>
            <pubDate>Thu, 26 Jan 2023 16:41:39 GMT</pubDate>
            <description><![CDATA[<h1 id="🤓-what-i-learned-today"><strong>🤓 What I Learned Today</strong></h1>
<p>오늘은 여러가지로 막히는 하루라 그냥 간단하게 개념정리만..!</p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/7cfa6ed3-2ab0-43a3-b5fa-b4fbd88cab1a/image.png" alt=""></p>
<p>1.async</p>
<p>예를 들면 사용자의 데이터를 백엔드에서 받아오는데 10초정도 걸리는 코드가 있다고 가정해보자</p>
<pre><code class="language-jsx">function fetchUser( ) {
//do network request in 10 secs...

    return &#39;mememe&#39;    
}
const user = fetchUer();
console.log(user)</code></pre>
<p>자바스크립트엔진은 동기적으로 수행하기 때문에 .. 오래 걸리는 코드를 비동기적인 처리를 전혀 하지 않으면 코드를 순차적으로 보여주는 동안 사용자는 10초정도 빈화면을 보고 있기 때문에 문제가 된다.</p>
<p>그러면 어떻게 비동기적으로 만들까?</p>
<p>먼저, promise 를 사용하는 방법이 있다.</p>
<pre><code class="language-jsx">function fetchUser( ) {
//do network request in 10 secs...
return new Promise((resolve,reject)=&gt;{
    resolve(&#39;ellie&#39;);
});
}
const user = fetchUer();
user.then(console.log)
console.log(user)</code></pre>
<p>좀더 간편하게 만들기..</p>
<pre><code class="language-jsx">async function fetchUser( ) {
//do network request in 10 secs...

    return &#39;mememe&#39;    
}
const user = fetchUer();
user.then(console.log)
console.log(user)</code></pre>
<p>async 라는 키워드를 함수앞에 쓰면 코드블록이 자동으로 promise로 바뀐다.</p>
<p>2.await</p>
<pre><code class="language-jsx">function delay(ms) {
    return new Promise(resolve =&gt; setTimeout(resolve, ms))
}

async function getApple() {
    await delay(1000);
    return &#39;apple&#39;;
}

async function getApple() {
    await delay(1000);
    return &#39;banana&#39;;
}

function pickFruits() {
    return getApple().then(apple =&gt; {
        return getBanana().then(banana =&gt; `${apple}+${banana}`);
});
}

pickFruits().then(console.log);</code></pre>
<p>하지만! 이 코드의 문제점은 너무 체이닝하고 있어 콜백지옥의 문제를 일으켜 문제가 된다.</p>
<p>다시 코드를 고쳐보자…!</p>
<pre><code class="language-jsx">function delay(ms) {
    return new Promise(resolve =&gt; setTimeout(resolve, ms))
}

async function getApple() {
    await delay(1000);
    return &#39;apple&#39;;
}

async function getApple() {
    await delay(1000);
    return &#39;banana&#39;;
}

async function pickFruits() {
    try {
        const apple= await getApple();
        const banana= await getBanana();
} catch() {
    ..........
}
    return `${apple}+${banana}`;
}

pickFruits().then(console.log);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]230125_비동기 Promise]]></title>
            <link>https://velog.io/@honey_bee/TIL230125</link>
            <guid>https://velog.io/@honey_bee/TIL230125</guid>
            <pubDate>Wed, 25 Jan 2023 15:18:22 GMT</pubDate>
            <description><![CDATA[<h1 id="🤓-what-i-learned-today"><strong>🤓 What I Learned Today</strong></h1>
<p>❓.비동기적으로 실행 된다는 것이 무엇일까?</p>
<p>하나의 동작이 완료되지 않아도 다음 코드가 실행 된다는 것을 의미한다.</p>
<p>❗️비동기 특성</p>
<p>서버에 요청을 보내고 결과가 돌아오지 않아도 다음 코드를 실행 한다.</p>
<p>❓.그러면 이게 왜 필요해?</p>
<p>웹에서 서버에 데이터를 요청했을때 요청이 완료되기 전까지는 아무것도 실행되지 않는데 그 이유는 하나의 프로그램을 실행하는 데 많은 시간이 소요 되기 때문이기도 하다.</p>
<p>그렇다면 어떻게 해야 빠르게 실행해야할까? 실행 순서가 순차적이아니라 빠르게 불러올 수 있는 것 부터 가져오면 어떨까? 예를 들면 서버에서 이미지를 가져온다고 해보자..</p>
<p>이미지의 크기와 네트워크의 환경에 따라 실행이 불가한 경우가 발생할 수가 있다. 이때 비동기 처리가 필요한 것이다.</p>
<p><code>fetch</code> 함수는 리퀘스트를 보내고 <code>promise</code> 객체를 리턴하며 그 객체의 <code>then</code> 메소드로 콜백을 ⭐️등록이 된다. 콜백은 서버로부터 리스폰스 받았을 때 실행된다.</p>
<p>또한, 해당 프로미스 객체가 <code>pending</code> 상태에서 <code>fulfilled</code> 상태가 되었을때 실행할 콜백 등록할 수 있으며,</p>
<p>리스폰스가 와서 프로미스 객체가 실제로 pending 에서  fulfilled 상태가 되면 등록해둔 콜백이 실행되고 그 작업 성공 결과가 콜백의 파라미터로 넘어오게 된다.</p>
<pre><code class="language-jsx">console.log(&#39;start!);

fetch(&#39;&#39;)
    .then((response) =&gt; response.text()) // ① 작업 성공 결과
    .then((result) =&gt; { console.log(result); });//② 첫 번째 콜백이 실행되고 나면 실행 

console.log(&#39;End&#39;);</code></pre>
<p>위의 예시에서 start → end → then 메소드에 등록되어두었던 콜백이 순서대로 실행</p>
<p>fetch 함수는 promise 객체를 리턴한다.</p>
<p>여기서 promise 객체란 어떤 작업에 관한 “상태 정보”를 갖고 있는 객체이다.(자바스크립트에서 비동기를 간편하게 처리할 수 있게 도와주는 object )</p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/9e3b9319-0aa3-4e53-be33-7330038e5b0b/image.png" alt=""></p>
<p><code>Promise</code> 객체는 크게 3가지 중 하나의 상태를 가진다.</p>
<ol>
<li>작업이 진행 중임을 의미하는 <code>pending</code> 상태</li>
<li>작업이 성공적으로 완료되었음을 의미하는 <code>fulifilled</code> 상태</li>
<li>작업이 실패했음을 의미하는 <code>rejected</code> 상태</li>
</ol>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/7bae0b2f-2f61-4a0f-bce2-e37417bc5b93/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/honey_bee/post/827bc53b-ce6a-4734-94ad-e6fcf8f6e71f/image.png" alt=""></p>
<p>🤔 그렇다면 fulfilled 상태의 객체와 rejected 상태의 객체를 만들고 싶으면 어떻게 코드를 작성해야할까?</p>
<p>fulfilled 상태의 객체</p>
<pre><code class="language-jsx">const x = Promise.resolve(&#39;success);</code></pre>
<p>rejected 상채의 객체</p>
<pre><code class="language-jsx">const x = Promise.reject(new Error(&#39;fail&#39;));</code></pre>
<h1 id="-🚀-challenges-experienced-">** 🚀 Challenges Experienced **</h1>
<p>리액트를 공부하다가 중요하게 나오는 자바스크립트의 비동기에 대해 좀 더 알아보았다. 아직은 잘 와닿지 않은 개념이지만 예제를 많이 봐야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]230124_Axios (+인터셉터 , .env ,  promise.all)]]></title>
            <link>https://velog.io/@honey_bee/TIL230124Axios-%EC%9D%B8%ED%84%B0%EC%85%89%ED%84%B0-.env-promise.all</link>
            <guid>https://velog.io/@honey_bee/TIL230124Axios-%EC%9D%B8%ED%84%B0%EC%85%89%ED%84%B0-.env-promise.all</guid>
            <pubDate>Tue, 24 Jan 2023 16:34:26 GMT</pubDate>
            <description><![CDATA[<h1 id="🤓-what-i-learned-today"><strong>🤓 What I Learned Today</strong></h1>
<p>먼저, API 를 호출하려면 세 가지 방법이 있다. fetch, Ajax, Axios 가 있다.</p>
<p><strong>여기서..Axios가 뭐야?</strong></p>
<p> 브라우저, Node.js를 위한 Promise API를 활용하는 HTTP 비동기 통신 라이브러리로 백엔드와 프론트엔드가 통신을 쉽게 하기위해 Ajax와 더불어 사용된다.</p>
<p><strong>그럼 왜 다른 방법도 있는데 Axios를 더 많이 쓸까?</strong></p>
<p>비슷비슷하지만 좀 더 많은 기능을 사용할 수 있게 해주기 때문이다. 예를 들면 타임아웃 기능도 있고 baseURL 기능 등등을 제공해주기 때문이다. 또한 nodeJS에서는 node-fetch 를 써야하기 때문에 백엔드와 통신하려면 Axios를 사용하는 게 좋다!</p>
<p><strong>장점👍?</strong></p>
<p>운영 환경에 따라 브라우저의 XMLHttpRequest 객체 또는 Node.js의 http api 사용,요청과 응답 데이터의 변형,HTTP 요청을 취소할수 있고 요청과 응답을 JSON 형태로 자동 변,jquery와 비교하면, 타입스크립트도 사용이 가능하고, 요청 취소도 가능하며, 통신 기능만을 전담하므로 가볍다는 것이 장점!</p>
<p><strong>단점👎?</strong></p>
<p>ES6 버전의 자바스크립트 문법을 사용하므로, 낮은 버전의 브라우저에서는 구동하지 않을 수도 있다는 것(하지만 그것도 바벨, 웹팩 등으로 트랜스파일을 가하면 해결)</p>
<p>(참고사이트)</p>
<p><a href="https://inpa.tistory.com/entry/AXIOS-%F0%9F%93%9A-%EC%84%A4%EC%B9%98-%EC%82%AC%EC%9A%A9#Axios_%ED%8A%B9%EC%A7%95">[AXIOS] 📚 axios 설치 &amp; 특징 &amp; 문법 💯 정리</a></p>
<p><br><br></p>
<h1 id="-🤔-code-snippets-">** 🤔 Code Snippets **</h1>
<p>적용해보기🤓</p>
<pre><code class="language-jsx">import axios from &quot;axios&quot;;

const api = axios.create({
  //서버주소
  baseURl:&quot;&quot;
  //요청헤더: 보통 무슨 타입인지 써준다.
  headers:{&quot;Content-type&quot;:&quot;aplication/json&quot;}
})

// 요청 인터셉터 추가하기! 인터셉터는 해도되고 안해도 된다~!
// axios 에서 이름을 api 로 바꿔주기
//위에서 선언한 api에 인터셉터를 더해주고 싶으니 이름 바꾸기!
api.interceptors.request.use(function (config) {
  // 요청이 전달되기 전에 작업 수행
  //디버깅:콘솔로 찍어 보내고 싶은 요청을 config 로 봐주고!
console.log(&quot;request start&quot;, config)
  return config;
}, function (error) {
  // 요청 오류가 있는 작업 수행
  //디버깅:콘솔로 찍어 에러 확인
  console.log(&quot;request error&quot;,error)
  return Promise.reject(error);
});

// 응답 인터셉터 추가하기
api.interceptors.response.use(function (response) {
  // 2xx 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
  // 응답 데이터가 있는 작업 수행
  //디버깅:콘솔로 찍어 받은 데이터를 확인
  console.log(&quot;get response&quot;, response)
  return response;
}, function (error) {
  // 2xx 외의 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
  // 응답 오류가 있는 작업 수행
//디버깅: 여기서도 콘솔로 에러 확인
console.log(&quot;response error&quot;, error)
  return Promise.reject(error);
});

export default api;</code></pre>
<p>⇒</p>
<pre><code class="language-jsx">import React from &quot;react&quot;;
import { useEffect } from &quot;react&quot;;
import { movieAction } from &quot;../redux/action/MovieAction&quot;;
import { useDispatch } from &quot;react-redux&quot;;

//웹페이지가 나타나자 마자 데이터가 뿅!하고 와야할때 써야하는 훅은? useEffect ㄱ하자
const Home = () =&gt; {
  //액션을 호출하려면 dispatch가 필요!
  const dispatch = useDispatch();
  // useEffect(() =&gt; {}, []); 두 개의 아규먼트 ㄱ하자
  useEffect(() =&gt; {
    dispatch(movieAction.getMovies());
  }, []);

  return &lt;div&gt;Home&lt;/div&gt;;
};

export default Home;</code></pre>
<p>이렇게 사용!</p>
<p><br><br></p>
<h1 id="-🚀-challenges-experienced-">** 🚀 Challenges Experienced **</h1>
<p>+추가 : 환경변수</p>
<p>.env</p>
<p>다른 사람에게 보여주고 싶지 않은 key 값을 넣어주는 파일</p>
<pre><code class="language-jsx">REACT_APP_API_KEY=
//공백주의!</code></pre>
<p>⇒ 나중에 .gitignore 파일에 넣어주기</p>
<p>나중에 액션파일에 이렇게 키값을 적용해주면 된다.</p>
<pre><code class="language-jsx">import api from &quot;../api&quot;

const API_KEY=process.env.REACT_APP_API_KEY

function getMovies() {
  return (dispatch)=&gt;{
    //Axios 호출
    const popularMovieApi = await api.get(&#39;~${API_KEY}~&#39;) //.http 함수

    //fetch 버전
    // let url =&#39;&#39;
    // let response = await fetch(url)
    // let data = await response.json()
    }
}

export const movieAction = {
  getMovies,
};</code></pre>
<hr>
<p>+추가 : Promise.all([])</p>
<pre><code class="language-jsx">import api from &quot;../api&quot;

const API_KEY=process.env.REACT_APP_API_KEY
function getMovies() {
  return (dispatch)=&gt;{
    //Axios 호출
    const popularMovie1Api =  api.get(&#39;&#39;) //.http 함수
    const popularMovie2Api =  api.get(&#39;&#39;) //.http 함수
    const popularMovie3Api =  api.get(&#39;&#39;) //.http 함수

    //이런식으로 API가 여러개 있을때 데이터를 한꺼번에 보여주고 싶을때
    //(단, 데이터끼리 연관있으면 await으로 기다려야한다.)

    let [popularMovie1Api,popularMovie2Api,popularMovie3Api] = await Promise.all([
      popularMovie1Api,
      popularMovie2Api,
      popularMovie3Api,
    ])

    console.log(&quot;promise all 이후에 받는 데이터?&quot;,data)
    //fetch 버전
    // let url =&#39;&#39;
    // let response = await fetch(url)
    // let data = await response.json()
    }
}

export const movieAction = {
  getMovies,
};</code></pre>
]]></description>
        </item>
    </channel>
</rss>