<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>ohwowo_o.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Fri, 11 Oct 2024 00:25:08 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>ohwowo_o.log</title>
            <url>https://velog.velcdn.com/images/ohwowo_o/profile/71ce57e8-0fdc-4109-96c1-eade44c1f3e4/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. ohwowo_o.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/ohwowo_o" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[JS] 프로그래머스 - 두 정수 사이의 합]]></title>
            <link>https://velog.io/@ohwowo_o/JS-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%91%90-%EC%A0%95%EC%88%98-%EC%82%AC%EC%9D%B4%EC%9D%98-%ED%95%A9</link>
            <guid>https://velog.io/@ohwowo_o/JS-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%91%90-%EC%A0%95%EC%88%98-%EC%82%AC%EC%9D%B4%EC%9D%98-%ED%95%A9</guid>
            <pubDate>Fri, 11 Oct 2024 00:25:08 GMT</pubDate>
            <description><![CDATA[<h3 id="🥇문제">🥇문제</h3>
<p>두 정수 a, b가 주어졌을 때 a와 b 사이에 속한 모든 정수의 합을 리턴하는 함수, solution을 완성하세요.
예를 들어 a = 3, b = 5인 경우, 3 + 4 + 5 = 12이므로 12를 리턴합니다</p>
<p><strong>제한 조건</strong>
a와 b가 같은 경우는 둘 중 아무 수나 리턴하세요.
a와 b는 -10,000,000 이상 10,000,000 이하인 정수입니다.
a와 b의 대소관계는 정해져있지 않습니다.</p>
<h4 id="접근방식">접근방식</h4>
<p>a와 b의 대소관계를 파악하고,
작은 수부터 큰 수까지 사이 수를 구하고,
그 수를 모두 더하자.
문제의 목적자체가 어렵지 않기때문에 효율적은 코드를 짜는게 관건이 될 듯</p>
<h4 id="해결방법">해결방법</h4>
<pre><code class="language-javascript">function solution(a, b) {
    var answer = 0;
    if(a &lt; b){
        for(let i = a ; i &lt;= b; i++){
            answer += i
        }
    }else{
        for(let i = b ; i &lt;= a; i++){
            answer += i
        }
    }
    return answer;
}</code></pre>
<p>문제를 직독직해한 코드. 당연히 통과는 한다. 하지만 이 코드는 효율성, 코드 가독성, 간결성 측면에서 최적화가 부족하게 보인다. 또한, 작은수에서 이렇게 <code>+=</code> 사용해 모두 더하는 것은 문제가 없지만 수가 커질 수록 비효율적일 수 있다. 그래서 검색을 해봤다. 두 숫자 사이의 합을 한번에 계산하는 공식이 있지 않을까? 
<img src="https://velog.velcdn.com/images/ohwowo_o/post/5fba0ec9-f35b-4df2-b67c-b7188e23f416/image.png" alt="">
이 공식을 보고 a와 b를 비교해서 먼저 큰 수를 찾아야겠구나 생각했다.</p>
<h3 id="📇-출력">📇 출력</h3>
<pre><code class="language-javascript">function solution(a, b) {
    const start = Math.min(a,b)
    const end = Math.max(a,b)

    return (start + end) * (end - start + 1) /2
}</code></pre>
<p><img src="https://velog.velcdn.com/images/ohwowo_o/post/aad851e0-89c9-448d-aae7-39c11fe6e9ae/image.png" alt=""></p>
<p>근데 풀이를 하고 다른 사람 풀이를 보니</p>
<pre><code class="language-javascript">return (a+b) * (Math.abs(a-b)+1) / 2;</code></pre>
<p>Math.abs() 메서드를 생각을 못했다..!</p>
<h3 id="🗝️필요한-사전-지식">🗝️필요한 사전 지식</h3>
<p><strong>Math.min()</strong>
가장 작은 값을 찾는 메서드다. 배열에서 활용할땐 아래와 같다. 배열의 값들을 스프레드 연산자(...)로 펼쳐서 Math.min()에 전달하여 가장 작은 값을 찾을 수 있다.</p>
<pre><code class="language-javascript">const numbers = [15, 3, 8, 22, 7];
console.log(Math.min(...numbers)); // 3</code></pre>
<p><strong>Math.max(x)</strong>
가장 큰 값을 반환하는 함수다. 여러 인수를 입력받아 그중 가장 큰 숫자를 찾아줍니다. 인수를 제공하지 않으면 반환값은 -Infinity이다.</p>
<p><strong>Math.abs()</strong>
내가 기억하지 못했던 바로 Math.abs()!
Math.abs()는 주어진 숫자가 양수일 경우 그대로 반환되고, 음수일 경우에는 그 음수를 양수로 바꾸어 반환한다. 절대값을 구할 때는 다양한 상황에서 유용하다. 특히, 두 값의 차이를 구할 때 차이가 양수로 표현되어야 할 경우 아주 유용하게 쓸 수 있다.</p>
<br/>

<p>링크
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/12912?language=javascript">두 정수 사이의 합</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 프로그래머스 - 정수 제곱근 판별]]></title>
            <link>https://velog.io/@ohwowo_o/JS-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%95%EC%88%98-%EC%A0%9C%EA%B3%B1%EA%B7%BC-%ED%8C%90%EB%B3%84</link>
            <guid>https://velog.io/@ohwowo_o/JS-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%95%EC%88%98-%EC%A0%9C%EA%B3%B1%EA%B7%BC-%ED%8C%90%EB%B3%84</guid>
            <pubDate>Thu, 10 Oct 2024 05:12:59 GMT</pubDate>
            <description><![CDATA[<h3 id="🥇문제">🥇문제</h3>
<p>임의의 양의 정수 n에 대해, n이 어떤 양의 정수 x의 제곱인지 아닌지 판단하려 합니다.
n이 양의 정수 x의 제곱이라면 x+1의 제곱을 리턴하고, n이 양의 정수 x의 제곱이 아니라면 -1을 리턴하는 함수를 완성하세요.</p>
<h4 id="접근방식">접근방식</h4>
<p>n의 제곱근을 구하고,
그 제곱근이 정수인지 아닌지 확인한 후,
정수이면 (제곱근 + 1)의 제곱을 반환,
정수가 아니면 -1을 반환합니다.</p>
<h3 id="📇-출력">📇 출력</h3>
<pre><code class="language-javascript">function solution(n) {
    const sqrt = Math.sqrt(n) 
    return Number.isInteger(sqrt) ? (sqrt+1) ** 2 :  -1  
}</code></pre>
<p><img src="https://velog.velcdn.com/images/ohwowo_o/post/024ef1b9-196f-4721-961c-92bc698c4974/image.png" alt=""></p>
<br/>

<h3 id="🗝️필요한-사전-지식">🗝️필요한 사전 지식</h3>
<p><strong>Math.sqrt()</strong>
제곱근(square root)을 구하는 메서드. 주어진 숫자의 양의 제곱근을 반환하며, 이는 그 숫자를 두 번 곱한 값이 원래 숫자가 되는 수를 의미한다.</p>
<pre><code class="language-javascript">Math.sqrt(x)</code></pre>
<ol>
<li>문법</li>
</ol>
<ul>
<li>매개변수: x는 제곱근을 구할 숫자</li>
<li>반환 값: x의 양의 제곱근을 반환<ul>
<li>만약 x가 음수이면, NaN을 반환한다. (제곱근은 음수가 될 수 없기 때문입니다)</li>
<li>x가 0이나 양수라면, 그 제곱근을 반환한다.</li>
</ul>
</li>
</ul>
<ol start="2">
<li>동작 방식</li>
</ol>
<ul>
<li>예를 들어, Math.sqrt(9)는 3을 반환한다. 이는 3을 두 번 곱하면 9가 되기 때문.</li>
<li>Math.sqrt(16)은 4를 반환합니다. 4를 두 번 곱한 값이 16이므로, 제곱근은 4이다.</li>
</ul>
<ol start="3">
<li>예시<pre><code class="language-javascript">console.log(Math.sqrt(9));    // 3
console.log(Math.sqrt(16));   // 4
console.log(Math.sqrt(2));    // 약 1.4142135623730951
console.log(Math.sqrt(-1));   // NaN (음수는 제곱근을 가질 수 없음)</code></pre>
</li>
</ol>
<p><br/><br/></p>
<p><strong>Number.isInteger()</strong>
주어진 값이 정수인지 판별하는 메서드. 이 메서드는 주어진 숫자가 정수이면 true를 반환하고, 그렇지 않으면 false를 반환한다.</p>
<ol>
<li>문법<pre><code class="language-javascript">Number.isInteger(value)</code></pre>
</li>
</ol>
<ul>
<li>매개변수: value는 확인할 숫자.</li>
<li>반환 값: value가 정수이면 true, 그렇지 않으면 false를 반환.</li>
</ul>
<ol start="2">
<li>동작 방식
Number.isInteger()는 주어진 값이 정수인지 확인하기 위해 두 가지 조건을 체크한다.</li>
</ol>
<ul>
<li>자료형: 주어진 값이 숫자여야 합니다.</li>
<li>정수 여부: 숫자 값이 소수점 아래에 숫자가 없어야 합니다.</li>
</ul>
<ol start="3">
<li>예시<pre><code class="language-javascript">console.log(Number.isInteger(4));      // true
console.log(Number.isInteger(4.0));    // true (정수로 표현 가능)
console.log(Number.isInteger(4.5));    // false
console.log(Number.isInteger(-3));     // true
console.log(Number.isInteger(&quot;5&quot;));    // false (문자열)
console.log(Number.isInteger(NaN));     // false (Not-a-Number)
console.log(Number.isInteger(undefined)); // false
console.log(Number.isInteger(null));    // false</code></pre>
</li>
</ol>
<br/>

<h4 id="링크">링크</h4>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/12934">정수 제곱근 판별</a></p>
<p><br/><br/></p>
<hr>
<p><img src="https://velog.velcdn.com/images/ohwowo_o/post/1ddcaf00-c477-4886-8ae7-d6b92c8c225f/image.png" alt=""></p>
<p>까마득한 순위. 10000안에 들어가는 그날 까지 화이팅!</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[새로운 시작]]></title>
            <link>https://velog.io/@ohwowo_o/%EC%83%88%EB%A1%9C%EC%9A%B4-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@ohwowo_o/%EC%83%88%EB%A1%9C%EC%9A%B4-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Wed, 09 Oct 2024 07:38:58 GMT</pubDate>
            <description><![CDATA[<h3 id="👩🏻💻work">👩🏻‍💻Work</h3>
<hr>
<p><strong>2023-2024년, 성장 기록</strong>
오랜만에 벨로그를 정리했다. 그동안 회사 일에 바쁘다는 핑계로 commit과 개발 블로그에 소홀했지만, 그만큼 많은 것을 배우고 경험한 시기였다. 입사와 퇴사를 반복하는 동안 여러 도전과 성장을 경험했고, 그 과정을 기록해보려고 한다.</p>
<p>첫 번째 회사는 비트코인 거래소 서비스를 제공하는 곳이었다. 비록 6개월 만에 경영 악화로 서비스가 종료되었지만, 돈이 오가는 플랫폼인 만큼 보안에 중점을 둔 코딩을 경험할 수 있었다. 또한, QA팀과의 협업을 통해 테스트 과정에서 이슈를 최소화하는 방법도 배우며 개발의 품질을 높이는 노하우를 쌓았다. 
이후 AI 영상 자막 서비스 회사에서는 오픈 멤버로 참여하여 11개월 동안 기획부터 개발, 오픈, 운영까지 폭넓게 경험할 수 있었다. 다양한 기술 스택을 다루며 전반적인 서비스 개발 과정을 깊이 있게 체험할 수 있었지만, 이곳 역시 경영 악화로 인해 대표님으로부터 월급을 보장하기 어려울 것 같다는 메일을 받게 되었다. 이렇게 2023년과 2024년은 입사와 퇴사를 반복하며 많은 고민과 성장을 이루어낸 시기였다.</p>
<p>새로 입사한 회사는 로펌 도메인을 가진 대형 기업이었다. IT 기업은 아니었지만, 안정적인 경영 구조와 회사 규모, 그리고 면접에서 느낀 긍정적인 분위기 덕분에 입사를 결정했다. 면접 당시 1대 6의 상황이었음에도 불구하고 면접관 분들이 내 경험과 역량을 높이 평가해주시는 모습을 보여주셨고, 이것이 곧 회사의 문화일 것이라는 기대감이 들었다. 내가 입사를 선택하게 된 결정적인 이유였다.</p>
<p>그렇게 한달 차, 나는 본사에서 분리되어 새로 꾸려진 부서에 속하게 됐다. 그 중 개발팀은 프론트엔드 1명, 백엔드 1명, 디자이너 1명으로 구성된 신설 팀으로, HTML, CSS, PHP로 작업된 18개의 센터 사이트를 유지보수하고 마이그레이션하는 작업을 맡게 됐다. 프론트엔드 마이그레이션을 주도적으로 진행할 수 있는 기회라니! 생각만 해도 설레였다. 내 첫 업무는 html, css, php 환경에서 퍼블리싱이였다. 퍼블리싱은 감히 내 특기라고 말할 수 있어 그저 출근이 재미있고 설렜다.</p>
<p>그렇게 두달 차, 예상치 못한 회사 내부 변화가 시작됐다. A이사님이 갑작스럽게 교체되셨고, 이사님의  &#39;공감, 겸손, 성장&#39;이라는 운영철칙을 애정하고 따랐던 사원들은 이런 갑작스러운 회사의 결정과 변화를 받아드리지 못했고 한 달만에 팀 4개가 없어졌다.  마이그레이션 역시 기약이 없어졌고 있었던 디자인 팀도 없어진 마당에 우리 팀의 디자이너 TO가 채워지는건 먼 일이 되었다. 인사팀도 없어졌다. 면접에서 뵀었던 네분이 퇴사하셨다. 아직 속단하긴 이른 두달이였지만 두달 동안 진행된 업무는 오직 퍼블리싱과 디자인 업무. 그마저의 일도 없는 날이 있었다. 프론트엔드 업무의 실무 감을 잃어 버릴까 불안해 시작한 평일 알고리즘 스터디와 주말 스터디. 이렇게 자바스크립트와 멀어질 수는 없었다.</p>
<p>그렇게 세달 차, 반복되는 면담과 여전히 기약 없는 마이그레이션으로 초조함이 생겨 팀에 업무를 제안 해보기도 했지만, 당시 상황에서 추가적인 업무를 받아들이는 것이 쉽지 않았고, 제안은 받아들여지지 않았다. 그래서 나는 주어진 상황에서 내가 할 수 있는 것을 시작했다. 기술경력서도 업데이트하고 매일 알고리즘 문제를 풀었다. 이를 기록하기 위해 벨로그를 다시 시작했고, 11월부터 시작되는 사이드 프로젝트에도 참여했다.
새롭게 다시 시작이라는 게 막막하게 느껴지기도 하지만 더 발전하기 위한 새로운 시작이라고 생각한다! 다시 가보자!</p>
<br/>


<h3 id="📖study">📖Study</h3>
<hr>
<p>퍼블리셔 기간 제외 웹 개발을 하면서 곧 2년차가 되어가는데 자바스크립트에 대해 아직은 모르는 부분이 많다고 느껴진다. 자바스크립트의 늪은 정말로 방대하다. 2년차가 되기 전에 Modern Javascript Deep Dive 책 완독이 목표다. 그리고 올해가 가기전 프로그래머스 Lv.2 진입이 목표다. 화이팅</p>
<br/>


<h3 id="💡algorithm">💡Algorithm</h3>
<hr>
<p>알고리즘은 어렵다는 인식이 있어서 도전을 해보지 않았는데 처음 퍼블리셔를 도전했었던 것처럼 정말 갑자기 하고싶다는 생각이 들었다. 그래서 프로그래머스 Lv.0부터 시작해 지금은 Lv.1을 풀고있다. 아직은 너무 재미있다. 자꾸 생각이 나서 퇴근하자마자 다시 앉아 풀만큼. 언젠가는 공채 코딩테스트 문제도 재미있게 풀만큼 성장하고싶다.</p>
<br/>


<h3 id="🏋🏻♀️health">🏋🏻‍♀️Health</h3>
<hr>
<p>처음에는 회사 출근 시간을 적응하느라 저녁도 못먹고 잠에 들었었다. 그래서 체력을 늘리기 위해 한강이나 동네를 2-3바퀴 달리고 있다. 야근도 하고 공부도 하려면 체력은 필수라고 느껴진다. 집 밖보다는 안을 좋아하는 성격이지만 노래 들으면서 하는 산책은 또 좋아하는 편이라 이사오고 나서 일주일에 3번 정도는 꾸준히 하고있다. 집 주변이 뛰기 좋은 환경이라 이사 온곳도 아주 만족하고있다.</p>
<br/>


<h3 id="♾️skills">♾️Skills</h3>
<hr>
<p>이전 회사에서는 기술스택이 Next.js, React, Typescript, TailwindCSS, Zustand다. 입사 후 새로운 프로젝트(AI 자막 솔루션)에 투입되는 팀이였기 때문에 기술채택부터 세팅까지 직접 해볼 수 있는 기회가 있어 좋았다. 기술 채택을 할 때는 주니어 개발자들이였기 때문에 다른 회사들의 기술스택을 많이 참고했다. 특히 우아한 형제들 기술팀에서 찍은 영상을 참고해 우리 프로젝트에 적합한 기술들을 도입했다. 처음에는 Styled component 방식을 선호해서 가독성이 좋지 않고 클래스명을 외워서 써야 하는 tailwind 사용에 불편함이 많았지만 익숙해 지면 반응형 작업을 할때도 편리하고 LucidIcon과 결합하여 사용하니 장점이 더 많이 느껴졌다. 
2023년도에 커리어적으로 가장 도움이 많이 됐던 일은 아마 typescript와 tailwind를 배워 실무에 직접 적용해 프로젝트를 오픈한 경험이 아닐까 싶다. 9to03이라는 강도 높은 업무량을 소화해야했지만 퍼블리셔를 벗어나 웹 개발자로 완전히 진입한게 느껴졌던 1년이였다고 생각한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[내가 일하면서 궁금해진 Map의 key]]></title>
            <link>https://velog.io/@ohwowo_o/%EB%82%B4%EA%B0%80-%EC%9D%BC%ED%95%98%EB%A9%B4%EC%84%9C-%EA%B6%81%EA%B8%88%ED%95%B4%EC%A7%84-Map</link>
            <guid>https://velog.io/@ohwowo_o/%EB%82%B4%EA%B0%80-%EC%9D%BC%ED%95%98%EB%A9%B4%EC%84%9C-%EA%B6%81%EA%B8%88%ED%95%B4%EC%A7%84-Map</guid>
            <pubDate>Tue, 16 Jan 2024 03:53:50 GMT</pubDate>
            <description><![CDATA[<p>map을 사용할때 나는 key값을 꼭 index로 줬었다.
index값으로 주지말라는 경고를 반대로 생각하고!!
index로 준것이다....😢😱</p>
<p>여기서 궁금증이 생겼다</p>
<br />

<h3 id="1-index로-주면-왜-안되는가">1. index로 주면 왜 안되는가?</h3>
<p>데이터가 변하지 않는 경우에는 index를 사용해도 문제가 없다!
하지만 데이터가 추가되고 삭제되는 경우, 데이터가 변경되면서 reRendering 되고 index가 0부터 다시 mapping 되면서 사이드 이펙트가 발생합니다.</p>
<br />

<h3 id="2-데이터에-고유한-id가-없는-경우는-value값으로-대체해도-되는가">2. 데이터에 고유한 id가 없는 경우는 value값으로 대체해도 되는가?</h3>
<p>고유한 식별자라면 사용할 수 있다. 코드로 예를 들어 보자.</p>
<pre><code class="language-javascript">const extensionObjects = [
  { language: &quot;English&quot;, type: &quot;SRT&quot; },
  { language: &quot;Spanish&quot;, type: &quot;VTT&quot; },
];

{extensionObjects.map((ext, index) =&gt; (
  &lt;div key={`${ext.language}-${ext.type}`}&gt;
    {ext.language}
  &lt;/div&gt;
))}</code></pre>
<p>language와 type을 조합하여 고유한 키를 만들 수 있다면 이런식으로도 사용할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[react hook form 과 shadcn react hook form]]></title>
            <link>https://velog.io/@ohwowo_o/react-hook-form-%EA%B3%BC-shadcn-hook-form</link>
            <guid>https://velog.io/@ohwowo_o/react-hook-form-%EA%B3%BC-shadcn-hook-form</guid>
            <pubDate>Mon, 08 Jan 2024 09:36:56 GMT</pubDate>
            <description><![CDATA[<p>같은 기능이나 ui 입히기가 쉽다?
기능에 특화된 것들을 focus 등등을 설정하기 쉽다.....
폼 프로바이더</p>
<br /> 

<h2 id="react-hook-form">React Hook Form</h2>
<p>React Hook Form은 React 애플리케이션에서 폼을 쉽게 다룰 수 있도록 도와주는 라이브러리 중 하나다. React Hooks를 사용하여 폼 상태를 관리하고 폼 제출을 처리하는데에 목적이 있다고 해석할 수 있다. 주요 특징과 사용법에 대해 간단하게 정리해 보겠다.</p>
<ol>
<li><p>간편한 사용: React Hook Form은 간단하게 사용할 수 있다. useForm, useFieldArray, useWatch와 같은 커스텀 훅들을 제공하여 필요한 상태나 기능을 쉽게 사용할 수 있다.</p>
</li>
<li><p>효율적인 성능: 렌더링 성능을 최적화하기 위해 불필요한 리렌더링을 방지해준다고 한다.</p>
</li>
<li><p>최소한의 보일러플레이트 코드: 다른 폼 라이브러리들과 비교했을 때 더 적은 양의 코드로 폼을 구현할 수 있다.</p>
</li>
<li><p>리액트 훅스 사용: React Hook Form은 주로 리액트 훅스 (React Hooks)를 사용하여 폼의 상태를 관리한다. 이를 통해 함수형 컴포넌트에서도 간편하게 폼을 다룰 수 있다는 장점이 있다.</p>
</li>
</ol>
<h3 id="예시">예시</h3>
<pre><code class="language-javascript">import React from &#39;react&#39;;
import { useForm, SubmitHandler } from &#39;react-hook-form&#39;;

interface FormInputs {
  firstName: string;
  lastName: string;
}

const MyForm: React.FC = () =&gt; {
  const { register, handleSubmit } = useForm&lt;FormInputs&gt;();

  const onSubmit: SubmitHandler&lt;FormInputs&gt; = (data) =&gt; {
    console.log(data);
  };

  return (
    &lt;form onSubmit={handleSubmit(onSubmit)}&gt;
      &lt;input {...register(&#39;firstName&#39;)} /&gt;
      &lt;input {...register(&#39;lastName&#39;)} /&gt;
      &lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
    &lt;/form&gt;
  );
};
</code></pre>
<br />

<h3 id="그렇다면-shadcn의-react-hook-form은-무엇일까">그렇다면 shadcn의 react hook form은 무엇일까?</h3>
<br />

<h3 id="예시-1">예시</h3>
<pre><code class="language-javascript">const form = useForm()

&lt;FormField
  control={form.control}
  name=&quot;username&quot;
  render={({ field }) =&gt; (
    &lt;FormItem&gt;
      &lt;FormLabel&gt;Username&lt;/FormLabel&gt;
      &lt;FormControl&gt;
        &lt;Input placeholder=&quot;shadcn&quot; {...field} /&gt;
      &lt;/FormControl&gt;
      &lt;FormDescription&gt;This is your public display name.&lt;/FormDescription&gt;
      &lt;FormMessage /&gt;
    &lt;/FormItem&gt;
  )}
/&gt;</code></pre>
<p>shadcn/ui에서 쓰는 react hookt form은 조금 형태가 다르다. react hook form보다 같은 기능이나 ui 입히기가 쉽고 기능에 특화된 것들을(focus 등등)을 설정하기 쉽다고 하는데 react hook form을 작업할때 큰 불편함을 못 느꼈어서 그런지
shadcn/ui react hook form으로 바꾼 지금 크게 차이를 느끼지 못하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[일하다보니 궁금해진 몇가지 개념정리]]></title>
            <link>https://velog.io/@ohwowo_o/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B4%80%EB%A0%A8-%EB%AA%87%EA%B0%80%EC%A7%80-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@ohwowo_o/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B4%80%EB%A0%A8-%EB%AA%87%EA%B0%80%EC%A7%80-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 07 Jan 2024 14:29:26 GMT</pubDate>
            <description><![CDATA[<h3 id="메서드에-대해-정리하기-쿼리스트링-바디">메서드에 대해 정리하기( 쿼리스트링, 바디)</h3>
<p>HTTP에는 여러가지 메서드가 있다. 클라이언트가 서버에 요청을 전송할 때 사용된다.</p>
<ul>
<li>GET : 조회 <ul>
<li>주로 데이터를 요청할 때 사용되며 쿼리스트링으로 보냅니다.</li>
</ul>
</li>
<li>POST : 생성하거나 수정<ul>
<li>요청의 본문 (body)에 데이터를 담아 전송합니다.</li>
</ul>
</li>
<li>PUT : 업데이트<ul>
<li>전체 리소스를 업데이트하기 위한 데이터를 전송</li>
<li>요청의 본문 (body)에 데이터를 담아 전송합니다.</li>
</ul>
</li>
<li>PATCH: 리소스의 부분적인 업데이트</li>
<li>DELETE: 삭제</li>
</ul>
<br />

<h3 id="mutation-query에-대해-정리하기">mutation, query에 대해 정리하기</h3>
<ul>
<li><p>query</p>
<ul>
<li>목적: 데이터를 읽기 위해 사용됩니다.</li>
<li>HTTP 메서드: 주로 GET 메서드를 사용하며, 데이터를 가져올 때 사용됩니다.</li>
<li>특징:<ul>
<li>클라이언트는 필요한 데이터의 구조를 지정하여 서버로부터 해당 데이터만을 요청할 수 있습니다.</li>
<li>여러 리소스에서 필요한 정보를 한 번에 요청할 수 있습니다.</li>
<li>읽기 전용 작업에 사용됩니다.</li>
</ul>
</li>
</ul>
</li>
<li><p>Mutation:</p>
<ul>
<li>목적: 데이터를 변경하기 위해 사용됩니다.</li>
<li>HTTP 메서드: 주로 POST 메서드를 사용하며, 서버에 데이터를 생성하거나 수정할 때 사용됩니다.</li>
<li>특징:<ul>
<li>클라이언트가 서버에게 데이터를 변경하도록 요청할 때 사용됩니다.</li>
<li>서버에 의해 수행되는 작업은 주로 데이터의 생성, 수정, 삭제 등이 포함됩니다.</li>
<li>읽기와 쓰기 작업을 통합할 수 있습니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<br />

<h3 id="컴포넌트-분리를-어떤-기준으로-하면-좋은가">컴포넌트 분리를 어떤 기준으로 하면 좋은가?</h3>
<p>프로젝트를 진행하면서 여러번의 회의를 하며 모두가 함께 고민했던 주제이기도 했다. 여러명이 함께 페이지를 나눠 작업하는 프로젝트 일 수록 컴포넌트 분리에 대한 기준은 명확해야한다. 내가 생각해본 컴포넌트 분리 기준에 대해 정리해보겠다.</p>
<ol>
<li><p>기능
가장 기본적으로 &#39;컴포넌트 분리&#39;라고 하면 떠오르는 기준이 기능적 분리이다. 페이지를 제작하기 전에 페이지 디자인(피그마)을 보면 가장 먼저 하는 일이 아마도 어떤 기능들이 있는지, 몇개의 기능이 있는 페이지 인지일 만큼 기능은 그 작업의 메인요소라고 할 수 있다. 따라서 컴포넌트 역시 특정 기능 또는 역할을 담당하도록 분리하면 나중에 있을 유지보수나 수정을 할 때에도 편리하게 작업 할 수 있을 것이다. 또한, 비슷한 기능을 가진 코드를 하나의 컴포넌트로 묶어 모듈화한다면 재사용성을 높일 수 있다.</p>
</li>
<li><p>모듈화
기능에서도 잠깐 언급된 모듈화란 코드를 재사용 가능한 작은 모듈로 컴포넌트를 분리하여 재사용과 유지보수를 쉽게 만드는 것이다. 모듈 간의 의존성을 최소화하고, 각 모듈이 독립적으로 테스트 가능하도록 설계한다면 사이드 이펙트를 줄일 수 있다.</p>
</li>
<li><p>변경
동일한 기능을 하거나 동일한 이유로 변경될 가능성이 있는 코드를 동일한 컴포넌트로 묶는다. 예를 들어, 동일한 로직이 여러 부분에서 사용된다면, 해당 로직을 하나의 컴포넌트로 추출해 사용 할 수 있다.</p>
</li>
</ol>
<p>컴포넌트의 분리는 프로젝트의 특성에 따라 기준을 정해 사용할 수 있으며 주요 목표는 <strong>유지보수성, 재사용성</strong>이라는 생각이 든다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 DeepDive]]></title>
            <link>https://velog.io/@ohwowo_o/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive</link>
            <guid>https://velog.io/@ohwowo_o/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive</guid>
            <pubDate>Fri, 29 Dec 2023 00:52:14 GMT</pubDate>
            <description><![CDATA[<h3 id="09-타입-변환과-단축-평가">09. 타입 변환과 단축 평가</h3>
<br/>

<p>자바스크립트의 <strong>모든 값</strong>은 타입이 있다</p>
<ul>
<li>명시적 타입 변환 (타입 캐스팅) : 개발자가 의도적으로 값의 타입을 변환하는 것</li>
<li>암묵적 타입 변환(타입 강제 변환) : 자바스크립트 엔진에 의해 암묵적으로 타입이 자동 변환되는 것</li>
</ul>
<br/>

<p>🚩이 때 기존 원시 값이 직접 변경 되는 것은 아니다! 기존 원시 값을 사용해 다른 타입의 새로운 원시 값을 생성해 내는 것이다. 
(⭐원시값은 변경 불가능한 값이라 변경할 수 없다)</p>
<br/>

<p>암묵적 타입 변환의 경우, 다른 타입의 새로운 원시 값이 재할당 되는 개념이 아니라 새롭게 생성돼서 한번만 사용되고 버려지는 개념이다.</p>
<br/>

<p>개발자의 의도를 코드에서 예측할 수 있는 명시적 타입 변환에 비해 암묵적 타입 변환은 개발자의 의도를 예측하기 어렵다. 이런 타입 변환을 예측하지 못한다면 오류를 발생시킬 확률이 높기때문에 나와 내 코드를 볼 동료가 예측 가능한 코드를 만들어야 <strong>좋은 코드</strong>라고 할 수 있다! (때문에 타입스크립트를 선호 하는듯 하다!)</p>
<ol>
<li>Truthy / Falsy 값 판별하는 함수<pre><code class="language-javascript">//전달받은 인수가 Falsy 값이면 true, Truthy 값이면 false를 반환한다.
function isFalsy(num){
return !num; 
}
</code></pre>
</li>
</ol>
<p>//전달받은 인수가 Truthy 값이면 true, Falsy 값이면 false를 반환한다.
function isTruthy(num){
 return !!num; 
}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 Deep Dive]]></title>
            <link>https://velog.io/@ohwowo_o/%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%9D%98-%EC%97%AD%EC%82%AC</link>
            <guid>https://velog.io/@ohwowo_o/%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%9D%98-%EC%97%AD%EC%82%AC</guid>
            <pubDate>Fri, 22 Dec 2023 07:32:13 GMT</pubDate>
            <description><![CDATA[<h3 id="리액트를-선호하는-이유">리액트를 선호하는 이유</h3>
<ol>
<li><p>리액트의 상태변화는 &#39;단방향&#39; 그리고 &#39;명시적&#39;으로 이루어진다. 때문에 상태가 변화했다면, 그 상태 변화를 명시적으로 일으키는 함수만 찾으면 된다.</p>
</li>
<li><p>JSX : 자바스크립트에 HTML을 살짝 가미한 수준</p>
</li>
<li><p>비교적 낮은 러닝커브 : 1+2 조합으로 처음에 비교적 난이도가 쉽다. 하지만 성능 최적화하는 것부터는 어렵다는 점!</p>
</li>
<li><p>강력한 커뮤니티와 메타의 디팬스(defence) : 자유도가 높은 리액트로 많은 개발자들이 꿈과 희망을 펼치기 시작했고 그로 인해 정보나 이슈해결에 도움이 되는 커뮤니티가 활성화 되었다. 또한 메타(이전의 페이스북)가 적극 지원을 해주면서 꾸준히 성장 할 수 있었다.</p>
</li>
</ol>
<br />

<blockquote>
<h4 id="react의-등장"><strong>React의 등장</strong></h4>
<p>페이스북 팀은 더 나은 사용자 경험을 위해 BoltJs라는 새로운 프레임워크를 개발한다.
하지만, 돌연 삭제되고 그 이유는 공개하기에는 부족한 코드라는 판단이 아니였을까 추측된다.
그에 따라 많은 개발자들이 Functional Bolt 즉 Fbolt(함수형 boltJs)를 생각해 내는데 훗날 이것이 React가 됩니다.
모델의 데이터가 변경되면 이전 DOM을 버리고 새롭게 렌더링하자!는 아이디어가 나온 것이다. 
🎉 그렇게 <strong>React</strong> 의 역사가 <strong>시작</strong>되었다. 🎉</p>
</blockquote>
<blockquote>
<h4 id="react의-발표"><strong>React의 발표</strong></h4>
<p>JsConf US 2013 에서 공개했으나 처음에 반응은 그다지 호의적이지 않았다.
<em>&quot;자바스크립트랑 HTML을 섞다니!  It&#39;s terrible!!!😱&quot;</em>
하지만! 오픈소스 컨트리뷰터에게서 많은 아이디어를 얻기 시작하면서 빛을 보기 시작했다.
메타는 이 기회를 놓치지 않고 리액트 커뮤니티를 형성하는데 노력을 쏟기 시작한다.</p>
</blockquote>
<blockquote>
<h4 id="자리잡기-시작한-react"><strong>자리잡기 시작한 React</strong></h4>
<p>점차 추가되는 기능과 복잡해지는 요구사항으로 고민하던 야후!메일을 시작으로 넷플릭스도 긴 최초 상호작용시간, 오래걸리는 사이트 빌드 등의 이유로 어려움을 겪다가 야후!메일의 성공을 보고 react를 적용하기로 한다. 전 세계에서 두번째로 큰 IT 회사인 넷플릭스가 React를 적용하다니! 
<em>Bravo!🙌🏻</em> 
🎊 <strong>React 전성기</strong>의 시작이다! 🎊</p>
</blockquote>
<br />

<h3 id="01-리액트-개발을-위해-꼭-알아야-하는-자바스크립트-53p">01. 리액트 개발을 위해 꼭 알아야 하는 자바스크립트 (~53p)</h3>
<br />


<ol>
<li>Es6에서 새롭게 도입된 비교 문법 <strong>Object.js</strong></li>
</ol>
<ul>
<li><p>Object.js</p>
<ul>
<li>=== 처럼 타입이 다르면 false를 반환한다.</li>
<li>-0 === +0 =&gt; true / Object.is(-0, +0) =&gt; false</li>
</ul>
<br />
</li>
</ul>
<ol start="2">
<li>부수효과를 최소화하기 위해서 useEffect를 최소한으로 사용하는 것이 좋다. useEffect 사용을 줄임으로써 함수의 역할을 좁히고, 버그를 줄이며, 컴포넌트의 안정성을 높일 수 있다.</li>
</ol>
<br />

<h3 id="02-리액트-핵심요소-깊게-살펴보기">02. 리액트 핵심요소 깊게 살펴보기</h3>
<ol>
<li>JSX
 리액트에서 JSX를 접하다 보니 리액트의 전유물이라고 착각하기 쉬운데 JSX는 독자적인 문법이라는 사실!
 하지만, 아무런 처리없이 JSX 코드를 실행하면 오류가 발생한다.
 반.드.시 트랜스파일러를 거쳐야 자바스크립트 런타임이 이해할 수 있는 자바스크립트 코드로 변환된다.<ul>
<li>JSXElement  <div><div />
    <div/>
    <></></li>
<li>JSXAttributes</li>
<li>JSXChildren</li>
<li>JSXStrings</li>
</ul>
</li>
</ol>
<blockquote>
<p>1-1. JSX가 변환되는 특성을 활용</p>
</blockquote>
<pre><code class="language-javascript">import {createElement, PropsWithChildren} from &#39;react&#39;;
  function Text({
     isCheck,
     children,
}: PropsWithChildren&lt;{ isCheck : boolean}&gt;) {
   return isCheck ? (
     &lt;h1 className=&quot;text&quot;&gt;{children}&lt;/h1&gt;
   ) : (
    &lt;span className=&quot;text&quot;&gt; className=&quot;text&quot;&gt;{children}&lt;/span&gt;
   )
}
  //이런식으로 짠다면 불필요한 코드 중복이 일어나서 비추
  //
  //
  import {createElement, PropsWithChildren} from &#39;react&#39;;
   function Text({
     isCheck,
     children,
}: PropsWithChildren&lt;{ isCheck : boolean}&gt;) {
   return createElement(
      isCheck ? &#39;h1&#39; : &#39;span&#39;,
    { className : &#39;text&#39;},
    children,
   )
}
// JSX 반환값이 결국 React.createElement로 귀결된다는 것을 알면
// 이렇게 리팩토링 삽가능!</code></pre>
<ol start="2">
<li>가상 DOM
하나의 페이지에서 모든 작업이 일어나는 싱글 페이지 어플리케이션의 경우 DOM의 부담도 크다.
때문에 탄생한 것이 <strong>가상 DOM</strong>이다.</li>
</ol>
<p>  <strong>가상 DOM</strong>은 말그대로 실제 브라우저의 DOM이 아닌 react에서 관리하는 가상의 DOM이다.
  가상의 DOM은 실제 브라우저의 DOM을 일단 메모리에 저장하고 리액트가 실제 변경에 대한 준비가 완료됐을 때 실제 브라우저 DOM에 반영한다. 
  이렇게 메모리에서 계산하는 과정을 한번 거치게 된다면, 실제 DOM이 받는 부담을 덜 수 있다.</p>
<p>  2-1 가상 DOM을 위한 아키텍처, 리액트 파이버
  파이버는 가상 DOM과 실제 DOM을 비교해서 변경사항을 수집한다. 후에 파이버 기준으로 렌더링을 요청한다. 이것은 모두 비동기작업으로 이루어진다는 점!
  파이버는 컴포넌트가 최초로 마운트되는 시점에 생성되어 가급적이면 재사용된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA['string | null' 형식은 'number' 형식에 할당할 수 없습니다.
  'null' 형식은 'number' 형식에 할당할 수 없습니다.]]></title>
            <link>https://velog.io/@ohwowo_o/string-null-%ED%98%95%EC%8B%9D%EC%9D%80-number-%ED%98%95%EC%8B%9D%EC%97%90-%ED%95%A0%EB%8B%B9%ED%95%A0-%EC%88%98-%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4.-null-%ED%98%95%EC%8B%9D%EC%9D%80-number-%ED%98%95%EC%8B%9D%EC%97%90-%ED%95%A0%EB%8B%B9%ED%95%A0-%EC%88%98-%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4</link>
            <guid>https://velog.io/@ohwowo_o/string-null-%ED%98%95%EC%8B%9D%EC%9D%80-number-%ED%98%95%EC%8B%9D%EC%97%90-%ED%95%A0%EB%8B%B9%ED%95%A0-%EC%88%98-%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4.-null-%ED%98%95%EC%8B%9D%EC%9D%80-number-%ED%98%95%EC%8B%9D%EC%97%90-%ED%95%A0%EB%8B%B9%ED%95%A0-%EC%88%98-%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4</guid>
            <pubDate>Fri, 27 Oct 2023 08:04:53 GMT</pubDate>
            <description><![CDATA[<p>타입스크립트를 쓰기 시작하고 props를 보낼때 자주 만나게 됐던 경고창...
상황을 간략하게 설명을 해보자면!</p>
<p><br/><br/></p>
<blockquote>
<p>systemIdx: number;</p>
</blockquote>
<p>타입을 지정해주었고</p>
<br/>

<blockquote>
<p>const systemIdx = sessionStorage.getItem(&quot;systemIdx&quot;);</p>
</blockquote>
<p>아마도 아니 무조건 number여야만! 하는! 값을 세션에서 받아와서</p>
<p><br/><br/></p>
<blockquote>
<p>systemIdx: systemIdx</p>
</blockquote>
<p>props를 넘겨주는데!</p>
<p><br/><br/></p>
<p><img src="https://velog.velcdn.com/images/ohwowo_o/post/791d274f-7f37-417a-a320-3efe008abaf8/image.png" alt=""></p>
<p>화를 잔뜩 나게 하는 빨간줄.. 타입오류..</p>
<p><br/><br/></p>
<blockquote>
<p>🚩
if (typeof systemIdx !== &quot;number&quot;) return alert(&quot;타입에러&quot;);</p>
</blockquote>
<p>이렇게 예외처리를 넣어서 해결해주었음! 캬캬캬</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript]]></title>
            <link>https://velog.io/@ohwowo_o/JavaScript</link>
            <guid>https://velog.io/@ohwowo_o/JavaScript</guid>
            <pubDate>Sat, 04 Mar 2023 10:19:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>JavaScript가 무엇일까?</strong></p>
</blockquote>
<ul>
<li>역사 : 지금 자바스크립트는 아주 널리, 필수로 쓰이고 있는 스크립트 언어지만 그 시작은 단 10일이였다. 1995년 넷스케이프에서 근무하던 브랜든 아이크에 의해 10일만에 탄생된 자바스크립트. 그는 그때 자바스크립트가 이렇게까지 사용될 줄 알았을까?
처음 이름은 Mocha로 시작으나 4달만에 LiveScript로 개명하고 다시 3달 후에 Java와 비슷한 JavaScript로 개명하면서 유명세를 타기시작하고 지금까지 이어지고 있다. 개명 이유를 Java와 비슷한 구문을 사용하기 때문이라고 했지만, 당시 유명했던 Java에게 묻어가기 위함이 아닌가하는 의견들이 많다. 결과적으로 그런 의도는 성공적인 결과를 끌어냈다. 
나도 처음 JavaScript 공부를 시작했을때 Java와 이름이 비슷해서 비슷한 언어인가 하는 의문을 갖고 찾아봤었다. 그렇게 알게 된 둘의 관계는 햄과 햄스터 정도라는 것!</li>
</ul>
<br/>

<blockquote>
<p><strong>JavaScript의 특징</strong>
JavaScript는 약 28년간의 발전을 거쳐오면서 성숙한 프론트 프로그래밍의 기본언어로 자리 잡게 되었습니다. 브라우저들은 ECMA 표준사항을 따라가고 있으며 그로 인해 제이쿼리같은 라이브러리의 도움이 필요하지 않게 됩니다.</p>
</blockquote>
<ul>
<li>싱글 스레드 언어
싱글 스레드 언어이기 때문에 코드가 작성된 순서대로 작업이 처리됩니다.
이것을 동기방식이라하며 다른 작업이 불가능하도록 막습니다.(블로킹)
반대로 비동기 방식은 기다리지 않고 실행하겠다(논블로킹)는 의미입니다. (2초 setTimeout을 걸어도 기다리지않고 다음 애가 실행됨) 자바스크립트에서 어떻게 비동기 방식을 처리하는 지는 다른 글에서 다루겠습니다.</li>
<li>SPA(Single page Application)는 완전한 새로운 페이지를 불러오지않고 업데이트된 필요한 데이터만 불러오는 기법으로 전체적인 트래픽 감소와 렌더링에서 좋은 효율을 낸다는 이점때문에 최근에 많이 사용되고 있는데 JavaScript만으로 구현이 가능하나, 더욱 쉽게 만들기 위해 <strong>React나 Angula, Vue 등의 프레임 워크</strong>의 도움을 받습니다.</li>
<li>객체 지향 언어
JavaScript를 구성하는 거의 모든것이 객체입니다. 원시형(단하나의 값만을 나타냄)을 제외한 모든것이 관계성있는 객체들의 집합이라고 볼 수 있습니다. 명령형, 함수형, 프로토타입 기반 객체 지향 언어입니다. JavaScript는 클래스 개념이 없고 별도의 객체 생성 방법이 존재합니다.<pre><code class="language-javascript">//객체 리터널
const object = {};
object.name = &#39;Nia&#39;;   </code></pre>
<pre><code class="language-javascript">//object() 생성자 함수
const obj = new Object();
obj.name = &#39;Nia&#39;</code></pre>
<pre><code class="language-javascript">//생성자함수
function O(){}
const obj2 = new O();
obj2.name = &#39;Nia&#39;;</code></pre>
</li>
</ul>
<br/>


<blockquote>
<p>*<em>JavaScript의 이점 *</em></p>
</blockquote>
<ul>
<li>JavaScript는 *인터프리터 언어이기 때문에 Java와 같은 컴파일이 필요한 프로그래밍 언어에 비해 시간이 적게 소요됩니다.</li>
<li>인터프리터 언어란? : 프로그래밍 언어를 컴파일하여 기계언어로 바꾸지 않고 바로 실행할 수 있는 언어를 뜻한다.</li>
<li>대중화되어 있기 때문에 정보를 얻기 쉽고 소스를 접하기 쉬우며 접근하기 용이하다는 장점이 있습니다.</li>
</ul>
<br/>

<blockquote>
<p><strong>JavaScript를 직접써보면서 느낀 장점 &amp; 단점</strong>
퍼블리셔로 근무를 시작했기때문에 JavaScript보다 JQuery를 먼저 접했었습니다. 그래서 JQuery와 비교를 하면서 느낄 수 있었던 점은,</p>
</blockquote>
<ul>
<li>먼저 문법에서 차이를 느낄 수 있습니다. 개인적으로 JQuery 문법이 더 쉽고 간결하게 느껴졌습니다.<pre><code class="language-javascript">//JQuery
$(&#39;.blackBox&#39;).css(&#39;background-color&#39;, &#39;black&#39;) </code></pre>
<pre><code class="language-javascript">//JavaScript
const blackBox = document.getElementById(&quot;blackBtn&quot;); 
blackBox.addEventListener(&quot;click&quot;, (e) =&gt; {
document.body.style.backgroundColor = &quot;black&quot;;
});</code></pre>
예제코드에서 볼 수 있듯이 직관적으로 보기에도 JQuery 문법이 짧고 간결함이 느껴진다.
하지만 그 처리속도에서 차이가 느낄 수 있는데 JQuery는 단계를 거쳐서 실행되기 때문에 JavaScript보다 느립니다. </li>
</ul>
<br/>

<blockquote>
<p>공부하면서 참고했던 모든 것</p>
</blockquote>
<ol>
<li>무료강좌</li>
</ol>
<ul>
<li>윤인성 혼자공부하는 자바스크립트
<a href="https://youtube.com/playlist?list=PLBXuLgInP-5kxpAKy2DNXoebCse2grHjl">https://youtube.com/playlist?list=PLBXuLgInP-5kxpAKy2DNXoebCse2grHjl</a></li>
<li>유튜브 &gt; 제로초 &gt; 2021 자바스크립트
<a href="https://youtube.com/playlist?list=PLcqDmjxt30RvEEN6eUCcSrrH-hKjCT4wt">https://youtube.com/playlist?list=PLcqDmjxt30RvEEN6eUCcSrrH-hKjCT4wt</a></li>
<li>별코딩
<a href="https://www.youtube.com/playlist?list=PLZ5oZ2KmQEYiGLIDlsTQR_wdfCH9ZD6lx">https://www.youtube.com/playlist?list=PLZ5oZ2KmQEYiGLIDlsTQR_wdfCH9ZD6lx</a></li>
<li>코딩앙마
<a href="https://www.youtube.com/watch?v=ocGc-AmWSnQ&amp;list=PLZKTXPmaJk8JZ2NAC538UzhY_UNqMdZB4">https://www.youtube.com/watch?v=ocGc-AmWSnQ&amp;list=PLZKTXPmaJk8JZ2NAC538UzhY_UNqMdZB4</a><br/></li>
</ul>
<ol start="2">
<li>유료강좌</li>
</ol>
<ul>
<li>인프런 &gt; 김영보님 강의
<a href="https://www.inflearn.com/courses?s=%EA%B9%80%EC%98%81%EB%B3%B4">https://www.inflearn.com/courses?s=%EA%B9%80%EC%98%81%EB%B3%B4</a></li>
<li>코딩애플
<a href="https://codingapple.com/">https://codingapple.com/</a><br/></li>
</ul>
<ol start="3">
<li>인사이트</li>
</ol>
<ul>
<li><a href="https://poiemaweb.com/">https://poiemaweb.com/</a></li>
<li><a href="https://ko.javascript.info/">https://ko.javascript.info/</a></li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide">https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로젝트 배포하기]]></title>
            <link>https://velog.io/@ohwowo_o/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@ohwowo_o/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 07 Jan 2023 13:35:22 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>npm run build</strong>
압축된 파일을 얻을 수 있음
압축된 형태로 배포할 수 있도록 해주는 것임
build라는 폴더가 생김</p>
</blockquote>
<br />

<blockquote>
<p><strong>npm install -g serve</strong>
파일을 배포할 수 있는 패키지
serve라는 명령어를 깔아야 배포할 수 있음</p>
</blockquote>
<br />

<p>!! 배포할 준비 끝 !!</p>
<br />

<blockquote>
<p><strong>serve -s build</strong>
build 파일들을 실제로 배포해보기</p>
</blockquote>
<br />

<p>On Your Network 주소 : 나와 같은 공유기를 쓰는 사람들이 접속 할 수 있는 주소</p>
<p>!! 이때 오류가 발견되면 수정하고 1번과 3번 다시</p>
<br />

<blockquote>
<p>Firebase에서 프로젝트 만들기
Firebase 호스팅 설정 : </p>
</blockquote>
<ul>
<li>CLI 설치 (cmd에서) : 파이어베스에서 뜨는 명령어 복사에서 넣기</li>
<li>프로젝트 초기화 : 파이어베스에 뜨는대로 하기<ol>
<li>google 로그인 : $ firebase login</li>
</ol>
-&gt; 오류가 발생하면 vscode 안에서 firebase login &gt; 메일 입력<ol start="2">
<li>프로젝트 시작 : firebase init</li>
</ol>
-&gt; 진행할 준비 됐냐?
-&gt; Hosting : Configure..
-&gt; Use an ... 프로젝트 이미 만들었음
-&gt; public : build
-&gt; 싱글페이지 만들거야? yes
-&gt; git 연결?
-&gt; 이미 index있어 다시써도돼?</li>
</ul>
<p>** firebase 폴더 생성 됨 **</p>
<p>firebase 사이트에서 아까 만든 프로젝트 안에 사이트 추가해준 후</p>
<blockquote>
<p>firebase.json 파일에서 &quot;hosting&quot; : {&quot;site&quot;:&quot;추가한 사이트주소&quot;}
<strong>npm run build</strong>
<strong>firebase deploy</strong>
호스팅 주소 나옴</p>
</blockquote>
<p><br /><br /></p>
<p><strong>완료</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Interface로 props 이동하기 오류 탈출]]></title>
            <link>https://velog.io/@ohwowo_o/Interface%EB%A1%9C-props-%EC%9D%B4%EB%8F%99%ED%95%98%EA%B8%B0-%EC%98%A4%EB%A5%98-%ED%83%88%EC%B6%9C</link>
            <guid>https://velog.io/@ohwowo_o/Interface%EB%A1%9C-props-%EC%9D%B4%EB%8F%99%ED%95%98%EA%B8%B0-%EC%98%A4%EB%A5%98-%ED%83%88%EC%B6%9C</guid>
            <pubDate>Sat, 07 Jan 2023 13:35:08 GMT</pubDate>
            <description><![CDATA[<p><strong>야호</strong></p>
<blockquote>
<ul>
<li>목적 : &#39;회원탈퇴&#39;버튼을 클릭하면 정보 팝업창이 뜨고 팝업창에 있는 &#39;취소&#39;버튼을 클릭하면 팝업창이 닫히는 기능을 구현하고 싶었음.</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>상황 : &#39;회원탈퇴&#39;버튼은 Mypage.tsx파일에 있고, &#39;취소&#39;버튼은 Withdrawal.tsx 파일에 있어서 prop를 이동해야 하는 상황</li>
</ul>
</blockquote>
<p><br /><br /></p>
<p><img src="https://velog.velcdn.com/images/ohwowo_o/post/8e42b9b4-c205-420f-9067-722104d3ace1/image.png" alt=""></p>
<p>신나는 코딩 시작 (•̀ᴗ•́) ̑̑و</p>
<p><br/><br/></p>
<pre><code class="language-typescript">//Mypage.tsx
export interface PropsType {
  popup: boolean;
}

const MypageTab = () =&gt; {
  const [popup, setPopup] = useState&lt;PropsType[&#39;popup&#39;]&gt;(false);

  return (
    &lt;ContentsList&gt;
        &lt;p onClick={() =&gt; setPopup(true)}&gt;회원탈퇴&lt;/p&gt;
    &lt;/ContentsList&gt;
    &lt;ContentsResult&gt;
        {popup === true &amp;&amp; &lt;Withdrawal togglePop={togglePop} /&gt;}
    &lt;/ContentsResult&gt;
  );
};</code></pre>
<pre><code class="language-typescript">//Withdrawal.tsx
import { PropsType } from &#39;./MypageTab&#39;;
const Withdrawal = ({popup,}: {popup: PropsType[&#39;popup&#39;];}): JSX.Element | any =&gt; {
  const onPopupToggle = (popup: any) =&gt; {
    popup(!popup);
    console.log(popup);
  };
  if (popup) {
    return (
        &lt;Popup&gt;
            &lt;Btn fontColor=&quot;#666&quot; backgroundColor=&quot;#fff&quot; padding=&quot;11px 26px&quot;&gt;
              취소
            &lt;/Btn&gt;
        &lt;/Popup&gt;
    );
  }
};</code></pre>
<p><br /><br /></p>
<p>오류감옥에 갇힘..
<img src="https://velog.velcdn.com/images/ohwowo_o/post/f624eab7-427f-436b-84a5-be6edf88c8ca/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/ohwowo_o/post/80316313-6104-40a6-9eb6-c7012c0852bb/image.png" alt=""></p>
<p>검색.. 검색... 이유... 보내는법.. interface.. props.. react ..</p>
<p><br /><br /></p>
<p>몇일을 고민하다가 해결법을 찾음 야호</p>
<pre><code class="language-typescript">//Mypage.tsx
const MypageTab = () =&gt; {
  const [popup, setPopup] = useState&lt;boolean&gt;(false);
  const togglePop = () =&gt; {
    setPopup(!popup);
  };

  return (
    &lt;ContentsList&gt;
        &lt;p onClick={() =&gt; setPopup(true)}&gt;회원탈퇴&lt;/p&gt;
    &lt;/ContentsList&gt;
    &lt;ContentsResult&gt;
        {popup === true &amp;&amp; &lt;Withdrawal togglePop={togglePop} /&gt;}
    &lt;/ContentsResult&gt;
  );
};</code></pre>
<pre><code class="language-typescript">//Withdrawal.tsx
interface Prop {
  togglePop: () =&gt; void;
}
const Withdrawal = ({ togglePop }: Prop): JSX.Element | any =&gt; {
  return (
      &lt;Popup&gt;
          &lt;Btn
            fontColor=&quot;#666&quot;
            backgroundColor=&quot;#fff&quot;
            padding=&quot;11px 26px&quot;
            onClick={togglePop}
          &gt;
            취소
          &lt;/Btn&gt;
      &lt;/Popup&gt;
  );
};</code></pre>
<p>성공!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[target type 오류]]></title>
            <link>https://velog.io/@ohwowo_o/React-Typescript</link>
            <guid>https://velog.io/@ohwowo_o/React-Typescript</guid>
            <pubDate>Sat, 07 Jan 2023 13:34:35 GMT</pubDate>
            <description><![CDATA[<p>Create React App과 Typescript 한꺼번에 설치 착착</p>
<blockquote>
<p>npx create-react-app my-app --template typescript</p>
</blockquote>
<p><br /><br /></p>
<p><img src="https://velog.velcdn.com/images/ohwowo_o/post/b1b80edb-cff5-4f0c-aa45-5b7c4a951c1d/image.png" alt="">
뭔가 오류가 난다 왤까..? ㄴㅇㄱ</p>
<p>평소하던데로 e.target을 주었더니!
또 문제발생
<img src="https://velog.velcdn.com/images/ohwowo_o/post/80d2df49-5acb-43dc-b9a6-f266d7fc2967/image.png" alt="">
<img src="https://velog.velcdn.com/images/ohwowo_o/post/01707b4a-d0b6-4d28-b0b6-f85d6d427f7b/image.png" alt=""></p>
<pre><code class="language-typescript">const inputId = (e : {target : HTMLInputElement}) =&gt; {
  console.log(e.target.value )
}</code></pre>
<p>이런식으로 target에 type지정해 주었더니 해결</p>
<p>useState 로 id값 저장하려고했더니 또 오류발생!
<img src="https://velog.velcdn.com/images/ohwowo_o/post/e8108b21-1265-4e25-b7ec-cd1dc9a4390c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/ohwowo_o/post/4d099f3d-bc06-47d8-a20a-289594d86c53/image.png" alt=""></p>
<p>근데 이렇게 하는 경우는 number을 넣고 싶어도 string으로만 받아오는 현상이 발생한다고 한다.
html 자체가 element.value를 스트링으로 꺼내오는 특징이 있다고함.
넘버를 넣어도 받아와보면 string인 현상..</p>
<blockquote>
<p>참고사이트 : <a href="https://stackoverflow.com/questions/61070803/how-to-handle-number-input-in-typescript">https://stackoverflow.com/questions/61070803/how-to-handle-number-input-in-typescript</a>
변환하고 싶은 시점에서 number로 변환해 사용해야 한다고 한다</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[React-query]]></title>
            <link>https://velog.io/@ohwowo_o/React-query</link>
            <guid>https://velog.io/@ohwowo_o/React-query</guid>
            <pubDate>Sat, 07 Jan 2023 13:34:04 GMT</pubDate>
            <description><![CDATA[<ul>
<li>ajax 성공 시 / 실패 시 html 보여주려면 ?</li>
<li>몇초마다 자동으로 ajax 요청 ?</li>
<li>실패 시 몇초 후 요청 재시도 ?</li>
<li>prefetch ?
=&gt; 쉽게 구현가능한 <strong>React - Query</strong> !!! 야호 ٩( ᐛ )و 배워보자</li>
</ul>
<p>(코인거래소나 실시간sns같은 실시간 데이터를 계속 가져와야 하는 사이트들이 쓰면 좋음)</p>
<br />

<blockquote>
<p>npm install react-query 설치
(index.js)
import {QueryClient, QueryClientProvider } from &quot;react-query&quot;;
const queryClient = new QueryClient()</p>
</blockquote>
<pre><code>&lt;QueryClientProvider client={queryClient}&gt;
  ~~~
&lt;/QueryClientProvider&gt;</code></pre><pre><code class="language-javascript">useQuery(&#39;작명&#39;, ()=&gt;{
    return axios.get(&#39;https://~~&#39;).then((a)=&gt;{
        return a.data
    })
})</code></pre>
<p><br /><br /></p>
<h2 id="장점-❗">장점 ❗</h2>
<p><strong>1. 성공/실패/로딩 중 쉽게 파악가능</strong></p>
<pre><code class="language-javascript">let result = useQuery(&#39;작명&#39;, ()=&gt;{
    return axios.get(&#39;https://~~&#39;).then((a)=&gt;{
        return a.data
    })
})

// result.data - axios 요청이 성공했을때 가져오는 데이터 들어있음
// result.isLoading - axios 요청이 로딩중일때 true 값이 됨
// result.error - axios 요청이 실패했을 때 true 값이 됨

{result.isLoading &amp;&amp; &#39;로딩중&#39;}
//로딩중일때 &#39;로딩중&#39;띄워줘
</code></pre>
<p><br /><br /></p>
<p><strong>2. 틈만나면 자동으로 재요청해줌</strong></p>
<p>다른 탭으로 들어갔다와도 자동으로 refetch 해줌
실시간으로 신선한 데이터들을 보여줘야하는 사이트도 걱정하지 않아도됨! good!
간격 설정도 가능</p>
<pre><code class="language-javascript">let result = useQuery(&#39;작명&#39;, ()=&gt;{
    return axios.get(&#39;https://~~&#39;).then((a)=&gt;{
        return a.data
    }),
    {staleTime : 2000}
  //2초 안에는 refetch 안되게 설정할 수 있음
  //refetch를 끌 수 도있음
})</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[promis / async & await]]></title>
            <link>https://velog.io/@ohwowo_o/promis-async-await</link>
            <guid>https://velog.io/@ohwowo_o/promis-async-await</guid>
            <pubDate>Sat, 07 Jan 2023 13:30:48 GMT</pubDate>
            <description><![CDATA[<p>promise.all =&gt; 최종적으로 기다렸다가 한번만 반환</p>
<pre><code class="language-javascript">function a(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;A&#39;) //이행
        }, 1000)
    })
}

function b(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;B&#39;) //이행
        }, 2000)
    })
}

;(async () =&gt; {

    const res = await Promise.all([a(), b()])
    console.log(res)
})()</code></pre>
<p><br /><br /><br /></p>
<p>Promise.race =&gt; 선착순. 제일 먼저 온 값만 반환</p>
<pre><code class="language-javascript">function a(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;A&#39;) //이행
        }, 1000)
    })
}

function b(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;B&#39;) //이행
        }, 2000)
    })
}

function c(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;C&#39;) //이행
        }, 3000)
    })
}


;(async () =&gt; {
    const res = await Promise.race([a(), b(), c()])
    console.log(res)

})()</code></pre>
<p><br /><br /><br /></p>
<p>forEach는 비동기를 순서대로 돌릴수가 없음. 한번에 팍뜸!</p>
<pre><code class="language-javascript">function a(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;A&#39;)
        }, 1000)
    })
}

function b(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;B&#39;)
        }, 1000)
    })
}


function c(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;C&#39;)
        }, 1000)
    })
}

const arr = [a, b, c]
arr.forEach(async item =&gt; {
    console.log(await item())
})</code></pre>
<p><br /><br /><br /></p>
<p>for 반복문은 비동기를 순서대로 돌릴 수 있음</p>
<pre><code class="language-javascript">function a(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;A&#39;)
        }, 1000)
    })
}

function b(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;B&#39;)
        }, 1000)
    })
}


function c(){
    return new Promise(resolve =&gt; {
        setTimeout(() =&gt; {
            resolve(&#39;C&#39;)
        }, 1000)
    })
}


;(async () =&gt; {
    const arr = [a, b, c]
    for( let i = 0; i&lt; arr.length; i += 1){
        console.log(await arr[i]())
    }
})()</code></pre>
<blockquote>
<p>for =&gt; 기본
for in =&gt; 객체
for of =&gt; 배열</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Class]]></title>
            <link>https://velog.io/@ohwowo_o/Class</link>
            <guid>https://velog.io/@ohwowo_o/Class</guid>
            <pubDate>Sat, 07 Jan 2023 13:30:31 GMT</pubDate>
            <description><![CDATA[<p>typeof abc // function 남는 것은 인스턴스
typeof abc() //undefined 남는 것은 데이타</p>
<p>funcrion abc(){
  return 123
 }</p>
<p> 함수가 호출되고 증발한다. 남는 것은 데이타
 typeof abc // function
typeof abc() //123</p>
<p>일스턴스에 붙이는 일반메소드다
.prototype</p>
<p>정적메소드
.prototype(x)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Promise 비동기 만들기]]></title>
            <link>https://velog.io/@ohwowo_o/Promise-%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@ohwowo_o/Promise-%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sat, 07 Jan 2023 13:30:09 GMT</pubDate>
            <description><![CDATA[<h2 id="promise">Promise</h2>
<br />

<p>Promise를 실행해서 나온 인스턴스를 리턴하고</p>
<p>resolve를 매개변수로 가져옴</p>
<pre><code class="language-javascript">function a(){
    return new Promise((resolve)=&gt;{
        setTimeout(()=&gt;{
            console.log(&#39;A&#39;)
            resolve()
        },1000)
    }, 1000)
}
</code></pre>
<p><br /><br /></p>
<p>Promise 에서는
then이라는 매소드를 쓸수있음</p>
<pre><code class="language-javascript">function a(){
    return new Promise((resolve)=&gt;{
        setTimeout(()=&gt;{
            console.log(&#39;A&#39;)
            resolve()
        },1000)
    }, 1000)
}

function b(){
    console.log(&#39;b&#39;)
}

const p = a()
p.then(()=&gt; {
    b()
})
//then(()=&gt; { b()}) 콜백이 resolve로 들어가게되는 것임</code></pre>
<p><br /><br /></p>
<pre><code class="language-javascript">function a(){
    return new Promise((resolve)=&gt;{
        setTimeout(()=&gt;{
            console.log(&#39;A&#39;)
            resolve()
        },1000)
    })
}

function b(){
    return new Promise((resolve)=&gt;{
        setTimeout(()=&gt;{
            console.log(&#39;B&#39;)
            resolve()
        },1000)
    })
}
function c(){
    return new Promise((resolve)=&gt;{
        setTimeout(()=&gt;{
            console.log(&#39;C&#39;)
            resolve()
        },1000)
    })
}
function d(){
    return new Promise((resolve)=&gt;{
        setTimeout(()=&gt;{
            console.log(&#39;D&#39;)
            resolve()
        },1000)
    })
}

a().then(()=&gt; {
    b().then(()=&gt; {
        c().then(()=&gt; {
            d()
        })
    })
})</code></pre>
<p>abcd를 순차적으로 실행할수 있음
하지만 콜백 아도겐과 다를게없어보임 ??
이렇게 쓰지않음
밑에서 다시 적어보겠음</p>
<p><br /><br /></p>
<pre><code class="language-javascript">a().then(() =&gt; b()).then()
a().then(b).then()
//두개가 같은거임</code></pre>
<p>💡🤷🏻‍ <strong>.then(b)에 .then(b())를 해야하는거 아닌가요?</strong></p>
<blockquote>
<p>❌ NO 아닙니다. 두개는 다른 것
b =&gt; 함수임 function
b() =&gt; promise 인스턴스</p>
</blockquote>
<p><br /><br /></p>
<h2 id="async--await">async &amp; await</h2>
<br />

<p><strong>async &amp; await
;()() =&gt; 즉시실행함수</strong></p>
<pre><code class="language-javascript">;(async function() {
    await a()
    await b()
    await c()
    await d()
})()
// 이런 결과물이 나옴</code></pre>
<p><br /><br /></p>
<p>resolve : 해결됨
reject : 거부
reject 기다리는거 멈춰!</p>
<p>보통은 해결되는 상황만 써도 되긴하는데, 거부되는 상황이 나올 수도 있음
예) 인터넷이 안되는상황이면 해결될때까지 계속 기다릴 수없으니 거부되는 상황에는
그냥 멈추라고 로직을 짜주는 것임</p>
<p>reject쓰면 최종적으로 .catch를 쓸수 있음</p>
<pre><code class="language-javascript">function a(ok){
    return new Promise((resolve, reject)=&gt;{
        setTimeout(()=&gt;{
            if(!ok){
                reject()
                return
                //멈출꺼면 꼭 리턴을 써야함 안쓰면 x여도, A찍히고 x도 찍힘 
            }
            console.log(&#39;A&#39;)
            resolve()
        },1000)
    })
}

//a호출에 true라는 매개변수넣어주면 O뜨고 false넣어주면 X 뜸
a(false)
    .then(()=&gt;{
        console.log(&#39;Resolved! O&#39;)
    })
    .catch(()=&gt;{
        console.log(&#39;Rejected! X&#39;)
    })
</code></pre>
<p><br /><br /></p>
<pre><code class="language-javascript">//resolve(1234)를 넣어서 res(작명)라는 이름으로 받을 수 있음
function a(ok){
    return new Promise((resolve, reject)=&gt;{
        setTimeout(()=&gt;{
            if(!ok){
                reject()
                return
            }
            console.log(&#39;A&#39;)
            resolve(1234)
        },1000)
    })
}

a(true)
    .then((res)=&gt;{
        console.log(&#39;Resolved! O&#39;)
        console.log(res)
    })
    .catch(()=&gt;{
        console.log(&#39;Rejected! X&#39;)
    })</code></pre>
<p>** - console 출력 (이미지참고)**
<img src="https://velog.velcdn.com/images/ohwowo_o/post/a84f8f23-0f2b-499d-8e6a-8983bfa6cc01/image.png" alt=""></p>
<p><br /><br /></p>
<pre><code class="language-javascript">// reject(&#39;Err&#39;) 넣으면 .catch((err)=&gt;{})에서 받을 수 있음
function a(ok){
    return new Promise((resolve, reject)=&gt;{
        setTimeout(()=&gt;{
            if(!ok){
                reject(&#39;Err&#39;)
                return
                //멈출꺼면 꼭 리턴을 써야함 안쓰면 x여도 A나오고 x도나옴 
            }
            console.log(&#39;A&#39;)
            resolve(1234)
        },1000)
    })
}

//a호출에 true라는 매개변수넣어주면 O뜨고 false넣어주면 X 뜸
a(false)
    .then((res)=&gt;{
        console.log(&#39;Resolved! O&#39;)
        console.log(res)
    })
    .catch((err)=&gt;{
        console.log(&#39;Rejected! X&#39;)
        console.log(err)
    })</code></pre>
<p><br /><br /></p>
<p><strong>webAPI</strong>
fetch()
document.querySelector()</p>
<p><br /><br /><br /></p>
<p><strong>- http 상태 코드</strong></p>
<p><img src="https://velog.velcdn.com/images/ohwowo_o/post/0085e584-72b8-4ab9-8feb-42b6f6f0e87c/image.png" alt=""></p>
<blockquote>
<p>200대는 정상
400대는 요청오류 (프론트 오류일 확률 매우 높음)
401 권한 없음 (apk key 잘못됐을 확률)</p>
</blockquote>
<p><br /><br /><br /></p>
<pre><code class="language-javascript">fetch(&#39;https://www.omdbapi.com/?apikey=틀린api키&amp;s=frozen&#39;)
    .then(res =&gt; res.json())
    .then(res =&gt; console.log(res))
    .catch(err =&gt; console.log(&#39;Error:&#39;, err))</code></pre>
<p>에러나도 fetch는 따로 로직을 짜주지 않는 이상 잡아내지못함
.catch()부분이 뜨지 않음. =&gt; Axios는 잘 잡아냄(설치해야함)
서버에서는 오류가 나서 에러메세지를 보내도 메세지가 보내진거니까 데이터를 정상적인 응답에 해당함</p>
<p><br /><br /><br /></p>
<pre><code class="language-javascript">function http(url){
    return new Promise((resolve, reject) =&gt; {
        fetch(url)
            .then(res =&gt; res.json())
            .then(res =&gt; {
                if(res.Response === &#39;False&#39;){
                    reject(res.Error)
                    return //다른코드가 있다면
                }
                console.log(123) //다른코드가 있다면
                resolve(res)
            })
            .catch(err =&gt; reject(err))
    })
}

http(&#39;https://www.omdbapi.com/?apikey=틀린api키&amp;s=frozen&#39;)
.then(res =&gt; console.log(&#39;Resolved O:&#39; , res))
.catch(err =&gt; console.log(&#39;Resolved X:&#39; , err))</code></pre>
<p>이런식으로 로직을 추가해줘야 에러를 잡아낼수있음</p>
<p><br /><br /><br /></p>
<p>async 쓸수있음 </p>
<pre><code class="language-javascript">;(async () =&gt; {
    const res = await http(&#39;https://www.omdbapi.com/?apikey=7035c60c123&amp;s=frozen&#39;)
    console.log(&#39;Resolved O:&#39; , res) //정상코드
})()</code></pre>
<p>try catch =&gt; 시도해봤는데 에러가 나면 catch로 넘어간다
+finally =&gt; 에러가 안생겨도 생겨도 finally 무조건실행 (필수는 아니고 무조건 실행해야할 코드가 있을때만 쓰임)</p>
<pre><code class="language-javascript">;(async () =&gt; {
    try{
        const res = await http(&#39;https://www.omdbapi.com/?apikey=7035c60c123&amp;s=frozen&#39;)
        console.log(&#39;Resolved O:&#39; , res) //정상코드
    } catch (err){
        console.log(&#39;Resolved X:&#39; , err)
    }

})()</code></pre>
<p><br /><br /><br /></p>
<p><strong>중간 전체코드 정리</strong></p>
<pre><code class="language-javascript">function http(url){
    return new Promise((resolve, reject) =&gt; {
        fetch(url)
            // .then(res =&gt; res.json()) //json메소드를 통해 파싱중
            .then(res =&gt; {
                console.log(res)
                // if(!res.ok) reject() =&gt; 만약 오류가 나면 reject로 넘어가라
                return res.json()
            })
            .then(res =&gt; {
                if(res.Response === &#39;False&#39;){
                    reject(res.Error)
                    return //다른코드가 있다면
                }
                console.log(123) //다른코드가 있다면
                resolve(res)
            })
            .catch(err =&gt; reject(err))
    })
}

// http(&#39;https://www.omdbapi.com/?apikey=7035c60c123&amp;s=frozen&#39;)
// .then(res =&gt; console.log(&#39;Resolved O:&#39; , res))
// .catch(err =&gt; console.log(&#39;Resolved X:&#39; , err))

;(async () =&gt; {
    try{
        const res = await http(&#39;https://www.omdbapi.com/?apikey=7035c60c&amp;s=frozen&#39;)
        console.log(&#39;Resolved O:&#39; , res) //정상코드
    } catch (error){
        console.log(&#39;Resolved X:&#39; , error)
    }

})()</code></pre>
<p><br /><br /><br /></p>
<p>new promise()
기다린 다음을 약속해준다고 기억하기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🤷🏻‍♀️ 동기? 비동기?]]></title>
            <link>https://velog.io/@ohwowo_o/%EB%8F%99%EA%B8%B0-%EB%B9%84%EB%8F%99%EA%B8%B0</link>
            <guid>https://velog.io/@ohwowo_o/%EB%8F%99%EA%B8%B0-%EB%B9%84%EB%8F%99%EA%B8%B0</guid>
            <pubDate>Sat, 07 Jan 2023 13:27:46 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>자바스크립트는 동기식 처리 (Synchronous)</p>
</blockquote>
<ul>
<li>한번에 코드 한줄씩 차례로 실행</li>
</ul>
<blockquote>
<p>비동기식처리(Asynchronous)
오래걸리는 작업이 있으면 제껴주고 다른거부터 처리하는 방식
(자바스크립트가 아니라 자바스크립트를 실행하는 브라우저 덕분에 가능한 것 = 웹브라우저의 특수성)</p>
</blockquote>
<p>파이썬에서는</p>
<pre><code class="language-python">print(1)
time.sleep(1) // 1초 쉬어라 =&gt; 1초 멈췄다가 2실행됨(블로킹)
print(2)</code></pre>
<p>자바스크립트에서는</p>
<pre><code class="language-javascript">console.log(1);
setTimeout(()=&gt; {console.log(2)},1000); //멈추지 않고 3이 실행됨
console.log(3);

//setTimeout(()=&gt; {console.log(2)},1000); 비동기식으로 처리 도와주는 함수</code></pre>
<p>setTimeout, eventListener, ajax 코드같이 실행되는데 오래 걸리는 코드들은
Web API라는 공간(실행 대기실)으로 보내서 해결이 되길(시간이 지나길) 기다림.
Web API 덕분에 오래걸리는 작업이 있으면 제껴두고(블로킹이라는 멈추는 과정없이) 다른거부터 처리하는 비동기식 처리가 가능.</p>
<p>자바스크립트는 오래걸리는 연산을 만나면 멈춤 ( = 동기식 처리, synchronous )
Web API와 연관된 특수한 함수들을 쓰면 작업이 오래걸릴 때 정지 없이 다른거부터 실행이 가능( = 비동기식 처리, asynchronous )</p>
<p>하지만, 자바스크립트를 보류했다가 순차적으로 실행하려면? = 콜백함수를 사용함</p>
<pre><code class="language-javascript">console.log(1);
setTimeout(()=&gt; {console.log(2)},1000); //멈추지 않고 3이 실행됨

//()=&gt; {console.log(2)} 콜백함수임</code></pre>
<blockquote>
<p>콜백함수란?
함수안에 함수가 들어간 것.
순차적으로 실행하고 싶을 때, 왼쪽에 있는거 실행하고 나서 실행해줘라는 뜻으로 씀
콜백함수 자체가 동기/비동기처리를 해주는 건 아니고, 함수 디자인 패턴일 뿐</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[🤷🏻‍♀️ 고차함수? 콜백?]]></title>
            <link>https://velog.io/@ohwowo_o/%EA%B3%A0%EC%B0%A8%ED%95%A8%EC%88%98-%EC%BD%9C%EB%B0%B1</link>
            <guid>https://velog.io/@ohwowo_o/%EA%B3%A0%EC%B0%A8%ED%95%A8%EC%88%98-%EC%BD%9C%EB%B0%B1</guid>
            <pubDate>Sat, 07 Jan 2023 13:27:05 GMT</pubDate>
            <description><![CDATA[<h3 id="고차함수">고차함수</h3>
<blockquote>
<p>고차함수란? 함수를 _인자(argument)_로 받을 수 있고, 함수의 형태로 리턴할 수 있는 함수</p>
</blockquote>
<blockquote>
<p>고차 함수는 함수를 인자로 전달받거나 함수를 결과로 반환하는 함수를 말한다.
고차함수는 인자로 받은 함수를 필요한 시점에 호출하거나 _클로저_를 생성하여 반환한다.
자바스크립트의 함수는 일급 객체이므로 값처럼 인자로 전달할 수 있으며 반환할 수도 있다.</p>
</blockquote>
<br />

<p>💡 인자(argument)란?</p>
<ul>
<li>어떤 함수를 호출할때, 호출문의 ( )안에 들어가는 어떤 값이나 변수</li>
</ul>
<p>💡 매개변수란?</p>
<ul>
<li>함수를 정의하면서 그 전달된 인자를 받아들이는 변수</li>
</ul>
<br />

<p>❗️ 인자와 매개변수 예시</p>
<pre><code class="language-javascript">function doubleNum(num) {
  let result = num * 2
  return result
}

doubleNum(2);</code></pre>
<p>✅ 인자는 =&gt; 숫자 2 / 매개변수는 =&gt; num</p>
<br />


<br />

<p>❗️ 고차함수 예시</p>
<ul>
<li>다른 함수를 인자로 받는 경우<pre><code class="language-javascript">function back(num) {
return num * 2;
}
</code></pre>
</li>
</ul>
<p>function doubleNum(func, num) {
  return func(num);
}</p>
<p>doubleNum(back, 5);</p>
<pre><code>

✅ 다른 함수를 인자로 받고 있는 doubleNum은 고차함수임
✅ func는 doubleNum의 콜백함수임
✅ back은 doubleNum의 콜백함수임

&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;

### 콜백함수

&gt;콜백함수란? 다른 함수의 인자로 전달되는 함수
어떤 작업이 완료되었을 때 호출하는 경우가 많아 지어진 이름

&gt;콜백함수란? 순차적으로 함수를 실행하고 싶을 때 사용
콜백함수는 그냥 함수 디자인 패턴일 뿐
동기, 비동기와는 조금 다름

&lt;br /&gt;

❗️ 콜백함수 예시 (1)

```javascript
function 첫째함수(구멍) {
  console.log(1);
  구멍();
}

function 둘째함수() {
  console.log(2);
}

첫째함수(둘째함수);
//console에는 1 2 가 순차적으로 찍힘</code></pre><br />

<p>❗️ 콜백함수 예시 (2)</p>
<pre><code class="language-javascript">function 첫째함수(구멍) {
  console.log(1);
  구멍();
}

function 둘째함수() {
  console.log(2);
}

첫째함수(function(){
  둘째함수(function(){
    셋째함수(function(){

    });
  });
});</code></pre>
<p>패턴의 한계때문에 콜백 지옥이 생김.</p>
<p>💡 가독성 떨어지는 콜백함수의 문제점 =&gt; 더 쉽게 쓰기위한 Promise 함수</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🤷🏻‍♀️ Array? 그게 뭐죠]]></title>
            <link>https://velog.io/@ohwowo_o/Array-%EA%B7%B8%EA%B2%8C-%EB%AD%90%EC%A3%A03</link>
            <guid>https://velog.io/@ohwowo_o/Array-%EA%B7%B8%EA%B2%8C-%EB%AD%90%EC%A3%A03</guid>
            <pubDate>Sat, 07 Jan 2023 13:25:41 GMT</pubDate>
            <description><![CDATA[<h2 id="알다가도-모를-array를-알아보자-✍🏻">알다가도 모를 Array를 알아보자 ✍🏻</h2>
<blockquote>
<p><strong>&quot;모던 자바스크립트 딥다이브&quot;</strong>
배열(array)은 1개의 변수에 여러 개의 값을 순차적으로 저장할 때 사용한다. 자바스크립트의 배열은 객체이며 유용한 내장 메소드를 포함하고 있다.
배열은 Array 생성자로 생성된 Array 타입의 객체이며 프로토타입 객체는 Array.prototype이다.</p>
</blockquote>
<blockquote>
<p><strong>&quot;mdn&quot;</strong>
Array는 JavaScript Array 클래스는 리스트 형태의 고수준 객체인 배열을 생성할 때 사용하는 전역 객체입니다.</p>
</blockquote>
<blockquote>
<p><strong>&quot;코딩애플&quot;</strong>
Array 자료형 : [자료1, 자료2, 자료3...]
자료간 순서가 존재함 (object는 순서 개념 없음)</p>
</blockquote>
<blockquote>
<p><strong>&quot;코어자바스크립트&quot;</strong>
배열 : 특수한 형태의 객체로, 순서가 있는 자료를 저장하고 관리하는 용도에 최적화된 자료구조</p>
</blockquote>
<br />
<br />
<br />


<h2 id="array에서-자주쓰이는-함수">Array에서 자주쓰이는 함수</h2>
<br />
<br />

<h4 id="1-map">1. map</h4>
<ul>
<li>모든 array를 똑같이 변형시킬 수 있음 (판매사이트 구현할때 달러, 원화를 바꿀때 활용할 수 있음) </li>
<li>배열을 변형시키거나 요소를 재 정렬해주는 메서드</li>
</ul>
<pre><code class="language-javascript">const 어레이 = [4,7,9,10,57];

어레이.map(function(a){
  return a * 2
});

console.log(어레이);</code></pre>
<br />

<h4 id="2-filter">2. filter</h4>
<ul>
<li>자료 원하는 것만 필터함 (함수의 반환 값을 true로 만드는 단 하나의 요소만 찾음)</li>
<li>원본을 변형시키지않고 변경된 값을 그자리에 남겨주기때문에 filter()결과는 변수에 저장해서 써야함
( .sort()는 예전문법이라 원본변형시킴 )</li>
</ul>
<pre><code class="language-javascript">const 어레이 = [4,7,9,10,57];

const 새어레이 = 어레이.filter(function(a){
  return a &lt; 4
});

console.log(어레이);</code></pre>
<br />

<h4 id="3-foreach">3. forEach</h4>
<ul>
<li>주어진 함수를 배열 요소 각각에 대해 실행할 수 있게 해줌</li>
<li>인수로 넘겨준 함수의 반환값은 무시됨</li>
</ul>
<pre><code class="language-javascript">[&quot;Bilbo&quot;, &quot;Gandalf&quot;, &quot;Nazgul&quot;].forEach((item, index, array) =&gt; {
  alert(`${item} is at index ${index} in ${array}`);
});</code></pre>
<br />

<h4 id="4-find">4. find</h4>
<ul>
<li>특정 조건에 부합하는 객체를 배열 내에서 찾을 수 있음</li>
</ul>
<pre><code class="language-javascript">let users = [
  {id: 1, name: &quot;jeong&quot;},
  {id: 2, name: &quot;min&quot;},
  {id: 3, name: &quot;miya&quot;}
];

let user = users.find(item =&gt; item.id == 1);

alert(user.name); // jeong</code></pre>
]]></description>
        </item>
    </channel>
</rss>