<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev_marco.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 20 Jun 2022 06:32:51 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev_marco.log</title>
            <url>https://images.velog.io/images/dev_marco/profile/8cd0fbf5-0818-4458-bc2b-f0595bb54559/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev_marco.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev_marco" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[원티드_ 프리온보딩 코스_프론트엔드 에세이]]></title>
            <link>https://velog.io/@dev_marco/%EC%9B%90%ED%8B%B0%EB%93%9C-%ED%94%84%EB%A6%AC%EC%98%A8%EB%B3%B4%EB%94%A9-%EC%BD%94%EC%8A%A4%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%97%90%EC%84%B8%EC%9D%B4</link>
            <guid>https://velog.io/@dev_marco/%EC%9B%90%ED%8B%B0%EB%93%9C-%ED%94%84%EB%A6%AC%EC%98%A8%EB%B3%B4%EB%94%A9-%EC%BD%94%EC%8A%A4%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EC%97%90%EC%84%B8%EC%9D%B4</guid>
            <pubDate>Mon, 20 Jun 2022 06:32:51 GMT</pubDate>
            <description><![CDATA[<h1 id="원티드-프리온보딩-에세이">원티드 프리온보딩 에세이</h1>
<h2 id="프리온보딩-코스에는-참가기업에-지원해야-하는-제도가-있습니다이런제도가-있는-이유">프리온보딩 코스에는 참가기업에 지원해야 하는 제도가 있습니다.이런제도가 있는 이유</h2>
<ul>
<li><p>부트캠프에서는 비전공자가 개발자가 될 수 있도록 공부하는 방법을 가르쳐 주고 있다.</p>
</li>
<li><p>공부하는 방법만 알고 있다고 해서 취업을 할 수 있는 것은 아니다.</p>
</li>
<li><p>혼자서는 스터디의 방향성을 잡기 어렵다.</p>
</li>
<li><p>혼자 하는 것이 아닌 동료학습을 통해 협업하는 능력을 기를 수 있다.</p>
</li>
<li><p>기업과제(케이스 스터디)를 통해 실무에서 사용 할 수 있는 스킬을 습득 할 수 있다.</p>
</li>
<li><p>여러가지의 프로젝트를 통해 다양한 케이스들을 경험 해 볼 수 있다.</p>
</li>
<li><p>위에서 이야기한 내용을 토대로 참가기업에 맞는 프로젝트를 진행하고 업무에 활용 할 수 있는 역량을 기를 수 있다.</p>
</li>
</ul>
<h2 id="지원하고-싶은-기업">지원하고 싶은 기업</h2>
<ul>
<li>트립비토즈<blockquote>
<p>저는 여행을 좋아합니다. 3년전 해외여행중에 급하게 호텔을 예약 할 일이 생겨 트립비토즈를 사용할 때 사용자 친화적인 UI가 기억에 남아있어요.
각 분야에서 전문성을 가진 사람들이 모여 기존의 방식에 도전하며 일하고 있는 트립비토즈에서 여행을 같이 하고 싶어요. 프론트엔드 개발자는 유저의 작은 니즈에서 문제를 발견해 이를 정의하고 해결하는 것이 중요하다고 생각 합니다. 여행은 필연적으로 국경을 넘나들며 트립비토즈 역시 빠른 글로벌 성장을 계획하고 있는 트립비토즈에서 저도 역량을 갖춰나가는 프론트엔드 개발자가 되고 싶습니다. </p>
</blockquote>
</li>
</ul>
<ul>
<li><p>스티비</p>
<blockquote>
<p>스티비 팀은 &#39;좋은 뉴스레터를 더 많은 사람에게&#39; 연결시키기 위해,
• (WHY) 누구나 자신의 구독자와 관계를 쌓을 수 있도록
• (HOW) 간결하고 세심하고 친절한 방식으로
• (WHAT) 콘텐츠를 제작하고 발행하는 도구를 만들고 있습니다.
스티비에서 간결하고 클린한 코드를 만들고 싶어요. 또 스티비에서는 좋은 뉴스를 더 많은 사람에 연결하려는 (why)(how)(what) 를 가지고 있는데 업무환경도 이와 다를바 없다고 생각이 듭니다. 저도 스티비에서 콘텐츠를 제작하고 발행하는 개발자가 되고싶습니다.</p>
</blockquote>
</li>
<li><p>지엔에이컴퍼니</p>
<blockquote>
<p>누구에게나 게임을 플레이 하는 시간은 굉장히 중요 합니다 &#39;게이머의 시간을 의미있게 만들겠다&#39;는 지엔에이컴퍼니의 의견에 찬성합니다. 저도 지엔에이 컴퍼니에서 일을 하면서 저의 개발하며 일하는 시간도 의미있는 시간으로 만들고 싶어요.
저도 지엔에이컴퍼니의 플레이어가 되어 게임과 개발 생태계를 바꾸고 싶습니다.</p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[무한 스크롤(Infinite Scroll)]]></title>
            <link>https://velog.io/@dev_marco/%EB%AC%B4%ED%95%9C-%EC%8A%A4%ED%81%AC%EB%A1%A4Infinite-Scroll</link>
            <guid>https://velog.io/@dev_marco/%EB%AC%B4%ED%95%9C-%EC%8A%A4%ED%81%AC%EB%A1%A4Infinite-Scroll</guid>
            <pubDate>Tue, 17 May 2022 00:49:27 GMT</pubDate>
            <description><![CDATA[<p>전체 데이터를 받아 FrontEnd에서 처리 하는 무한스크롤</p>
<pre><code class="language-js">const [dataList, setDataList] = useState([]);
const [hiddenDataList, setHiddenDataList] = useState([]); //랜더링하기 전 숨겨놓는 데이터(스크롤 할 때마다 -)
const [isLoading, setIsLoading] = useState(true); //무한스크롤 시 카드 로딩</code></pre>
<ul>
<li><p>무한스크롤을 위한 state 값</p>
<pre><code class="language-js">const fetchMoreData = async () =&gt; {
  //카드를 더 추가로 받아오는 함수

  if (hiddenDataList.length !== 0) {
    //안보여준 카드가 남아있을 때만
    setIsLoading(true);
    setTimeout(() =&gt; {
      setDataList([...dataList, ...hiddenDataList.slice(0, 8)]);
      setHiddenDataList(hiddenDataList.slice(8));
      setIsLoading(false);
    }, 700);
  }
};</code></pre>
</li>
<li><p>추가로 상품리스트를 더 가져오는 함수
로딩 상태를 바꿔주는데 타이밍 이슈가 있어<code>setTimeout</code> 으로 
<code>isLoading</code>의 상태를 바뀔 수 있는 시간을 준다.
추후 데이터를 DB에서 바로 받아오면 삭제도 가능 할 듯</p>
<pre><code class="language-js">const infiniteScroll = useCallback(() =&gt; {
  //스크롤 높이 및 정도 감지하여, 조건 만족하면 fetchMoreData 함수 호출
  let scrollHeight = Math.max(
    document.documentElement.scrollHeight,
    document.body.scrollHeight
  );
  let scrollTop = Math.max(
    document.documentElement.scrollTop,
    document.body.scrollTop
  );
  let clientHeight = document.documentElement.clientHeight;
  scrollHeight -= 100;
  if (scrollTop + clientHeight &gt;= scrollHeight &amp;&amp; isLoading === false) {
    fetchMoreData();
  }
}, [isLoading]);</code></pre>
</li>
<li><p>스크롤이벤트를 감지 후 추가데이터를 가져와주는 함수 <code>fetchMoreData</code>를 호출 실행 </p>
<pre><code class="language-js">useEffect(() =&gt; {
  const getFetchData = () =&gt; {
    //페이지&#39;최초&#39; 랜더링때에만 작동
    setIsLoading(true);
    fetch(&#39;http://localhost:3000/data/MockData.json&#39;)
      .then(res =&gt; res.json())
      .then(data =&gt; {
        // setDataList(data); --&gt; 이렇게 다 보여주는 대신에
        setDataList(data.slice(0, 8)); //최초에 8개만 보여주고
        setHiddenDataList(data.slice(8)); //보여준 8개 제외한 나머지만 추려서상태값에 저장
        setIsLoading(false);
      });
  };
  getFetchData();
}, []);</code></pre>
</li>
<li><p>최초 렌더링에서 <code>dataList</code> 에 상품리스트를 채워주는 곳
맨 처음 상품 8개를 보여준다.</p>
<pre><code class="language-js">useEffect(() =&gt; {
  window.addEventListener(&#39;scroll&#39;, infiniteScroll, true); // 스크롤 이벤트 등록
  return () =&gt; window.removeEventListener(&#39;scroll&#39;, infiniteScroll, true); //스크롤 이벤트 삭제(컴포넌트 언마운트시)
}, [infiniteScroll]);</code></pre>
</li>
<li><p>컴포넌트가 마운트 때 스크롤 이벤트 등록!</p>
</li>
<li><p>컴포넌트가 언마운트될 때 스크롤 이벤트 삭제!</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2차 팀프로젝트 세번째]]></title>
            <link>https://velog.io/@dev_marco/2%EC%B0%A8-%ED%8C%80%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%84%B8%EB%B2%88%EC%A7%B8</link>
            <guid>https://velog.io/@dev_marco/2%EC%B0%A8-%ED%8C%80%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%84%B8%EB%B2%88%EC%A7%B8</guid>
            <pubDate>Mon, 16 May 2022 00:30:46 GMT</pubDate>
            <description><![CDATA[<h2 id="do-do">Do do</h2>
<ul>
<li><del>레이아웃 만들기</del></li>
<li><del>컴포넌트화 하기</del></li>
<li><del>한페이지 안에 styled-components 적용하기</del></li>
<li><del>기능 구현 craousel</del></li>
<li><del>mockdata화</del></li>
<li><del>mockdata연결</del></li>
<li><del>category별 필터링</del></li>
<li><del>더보기에서 전체보기 무한스크롤로 변경</del></li>
<li><del>인기순 페이지 구현(랜덤 or 예약순)BE에서 랜덤으로 데이터받기</del></li>
<li><del>식당이름으로 검색하기</del></li>
<li><del>BackEnd와 데이터 통신확인(5월14일 토요일)</del></li>
<li>상품리스트 무한스크롤</li>
<li>로그인 상태에 따른 북마크 추가 및 로그인페이지로 이동</li>
<li>상품카드 클릭시 예약페이지 이동 로직</li>
<li>카테고리 카드에 전체리스트보기 버튼 만들기<h2 id="doing">Doing</h2>
</li>
<li>category별 필터링</li>
<li>식당이름으로 검색하기<h2 id="blocker">Blocker</h2>
<pre><code class="language-js">const [totalData, setTotalData] = useState([]);
const [dataList, setDataList] = useState([]);
const [selectedCategory, setSelectedCategory] = useState(&#39;&#39;);</code></pre>
filter를 할 대상을 상태에 담아놓고 UI에 그려지는 상태를 조작하여 랜더링이 이루어지게 작업을 한다. 카테고리별 필터링에서 이 부분이 헷갈렸다. 헷갈린 이유는 컴포넌트에서 props로 넘기는 과정에서 꼬이기 시작했다.<pre><code class="language-js">const handleCategory = categoryId =&gt; {
  setSelectedCategory(categoryId);
  setDataList(totalData.filter(el =&gt; el.category_id === categoryId));
};</code></pre>
위의 로직을 자식컴포넌트에서 만들려다 보니 props로 넘기는 양이 많아져 기능상의 문제가 생길 가능성이 높아보였다. 그리고 이부분에서 어느 것을 보내고 보내지 말아야 할 지 헷갈렸다.
자식컴포넌트에서 하던 로직을 부모로 옮겨서 함수를 만드니 만들어진 함수만 props로 보내주면 되서 작업이 엄청 수월해졌다.<pre><code class="language-js">const CategoryCard = ({ value, selectedCategory, handleCategory }) =&gt; {
return (
  &lt;StyledCategoryCard
    onClick={() =&gt; {
      handleCategory(value.category_id);
    }}
  &gt;
    &lt;StyledCategoryImg alt=&quot;food&quot; src={value.img} /&gt;
    &lt;StyledTitle isSelected={value.category_id === selectedCategory}&gt;
      {value.title}
    &lt;/StyledTitle&gt;
  &lt;/StyledCategoryCard&gt;
);
};</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2차 프로젝트 세번째]]></title>
            <link>https://velog.io/@dev_marco/2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%84%B8%EB%B2%88%EC%A7%B8</link>
            <guid>https://velog.io/@dev_marco/2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%84%B8%EB%B2%88%EC%A7%B8</guid>
            <pubDate>Fri, 13 May 2022 00:22:30 GMT</pubDate>
            <description><![CDATA[<h2 id="do-do">Do do</h2>
<ul>
<li><del>레이아웃 만들기</del></li>
<li><del>컴포넌트화 하기</del></li>
<li><del>한페이지 안에 styled-components 적용하기</del></li>
<li>기능 구현 <del>craousel</del></li>
<li><del>mockdata화</del></li>
<li><del>mockdata연결</del></li>
<li>category별 필터링</li>
<li>더보기에서 전체보기</li>
<li>인기순 페이지 구현(랜덤 or 예약순)</li>
<li>식당이름으로 검색하기<h2 id="doing">Doing</h2>
</li>
<li>react-slick 사용하여 사용중이나 커스터마이징이 어려움</li>
<li>category별 필터링</li>
<li><del>더보기에서 전체보기
생략예정</del></li>
<li>인기순 페이지 구현(랜덤 or 예약순)</li>
<li>식당이름으로 검색하기</li>
</ul>
<h2 id="blocker">Blocker</h2>
<p>데이터를 props로 내리는 과정에서 첫번째 컴포넌트로는 무사하게 넘겼으나 다음 컴포넌트로는 원하는데로 보내지를 못했다.</p>
<pre><code class="language-js">const Main = () =&gt; {
  const [data, setData] = useState([]);
  const [selectedCategory, setSelectedCategory] = useState(&#39;&#39;);

  useEffect(() =&gt; {
    fetch(&#39;http://localhost:3000/data/MockData.json&#39;)
      .then(res =&gt; res.json())
      .then(data =&gt; {
        setData(data);
      });
  }, []);</code></pre>
<p>  데이터를 <code>fetch</code>하여 가져온 후 <code>useState</code>로 배열에 담아 놓는다.</p>
<pre><code class="language-js">return (
    &lt;StyledMain&gt;
      &lt;StyledBannerWrap&gt;
        &lt;StyledVideo&gt; 동영상 &lt;/StyledVideo&gt;
        &lt;StyledCarousel&gt;
          &lt;CarouselBanner /&gt;
        &lt;/StyledCarousel&gt;
      &lt;/StyledBannerWrap&gt;
      &lt;StyledSearchBar&gt;
        &lt;StyledInput type=&quot;search&quot; placeholder=&quot;🔍️ &amp;nbsp; 오늘의집 통합검색&quot; /&gt;
      &lt;/StyledSearchBar&gt;
      &lt;StyledRecommendCarousel&gt;
        &lt;RecommendFoodCarousel data={data} /&gt;
      &lt;/StyledRecommendCarousel&gt;
      &lt;StyledFoodCategory&gt;
        {categoryInfo.map((value, i) =&gt; (
          &lt;CategoryCard
            key={i}
            value={value}
            selectedCategory={selectedCategory}
            setSelectedCategory={setSelectedCategory}
          /&gt;
        ))}
      &lt;/StyledFoodCategory&gt;
      &lt;CategoryRestaurantList data={data} /&gt;
    &lt;/StyledMain&gt;
  );</code></pre>
<p><code>&lt;CategoryRestaurantList data={data} /&gt;</code> 보내고 싶은 컴포넌트에 props로 내려 준 후 <code>data={data}</code>
이 데이터를 다음 컴포넌트에서 map해준다.</p>
<pre><code class="language-js">const CategoryRestaurantList = ({ data }) =&gt; {
  return (
    &lt;StyledRecommendCard&gt;
      {data.map((value, i) =&gt; (
        &lt;div key={i} style={{ width: &#39;25%&#39; }}&gt;
          &lt;RecommendFoodCard key={i} value={value} /&gt;
        &lt;/div&gt;
      ))}
    &lt;/StyledRecommendCard&gt;
  );
};</code></pre>
<p><code>({ data })</code> 객체로 받아와야 하는데 처음에 그냥 <code>const CategoryRestaurantList = data  =&gt; {}</code> 이렇게 props로 받아와 원하는 상태로 받아오지 못했다.
<code>{data.map((value, i) =&gt; (
        &lt;div key={i} style={{ width: &#39;25%&#39; }}&gt;
          &lt;RecommendFoodCard key={i} value={value} /&gt;
        &lt;/div&gt;</code></p>
<p>그 다음 그 데이터를 바로 <code>map</code> 해주면 된다. 그 다음 이 데이터를 그대로 다음의 컴포넌트 <code>RecommendFoodCard</code>에 보내주기 위해 객체 하나하나를 <code>value={value}</code> 담아 다음 컴포넌트로 보내준다.
그래야 내가 사용 할 수 있는 객체 하나하나의 형태로 데이터가 넘어오게 된다.
<img src="https://velog.velcdn.com/images/dev_marco/post/8943bd39-2f32-4efe-8cce-4a3b2de0120e/image.png" alt="">
그 다음으로 객체의 key를 사용해주면 된다.</p>
<pre><code class="language-js">const RecommendFoodCard = ({ value }) =&gt; {
  const [isBookMark, setIsBookMark] = useState(false);
  console.log(value);
  return (
    &lt;StyledRecommend&gt;
      &lt;StyledRecommendCard&gt;
        &lt;StyledRecommendCardImg art=&quot;restaurant&quot; src={value.thumbnail_image} /&gt;
        {isBookMark ? (
          &lt;i
            onClick={() =&gt; setIsBookMark(!isBookMark)}
            className=&quot;fa-solid fa-bookmark&quot;
          /&gt;
        ) : (
          &lt;i
            onClick={() =&gt; setIsBookMark(!isBookMark)}
            className=&quot;fa-regular fa-bookmark&quot;
          /&gt;
        )}
      &lt;/StyledRecommendCard&gt;
      &lt;StyledRestaurant&gt;{value.name}&lt;/StyledRestaurant&gt;
      &lt;StyledRestaurantMenu&gt;{value.address}&lt;/StyledRestaurantMenu&gt;
    &lt;/StyledRecommend&gt;
  );
};</code></pre>
<p><code>({ value })</code> props로 받아오고 원하는 위치에서
<code>&lt;StyledRecommendCardImg art=&quot;restaurant&quot; src={value.thumbnail_image} /&gt;</code> 객체의 이미지
<code>&lt;StyledRestaurant&gt;{value.name}&lt;/StyledRestaurant&gt;
      &lt;StyledRestaurantMenu&gt;{value.address}</code>주소와 이름 같은 형식으로 사용 해주면 된다. 데이터가 넘어 올 때 마다 객체인지 배열인지를 정확히 확인하고 사용해야 한다. 다시한번 디버깅의 중요성을 알게되었다.</p>
<h2 id="1주차-느낀-점">1주차 느낀 점</h2>
<ul>
<li>1차 프로젝트보다는 시간이 단축 되었다</li>
<li>1차 때 사용했던 스킬들이 온전히 내 것이 아니었다. 알고 쓴게 아니라 그냥 가져다 쓰기만 한 느낌 온전한 내것으로 만들어야 겠다.</li>
<li>새로운 스킬을 계속 배우고 있지만 아직 적용해본것이 몇가지 없다. 완성 후 절대적으로 리펙토링이 필요하다.</li>
<li>1차 때보다는 확실이 코드들이 눈에 들어고 데이터가 어디에서 어디로 넘어가는지 조금은 더 알게 되었다.</li>
<li>부족한 부분들이 보이기 시작하니 어디를 공부해야 할지 알게 되는 것 같다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2차 프로젝트 진행중]]></title>
            <link>https://velog.io/@dev_marco/2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%A7%84%ED%96%89%EC%A4%91</link>
            <guid>https://velog.io/@dev_marco/2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%A7%84%ED%96%89%EC%A4%91</guid>
            <pubDate>Thu, 12 May 2022 01:08:41 GMT</pubDate>
            <description><![CDATA[<h2 id="do-do">Do do</h2>
<ul>
<li><del>레이아웃 만들기</del></li>
<li><del>컴포넌트화 하기</del></li>
<li><del>한페이지 안에 styled-components 적용하기</del></li>
<li>기능 구현 craousel, category별 필터링, 더보기에서 전체보기</li>
<li>인기순 페이지 구현(랜덤 or 예약순)</li>
</ul>
<h2 id="doing">Doing</h2>
<ul>
<li>기능 구현 craousel 
react-slick 사용하여 사용중이나 커스터마이징이 어려움</li>
<li>category별 필터링</li>
<li>더보기에서 전체보기
생략예정</li>
<li>인기순 페이지 구현(랜덤 or 예약순)</li>
<li>mockdata화</li>
</ul>
<h2 id="blocker">Blocker</h2>
<pre><code class="language-js"> return (
    &lt;StyledRecommendCard&gt;
      {restaurantList.map((value, i) =&gt; (
        &lt;div key={i} style={{ width: &#39;25%&#39; }}&gt;
          &lt;RecommendFoodCard key={i} value={value} /&gt;
        &lt;/div&gt;
      ))}
    &lt;/StyledRecommendCard&gt;
  );</code></pre>
<p>map을 tag로 상위에서 감싸는 바람에 원치않는 사이즈가 계속 활성화 되었다.</p>
<pre><code class="language-css">const StyledRecommendCard = styled.div`
  display: flex;
  flex-wrap: wrap;
`;</code></pre>
<p>상위 요소에서 포지션속성을 줘야 한다.</p>
<p>Bookmark 버튼 만들기
처음에는 바탕이 있는 버튼으로 컬러만 바꾸는 방식으로 했으나 ui에서 가독성이 떨어지는 바람에 
테두리만 있는 버튼에서 바탕이 있는 버튼으로 바꾸는 디자인으로 변경하였다.</p>
<pre><code class="language-js">{isBookMark ? (
          &lt;i
            onClick={() =&gt; setIsBookMark(!isBookMark)}
            className=&quot;fa-solid fa-bookmark&quot;
          /&gt;
        ) : (
          &lt;i
            onClick={() =&gt; setIsBookMark(!isBookMark)}
            className=&quot;fa-regular fa-bookmark&quot;
          /&gt;
        )}</code></pre>
<pre><code class="language-css">const StyledRecommendCard = styled.div`
  position: relative;
  margin: 0 10px;

  .fa-bookmark {
    position: absolute;
    bottom: 15px;
    right: 15px;
    font-size: 20px;
    cursor: pointer;
  }

  .fa-regular {
    color: white;
  }

  .fa-solid {
    color: #36c5ef;
  }
`;</code></pre>
<p>내가 만들기 편한코드보다 사용자 입장에서 한번더 생각해 볼 필요가 있다고 생각했다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2차 프로젝트]]></title>
            <link>https://velog.io/@dev_marco/2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@dev_marco/2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Wed, 11 May 2022 00:29:52 GMT</pubDate>
            <description><![CDATA[<h2 id="to-do">To do</h2>
<ul>
<li>레이아웃 만들기</li>
<li>컴포넌트화 하기</li>
<li>한페이지 안에 styled-components 적용하기</li>
<li>기능 구현 craousel, category별 필터링, 더보기에서 전체보기</li>
<li>인기순 페이지 구현(랜덤 or 예약순)</li>
</ul>
<h2 id="doing">Doing</h2>
<ul>
<li>레이아웃</li>
<li>컴포넌트화</li>
<li>styled-components 적용</li>
</ul>
<h2 id="blocker">Blocker</h2>
<ul>
<li>Craousel 라이브러리 적용
slick 라이브러리 설치 후 불러 오는 것 까지 성공했으나 원하는 위치에 원하는 사이즈를 주지 못했다.
메인파일에서 작업을 해줘야 할 지 carousel이 사용되어지는 컴포넌트에서 사용 해야하는지에 대한 고민이 있었다. 메인에 사용하면 바로 나오나 메인파일이 가독성이 안좋아지기 때문에 컴포넌트에서 작업 하는 것으로 결정했다. 얕은 지식으로 인해 export는 한 파일에서 한번 만 되는 것으로 기억하고 있어 어떡케 풀어 나가야 할 지 고민이었다. 현업에서 실제로 사용되어지는 코드를 보고 조금 이해 하게 되었다.<pre><code class="language-js">const CarouselBanner = () =&gt; {
const settings = {
  dots: true,
  infinite: true,
  speed: 500,
  slidesToShow: 1,
  slidesToScroll: 1,
};
return (
  &lt;Slider {...settings}&gt;
    &lt;div&gt;
      &lt;h3&gt;1&lt;/h3&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;h3&gt;2&lt;/h3&gt;
    &lt;/div&gt;
    &lt;div&gt;
      &lt;h3&gt;3&lt;/h3&gt;
    &lt;/div&gt;
  &lt;/Slider&gt;
);
};
</code></pre>
</li>
</ul>
<p>const StyledNext = styled.span<code>position: absolute;
  right: 0;
  top: 50%;</code>;</p>
<p>const StyledPrev = styled.span<code>position: absolute;
  left: 0;
  top: 50%;</code>;</p>
<p>export default CarouselBanner;</p>
<p>```</p>
<p>컴포넌트자체를 carousel 자체로 만드는 방법이 있었다. 만들어 놓은 레이아웃을 활용하려던 생각 자체가 다음 스텝으로 넘어가는데 방해하는 요소였다.
이제 다음 스텝으로 들어갈 이미지추가와 여러 장을 한번에 보여주는 속성과 버튼의 위치를 조정해주는 작업을 하면 된다.
carousel을 넣을 태그를 만들어 준 후 그 안에 carousel이 들어 가도록 해주면 된다. width값을 줘야 원하는 사이즈를 줄 수가 있다.
한가지만 알고 있는 것이 정말 무섭다. 여러가지를 접해보고 필요한 상황에 맞게 정제해 사용하는 능력을 길러줘야 겠다.</p>
<h2 id="해야-할-작업">해야 할 작업</h2>
<ul>
<li>carousel 스타일링</li>
<li>퍼블리싱하기</li>
<li>최대한 오늘의 집 비슷하게 스타일링 하기
오늘안에 최대한 만들어야 이번주 안에 기능구현까지 가능하다!</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Styled-components]]></title>
            <link>https://velog.io/@dev_marco/Styled-components</link>
            <guid>https://velog.io/@dev_marco/Styled-components</guid>
            <pubDate>Mon, 09 May 2022 23:58:47 GMT</pubDate>
            <description><![CDATA[<h2 id="사용법">사용법</h2>
<ul>
<li>html tag와 className 대신에 변수로 만들어 사용 할 수 있다.
<img src="https://velog.velcdn.com/images/dev_marco/post/9ca22844-df03-4839-8d55-8f0b28d8f62c/image.png" alt="">
tag와 className    대신
<img src="https://velog.velcdn.com/images/dev_marco/post/e3a415a4-dd25-480b-bae6-6547ad12b894/image.png" alt=""></li>
</ul>
<p>변수명을 사용 할 수 있다.</p>
<ul>
<li>컴포넌트화 된다면 따로 파일을 만들 필요가 없다.
또 상태의 변화의 따라 값을 다르게 주기가 편리하다.
<img src="https://velog.velcdn.com/images/dev_marco/post/1f8c21d5-3d91-4dcc-a4bd-1b36d04dd5a2/image.png" alt="">
설치가 되어 있다면 자동으로 import된다.<img src="https://velog.velcdn.com/images/dev_marco/post/c15d3070-f1bb-4e68-b866-ab28a81fa09d/image.png" alt=""></li>
</ul>
<h2 id="장점">장점</h2>
<ul>
<li>한페이지에서 스타일 적용이 가능하여 가독성이 좋아진다.</li>
<li>css파일을 따로 만들지 않기 때문에 속도가 빠르다.</li>
<li>두가지의 속성을 3항을 사용하여 관리하기가 편리하다.</li>
<li>다른 js파일에 css속성의 영향을 주지 않는다</li>
</ul>
<h2 id="단점">단점</h2>
<ul>
<li>스타일의 양이 많아지면 파일안에서 가독성이 떨어 질수 있다.</li>
<li>굳이 파일을 나누다면 css와 다른 점을 가질수 있을까?</li>
<li>className 작명이 아닌 변수명 작명에서도 어려움을 느낄 것 같다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[1차 프로젝트 회고록]]></title>
            <link>https://velog.io/@dev_marco/1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@dev_marco/1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Sun, 08 May 2022 04:31:57 GMT</pubDate>
            <description><![CDATA[<h2 id="작업내용">작업내용</h2>
<ul>
<li>술담화 웹페이지 클론코딩</li>
<li>nav바, footer, 스토어페이지</li>
<li>pm역할</li>
<li>팀원 FE 4명, BE 2명</li>
</ul>
<h3 id="잘한-점">잘한 점</h3>
<ul>
<li>클론코딩의 목적의 맞게 끔 최대한 비슷하게 만듬</li>
<li>개인이 맡은 페이지를 기간내에 만들어 냄</li>
<li>전체적인 미팅과 내용의 조율을 잘함</li>
<li>각각의 성향에 맞는 페이지 분배</li>
<li>시간에 맞는 스케쥴 조절</li>
<li>매일매일 스탠드업 미팅 진행</li>
</ul>
<h3 id="아쉬운-점">아쉬운 점</h3>
<ul>
<li>전역에서 관리되어 질 부분과 지역에서 관리 될 부분을 따로 나누지 않음</li>
<li>토큰유무 로그인 상태를 관리하지 못함 전역에서 관리 할 부분의 담당을 따로 지정하지 못함</li>
<li>각각의 페이지의 타임라인이 없어서 전체적인 스케쥴이 늘어지는 느낌이었음</li>
<li>연관 되어 지는 페이지를 한 사람이 맞게 해야 하는데 따로 따로 나누는 바람에 한사람이 관리 해야 할 부분을 여러사람이 담당하게 되어버려 원할한 작업이 이루어지지 않음</li>
<li>스탠드업 미팅은 하루에 한번으로 부족함</li>
</ul>
<h3 id="새로-배운-점">새로 배운 점</h3>
<ul>
<li>트렐로, 슬랙, Git의 활용방법을 숙지 하게 됨 각각의 장점과 아쉬운 점을 알게 되어 추가로 사용 해야 할 툴의 필요성을 알게 됨</li>
<li>merge가 된 후의 작업과 각자의 작업 페이지이 구분을 지을 수 있게 됨</li>
<li>협업에서는 소통이 엄청 필요하다는 것을 알게 됨 협업에서는 절대 혼자만 생각하고 혼자만 알고 있으면 안됨</li>
<li>라이브러리가 왜 필요한 지 알게 됨</li>
<li>컴포넌트의 깊이가 깊어 질 수록 props에서 타이밍 이슈가 발 생된다는 것을 알게 됨</li>
</ul>
<h3 id="다음-프로젝트에서-해보고-싶은-일">다음 프로젝트에서 해보고 싶은 일</h3>
<ul>
<li>리덕스 라이브러리 사용(바로 되지 않는 다면 리펙토링 할 때)</li>
<li>전역에서 관리 되어야 할 부분 나누기</li>
<li>각각의 페이지 마다 타임라인 부여하기</li>
</ul>
<h3 id="느낀-점">느낀 점</h3>
<ul>
<li>팀프로젝트는 절대 혼자 하는 것이 아니다. 모르면 다른 팀원에게 피해주지 않도록 자기주도 학습을 해야 하고 다른 팀원들보다 더 알고 있다면 나의 지식의 공유를 통해 비슷한 수준으로 올려줘야 할 필요가 있다. 어느 한 페이지의 완성도가 높다고 해서 그 페이지 전체의 완성도가 높은 것은 아니다. 평균을 높여 줘야 하고 프로젝트내에서 진행되어지는 혼자만의 생각은 절대적으로 공유 할 필요가 있다. 프로젝트를 하면서 나에게 부족한 것이 무엇인지 알게 되었고 이로 인해 자기주도학습의 필요성을 더 알게 되었다. 다음 프로젝트에서도 모르는것을 혼자만 알고 있지 말고 알고 있는 것도 혼자만 알고 있지 않으면서 좋은 팀웤으로 프로젝트를 완성해봐야 겠다.
내가 처음에 생각했던 커뮤니케이션에 유연한 개발자가 되도록 더 노력해야겠다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모달 스크롤방지]]></title>
            <link>https://velog.io/@dev_marco/%EB%AA%A8%EB%8B%AC-%EC%8A%A4%ED%81%AC%EB%A1%A4%EB%B0%A9%EC%A7%80</link>
            <guid>https://velog.io/@dev_marco/%EB%AA%A8%EB%8B%AC-%EC%8A%A4%ED%81%AC%EB%A1%A4%EB%B0%A9%EC%A7%80</guid>
            <pubDate>Wed, 04 May 2022 08:34:14 GMT</pubDate>
            <description><![CDATA[<p>모달에서 확인 하기 </p>
<pre><code class="language-js">useEffect(() =&gt; {
    console.log(&#39;mount&#39;)
return () =&gt; console.log(&#39;unmount&#39;)
}, [])</code></pre>
<p>확인
모달이 뜨면 <code>mount</code>
모달이 꺼지면 <code>unmount</code></p>
<pre><code class="language-js">import React, { useEffect } from &#39;react&#39;;

export const Modal = (props) =&gt; {

  // 모달 오버레이에서 스크롤 방지
  useEffect(() =&gt; {
    document.body.style.cssText = `
      position: fixed; 
      top: -${window.scrollY}px;
      overflow-y: scroll;
      width: 100%;`;
    return () =&gt; {
      const scrollY = document.body.style.top;
      document.body.style.cssText = &#39;&#39;;
      window.scrollTo(0, parseInt(scrollY || &#39;0&#39;, 10) * -1);
    };
  }, []);

  return (
    &lt;&gt;
      {isDisplay &amp;&amp; (
        `&lt;Container&gt;
          &lt;ModalOverlay /&gt;
          &lt;ModalWindow /&gt;
        &lt;/Container&gt;`
      )}
    &lt;/&gt;
  );
};</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[리뷰수정사항 습관 들이기]]></title>
            <link>https://velog.io/@dev_marco/%EB%A6%AC%EB%B7%B0%EC%88%98%EC%A0%95%EC%82%AC%ED%95%AD-%EC%8A%B5%EA%B4%80-%EB%93%A4%EC%9D%B4%EA%B8%B0</link>
            <guid>https://velog.io/@dev_marco/%EB%A6%AC%EB%B7%B0%EC%88%98%EC%A0%95%EC%82%AC%ED%95%AD-%EC%8A%B5%EA%B4%80-%EB%93%A4%EC%9D%B4%EA%B8%B0</guid>
            <pubDate>Mon, 02 May 2022 10:07:15 GMT</pubDate>
            <description><![CDATA[<p>자주 하는 행동이지만 습관을 들여야 할 사항이 있다.
최상위 classNamer과 컴포넌트명과 동일하게 하기
예를 들어 컴포넌트명이 <code>Main.js</code>이면 최상위 클래스네임도<code>className=&quot;Main&quot;</code>으로 작명해 같은 파일임을 알아보기 쉽도록 해준다.
무의미한 div로 태그의 깊이가 깊어지지 않도록 주의한다.
동일한 속성을 가지는 class는 동일한 className를 부여해 scss파일의 내용이 쓸모없이 길어지지 가독성을 좋게 해준다. 컴포넌트 안에 또 컴포넌트가 들어가게 될 때 파일의 위치를 컴포넌트 안의 컴포넌트로 넣어준다.
그래야 내가 원하는 곳에서 수정이 가능하고 어느 부분의 컴포넌트인지 가독하기 쉬워진다.</p>
<pre><code class="language-js">const Nav = () =&gt; {
  const [isLogin, setIsLogin] = useState(false);

  return (
    &lt;header className=&quot;Nav&quot;&gt;
      &lt;nav className=&quot;navBar&quot;&gt;
        &lt;Link to=&quot;/&quot; className=&quot;navLogo&quot;&gt;
          &lt;img alt=&quot;logo&quot; src=&quot;/images/logo.jpg&quot; className=&quot;logoImg&quot; /&gt;
        &lt;/Link&gt;
        &lt;div className=&quot;navLogin&quot;&gt;
          &lt;Link to=&quot;subscribe&quot; className=&quot;moveBtn&quot;&gt;
            구독서비스
          &lt;/Link&gt;
          &lt;Link to=&quot;/&quot; className=&quot;moveBtn&quot;&gt;
            담아마켓(스토어)
          &lt;/Link&gt;
          {isLogin ? (
            &lt;div
              onClick={() =&gt; {
                setIsLogin(true);
              }}
              className=&quot;moveBtn&quot;
            &gt;
              로그아웃
            &lt;/div&gt;
          ) : (
            &lt;Link to=&quot;/login&quot; className=&quot;moveBtn&quot;&gt;
              로그인
            &lt;/Link&gt;
          )}

          &lt;Link to=&quot;/cart&quot;&gt;
            &lt;i className=&quot;fa-solid fa-1x fa-cart-shopping&quot; /&gt;
          &lt;/Link&gt;
        &lt;/div&gt;
      &lt;/nav&gt;
    &lt;/header&gt;
  );
};</code></pre>
<pre><code class="language-css">.Nav {
  position: relative;
  display: flex;
  justify-content: center;

  .navBar {
    position: sticky;
    top: 0;
    display: flex;
    justify-content: space-between;
    max-width: 1006px;
    width: 100vw;
    height: 65px;
    padding: 0 30px;
    align-items: center;

    .navLogo {
      display: flex;
      width: 120px;
      align-items: center;
      cursor: pointer;

      .logoImg {
        width: 100%;
      }
    }

    .navLogin {
      display: flex;
      font-size: 16px;
      font-weight: bold;
      align-items: center;

      .moveBtn {
        margin: 0 15px;
        border: none;
        background-color: transparent;
        color: #1b5218;
        font-weight: bold;
        cursor: pointer;
      }

      .fa-cart-shopping {
        color: rgb(163, 175, 163);
        cursor: pointer;
      }
    }
  }
}
</code></pre>
<p>로직은 알아보기 쉽게 변수명도 명확하게 하기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 타입에러 해결하기]]></title>
            <link>https://velog.io/@dev_marco/%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%83%80%EC%9E%85%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@dev_marco/%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%83%80%EC%9E%85%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 30 Apr 2022 15:50:59 GMT</pubDate>
            <description><![CDATA[<p>타이밍 이슈로 인한 랜더링이 올바르게 되지 않아 잘 나오던 UI가 안나오게 되었다.</p>
<pre><code class="language-js">  const getTitle = () =&gt; {
    if (data[0].category === &#39;탁주&#39;) {
      return &#39;술담화 전통주 소믈리에의 이번 탁주 P.I.C.K!&#39;;
    } else if (data[0].category === &#39;약주&#39;) {
      return &#39;술담화 약주약주 소믈리에의 이번 약주 P.I.C.K!&#39;;
    } else if (data[0].category === &#39;청주&#39;) {
      return &#39;술담화 청주청주 소믈리에의 이번 청주 P.I.C.K!&#39;;
    } else if (data[0].category === &#39;증류주&#39;) {
      return &#39;술담화 증류주 소믈리에의 이번 증류주 P.I.C.K!&#39;;
    }
  };</code></pre>
<pre><code class="language-html">return (
    &lt;section ref={ref} className=&quot;mainSojuRecommend&quot;&gt;
      &lt;div className=&quot;sectionContent&quot;&gt;
        &quot;어떤 술을 마실지 고민이라면, 이 술은 어때요?&quot;
      &lt;/div&gt;
      &lt;div className=&quot;sectionSubContent&quot;&gt;{getTitle()}&lt;/div&gt;
      &lt;div className=&quot;viewMore&quot;&gt;더보기 &lt;/div&gt;
      &lt;div className=&quot;sojuCarouselOuter&quot;&gt;
        &lt;div className={`sojuCarouselSet${productCardNum}`}&gt;
          {data.map(value =&gt; (
            &lt;ProductBoxCard key={value.id} data={value} /&gt;
          ))}
        &lt;/div&gt;
      &lt;/div&gt;
      &lt;button
        className={
          data[0]?.category === &#39;탁주&#39; ? &#39;arrowLeftBtnTak&#39; : &#39;arrowLeftBtn&#39;
        }
      &gt;
        &lt;i className=&quot;fa-solid fa-angle-left&quot; onClick={moveCardLeft} /&gt;
      &lt;/button&gt;
      &lt;button
        className={
          data[0]?.category === &#39;탁주&#39; ? &#39;arrowRightBtnTak&#39; : &#39;arrowRightBtn&#39;
        }
      &gt;
        &lt;i className=&quot;fa-solid fa-angle-right&quot; onClick={moveCardRight} /&gt;
      &lt;/button&gt;
      {data[0]?.category === &#39;탁주&#39; &amp;&amp; &lt;SpecialPriceCard /&gt;}
    &lt;/section&gt;
  );
});</code></pre>
<p>ui가 랜더링 되기 전에 data가 넘어오는 바람에 타입에러가 발생되었다.</p>
<pre><code class="language-js">  const getTitle = () =&gt; {
    if (data[0]?.category === &#39;탁주&#39;) {
      return &#39;술담화 전통주 소믈리에의 이번 탁주 P.I.C.K!&#39;;
    } else if (data[0]?.category === &#39;약주&#39;) {
      return &#39;술담화 약주약주 소믈리에의 이번 약주 P.I.C.K!&#39;;
    } else if (data[0]?.category === &#39;청주&#39;) {
      return &#39;술담화 청주청주 소믈리에의 이번 청주 P.I.C.K!&#39;;
    } else if (data[0]?.category === &#39;증류주&#39;) {
      return &#39;술담화 증류주 소믈리에의 이번 증류주 P.I.C.K!&#39;;
    }
    return null;
  };</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[1차  프로젝트 스토어 레이아웃]]></title>
            <link>https://velog.io/@dev_marco/1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%8A%A4%ED%86%A0%EC%96%B4-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83</link>
            <guid>https://velog.io/@dev_marco/1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%8A%A4%ED%86%A0%EC%96%B4-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83</guid>
            <pubDate>Wed, 27 Apr 2022 00:24:48 GMT</pubDate>
            <description><![CDATA[<p>클론코딩  복사본  만들기
화요일 하루동안 스토어페이지 작업을 하였다. 실제 상용화 되어있는  사이트를 클론코딩  하는 것이 쉽지는 않다. 월요일 하루동안 어떤식으로 페이지를  구성 할 것인가 고민을 하고 바로 작업을 시작하였다.눈대중으로만 레이아웃을  구성해봤다. 비슷하게는 만들어 지는게 처음보다 발전된 모습이 보이기 시작했다. 사용해보지 안았던 sass를 적용해서 사용해봤다. 생각보다 편리한 부분이 많기도 했지만 네스팅이 아직 어색하다.</p>
<pre><code class="language-scss">.mainHeader {
  height: 40px;
  background-color: rgb(244, 244, 244);
  .mainHeaderTitle {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    height: 40px;
    max-width: 1006px;
    background-color: transparent;
    margin: 0 auto;
    .mainHeaderMenu {
      cursor: pointer;
      margin: 0 20px;
      font-size: 15px;
      color: rgb(112, 112, 112);
    }
    .mainHeaderMenu:hover {
      color: rgb(244, 187, 95);
      transition: 0.3s;
    }
    .mainSearchBar {
      margin: 0 20px;
      width: 198px;
      height: 25px;
      line-height: 25px;
      border-radius: 4px;
      background-color: rgb(255, 255, 255);
      padding-left: 10px;
      font-size: 11px;
      color: rgb(178, 178, 178);
      display: inline-block;
      vertical-align: middle;
    }
  }
}</code></pre>
<p>가장 큰 장점으로는 부모 자식 형제 태그의 구분이 명확해지기 때문에 원하는 부분을 찾아 가서 수정하는 것이 수월해졌다. 
그렇지만 컨벤션에 맞게 순서를 잡아주는 것은 계속 숙달이 필요할 듯하다. 지금은 작업하는데 급급해 css의 속성들이 뒤죽박죽이기는 하다.</p>
<p>To Do </p>
<ol>
<li>페이지 하단 작업</li>
<li>캐러셀 완성하기</li>
<li>메인페이지 컴포넌트화 하기</li>
<li>리뷰창 작업 시작하기</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[4주차 회고록]]></title>
            <link>https://velog.io/@dev_marco/4%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@dev_marco/4%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Mon, 25 Apr 2022 00:18:22 GMT</pubDate>
            <description><![CDATA[<p>부트캠프 4주차를 지났다. 익숙한 일을 떠나 새로운 일을 시작한다는  것은 쉽지가 않다. 특히 이 개발공부는 러닝커브가 다른 업에 비해 높은 편이다.물론 누구나 할 수 없는 일이기 때문에 선택 한 이유도 있다.
새로운 지식이 들어 올 때마다 앞에서 들어온 지식은 빠져나가는 느낌이 들기도  한다. 4주 동안 배운 것들은 되짚어 보겠다.
첫째주는 <code>html</code>, <code>css</code>, <code>javascript</code> 그리고 웹의 기본이었다. 이 때 까지만 해도 정말 할 만 하다고 생각했다.
그러나 이주차 부터가 진짜였다.인스타그램 클론코딩을 순수자바스크립트로 클론코딩하는 것이었다. 나름 사전스터디 과정에서 할만큼 했다고 생각했는데 새로 만들어 보려니 기억이 나지 않는 부분들이 더 많았다. 내가 재능이 있다고 들었던 생각이 사라지는 부분이었다. 개발공부라는게 손에 익지 않으면 내것이 아니라는 것이 생각이 확 들었다. 나는 천재가 아니기 때문에 한 번 해보고 넘어가는 것은 절대 안되고 여러번 반복 숙지를 해야 하는 것이었다. 
현 상황에서 더 해보고 싶지만 지나가 일들을 복기하는 것은 지금 당장보다 수료를 한 이후에 더 해볼 생각이다. 물론 빨리 취업하는 것도 중요하지만 내가 만들고 싶은 것을 내 마음대로 만들 수 있고 내가 생각하는 바를 코드로 만들어 보고 싶다.
지금도 절대 완벽하게 이해한 부분들은 없다. 그렇지만 모르는 부분이 무엇인지는 점점 더 알아가고 있다. 그래서 처음에 보이지 않더 공부의 방향이 보이기 시작하고 있다.</p>
<ul>
<li>첫번째 영어 타이핑 숙지 하기. 처음보다는 빨라진 느낌이 들지만 아직 멀었다. </li>
<li>두번째 전문용어들 숙지 하기 아예 모르면 찾아보기라도 하는데 어설프게 알 고 있는 것은 알고있는 것이라고 생각하면서 다시 검색해보지 않는다.</li>
<li>세번째 검색 더 잘하기 찾고자 하는 정보를 더 정확하게 검색해야 한다. 용어를 검색 할 때는 블로그글이 먼저가 아니고 항상 mdn공식문서를 먼저 찾아봐야 한다.</li>
<li>영상만 보지 말고 영상에 나온 코드들은 항상 따라해 본다.눈보다 손이 기억하는게 더 기억에 남는다.</li>
<li>모르는 것이 생기면 모르고 넘어가지 말고 무조건 검색 아니면 동기 마지막으로 멘토님에게 물어본다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]Code Kata Week2 Day2 ]]></title>
            <link>https://velog.io/@dev_marco/TILCode-Kata-Week2-Day2</link>
            <guid>https://velog.io/@dev_marco/TILCode-Kata-Week2-Day2</guid>
            <pubDate>Wed, 20 Apr 2022 00:00:05 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p>숫자로 이루어진 배열인 nums를 인자로 전달합니다. 숫자중에서 과반수(majority, more than a half)가 넘은 숫자를 반환해주세요.</p>
<p>예를 들어,</p>
<blockquote>
<p>nums = [3,2,3]
return 3
nums = [2,2,1,1,1,2,2]
return 2</p>
</blockquote>
<p>가정
nums 배열의 길이는 무조건 2개 이상</p>
<blockquote>
<p><code>filter()</code>
메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환합니다.</p>
</blockquote>
<p>처음문제를 보고 딱 떠오르는 점은 배열안에 더 많은 수를 찾는가 였다.그런데 문제를 다시 읽어보고 천천히 풀어보려 하니 배열 길이의 과반수가 넘어야 한다는 중요한 점을 찾게 되었다. 일단 접근한 방법으로는 배열의 요소를 같은 숫자들끼리 모아 몇개가 있는지 비교를 해주는 것이었다.비교를 한 후 더 많은 요소를 nums의 length를 나누기 2를 해서 비교하려고 했으나 중간에 요소들끼리 갯수를 비교하는 로직이 한번 더 들어가기 때문에 <code>filter</code>메서드를 검색해서 찾게 되었다.
메서드의 특징은 조건이 참 일 때만 요소를 배열로 반환해 주는 것이다.그럼 불필요하게 배열의 요소들끼리 비교할 필요가 사라지고 바로 배열의길이와 비교를 해주면 끝나는 것이다.</p>
<pre><code class="language-js">function moreThanHalf(nums) {
  // 여기에 코드를 작성해주세요.
  for(let i=0; i&lt;nums.length; i++){
if(nums.filter( e =&gt; e === nums[i]).length &gt; (nums.length / 2)) {
      return nums[i]
    }
  }
} 
console.log(moreThanHalf([1,1,1,1,3,3,3]))</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]Code kata Week2-Day1 로마자에서 숫자로 바꾸기]]></title>
            <link>https://velog.io/@dev_marco/TILCode-kata-Week2-Day1-%EB%A1%9C%EB%A7%88%EC%9E%90%EC%97%90%EC%84%9C-%EC%88%AB%EC%9E%90%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0</link>
            <guid>https://velog.io/@dev_marco/TILCode-kata-Week2-Day1-%EB%A1%9C%EB%A7%88%EC%9E%90%EC%97%90%EC%84%9C-%EC%88%AB%EC%9E%90%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0</guid>
            <pubDate>Tue, 19 Apr 2022 00:20:08 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="문제">문제</h2>
<p>로마자에서 숫자로 바꾸기
1~3999 사이의 로마자 s를 인자로 주면 그에 해당하는 숫자를 반환해주세요. 로마 숫자를 숫자로 표기하면 다음과 같습니다.
Symbol&amp;nbsp&amp;nbsp&amp;nbsp &amp;nbspValue
I &amp;nbsp&amp;nbsp&amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp  1
V &amp;nbsp&amp;nbsp&amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp  5
X &amp;nbsp&amp;nbsp&amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp 10
L &amp;nbsp&amp;nbsp&amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp 50
C&amp;nbsp&amp;nbsp&amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp 100
D&amp;nbsp&amp;nbsp&amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp 500
M&amp;nbsp&amp;nbsp&amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp &amp;nbsp1000
로마자를 숫자로 읽는 방법은 로마자를 왼쪽부터 차례대로 더하면 됩니다. III = 3 XII = 12 XXVII = 27 입니다.
그런데 4를 표현할 때는 IIII가 아니라 IV 입니다. 뒤의 숫자에서 앞의 숫자를 빼주면 됩니다. 9는 IX입니다.
I는 V와 X앞에 와서 4, 9 X는 L, C앞에 와서 40, 90 C는 D, M앞에 와서 400, 900</p>
</blockquote>
<p>단순하게 로마자를 숫자로 바꾸는 로직이 필요하였다. 그러나 문제에서 두가지의 예외의 경우가 존재한다. 첫번째는 4, 두번째는 9의 표현이다.</p>
<pre><code class="language-js">function romanToNum(s) {
  // 여기에 코드를 작성해주세요.
   const Roma = {
I   :    1,
V   :   5,
X   :   10,
L   :    50,
C    :   100,
D    :   500,
M    :   1000,
}
  const romArr= s.split(&#39;&#39;);
  const numArr = romArr.map(el =&gt; Roma[el]);
  let sum=0;
  for(let i=0 ;i &lt; numArr.length ;i++) {
    if(numArr[i] &lt; numArr[i+1]) {
      sum = sum-numArr[i];
    } else {
      sum = sum + numArr[i];
    }  ;
  }
  return sum;
}</code></pre>
<p>앞 숫자가 뒷 숫자보다 작을 때를 찾기 위해 반복문을 사용하였다.
앞 숫자가 뒷 숫자보다 작을 때 result에 담아놓은 수에서 앞 숫자를 빼주면 4,9를 표현 할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Mock Data 연결]]></title>
            <link>https://velog.io/@dev_marco/Mock-Data-%EC%97%B0%EA%B2%B0</link>
            <guid>https://velog.io/@dev_marco/Mock-Data-%EC%97%B0%EA%B2%B0</guid>
            <pubDate>Tue, 19 Apr 2022 00:04:06 GMT</pubDate>
            <description><![CDATA[<p>public에 mock data파일을 만들어 접속해 사용 할 수 있다.
public폴더에 commentData.json파일을 만들어 놓고 </p>
<blockquote>
</blockquote>
<p>useEffect(() =&gt; {
    fetch(&#39;<a href="http://localhost:3000/data/commentData.json&#39;">http://localhost:3000/data/commentData.json&#39;</a>, {
      method: &#39;GET&#39;,
    })
      .then(res =&gt; res.json())
      .then(data =&gt; {
        setCommentsList(data);
      });
  }, []);</p>
<p>위와 같은 문법으로 가지고 올 수 있다. 바로 연결을 하는 것이 아니라 </p>
<blockquote>
<p><code>fetch</code>
자바스크립트를 사용하면 필요할 때 서버에 네트워크 요청을 보내고 새로운 정보를 받아오는 일을 할 수 있습니다.</p>
</blockquote>
<ul>
<li>주문 전송</li>
<li>사용자 정보 읽기</li>
<li>서버에서 최신 변경분 가져오기</li>
<li>등등</li>
</ul>
<p>를 사용 하여 연결을 해준다 가져와야 하는 정보에 따라 method의 내용이 달라진다 지금은 데이터를 읽고 가져오기만 하면 되기 때문에
<code>GET</code>을 사용 하였다.</p>
<blockquote>
<p><code>GET</code>
GET 메소드는 주로 데이터를 읽거나(Read) 검색(Retrieve)할 때에 사용되는 메소드이다. 만약에 GET요청이 성공적으로 이루어진다면 XML이나 JSON과 함께 200 (Ok) HTTP 응답 코드를 리턴한다. 에러가 발생하면 주로 404 (Not found) 에러나 400 (Bad request) 에러가 발생한다.
출처: <a href="https://im-developer.tistory.com/166">https://im-developer.tistory.com/166</a> [Code Playground]</p>
</blockquote>
<h4 id="메서드들은-다음-블로그를-참고-하자">메서드들은 다음 블로그를 참고 하자</h4>
<p><a href="https://velog.io/@yh20studio/CS-Http-Method-%EB%9E%80-GET-POST-PUT-DELETE">HTTP method</a></p>
<blockquote>
<p>1.then() 메서드는 Promise를 리턴하고 두개의 콜백 함수를 인수로 받습니다. 이때, 인수로 들어온 콜백함수의 리턴값이 promise객체일 때, then()이 콜백함수의 리턴값인 promise객체를 받습니다.</p>
</blockquote>
<p>useEffect는 한번만 실행 되면 되기 때문에 함수의 끝에 []를 넣어준다.</p>
<p>다 연결한 후 내가 만들어 놓은 데이터 객체의 key들을 mockdata와 동일 하게 만들어 준다.</p>
<p>다음 작업은</p>
<ol>
<li>메인피드 컴포넌트화 하기</li>
<li>메인피드 목데이터 만들어서 연결하기</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[React 댓글 추가, 삭제]]></title>
            <link>https://velog.io/@dev_marco/React-%EB%8C%93%EA%B8%80-%EC%B6%94%EA%B0%80-%EC%82%AD%EC%A0%9C</link>
            <guid>https://velog.io/@dev_marco/React-%EB%8C%93%EA%B8%80-%EC%B6%94%EA%B0%80-%EC%82%AD%EC%A0%9C</guid>
            <pubDate>Mon, 18 Apr 2022 00:12:46 GMT</pubDate>
            <description><![CDATA[<p>reac에서 아주 중요한 부분의 깨달음을 얻게 된 부분이 있었다.순수 자바스크립트와 가장 큰 차이가  자동렌더가  가능한 것이다.
그러므로 새로 랜더를 시킬 때 원본 배열에 바로 푸쉬를 하는 것이 아닌 새로운  배열을 복사해 복사 된 배열에만 내용을 추가하면 되는 것이었다.
그 중 하나가 <code>구조분해할당(...변수)</code>   </p>
<h2 id="구조분해할당">구조분해할당</h2>
<p>mdn에서 말하는 의미로는 </p>
<blockquote>
<p>구조분해할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.</p>
</blockquote>
<p>어렵다. 쉽게 풀어보자면 새로운 복사본을 만들는데 배열에서가 아닌 전부를 분해 따로따로 사용도 가능하고 전체를 다시 복사 할 수도 있다.
아래 코드에서 사용되어 진 예시로는</p>
<blockquote>
<p>const newCommentData = [
      ...commentsList,
      {
        id: Math.floor(Math.random() * 100),
        userId: &#39;jonghyeok&#39;,
        text: newComment,
        isLiked: false,
        createdAt: &#39;16분전&#39;,
      },
    ];
    setCommentsList(newCommentData);
    setNewComment(&#39;&#39;);
  };</p>
</blockquote>
<blockquote>
<pre><code>const handleDelete = id =&gt; {
const index = commentsList.findIndex(value =&gt; value.id === id);
const deleteCommentList = [
  ...commentsList.slice(0, index),
  ...commentsList.slice(index + 1),
];
setCommentsList(deleteCommentList);</code></pre><p>  };</p>
</blockquote>
<blockquote>
<p>  const handleLike = id =&gt; {
    const index = commentsList.findIndex(value =&gt; value.id === id);
    const isLikedCommentList = [...commentsList];
    if (isLikedCommentList[index].isLiked === true) {
      isLikedCommentList[index].isLiked = false;
    } else {
      isLikedCommentList[index].isLiked = true;
    }
    setCommentsList(isLikedCommentList);
  };</p>
</blockquote>
<h1 id="findindex">findIndex()</h1>
<blockquote>
<p>주어진 판별 함수를 만족하는 배열의 첫 번째 요소에 대한 인덱스를 반환합니다.만족하는 요소가 없으면 -1을 반환합니다.</p>
</blockquote>
<p>댓글 추가, 삭제, 좋아요 버튼에 필요한 메서드이다.</p>
<p>새로운 배열을 만들어 리액트에서 자동으로 렌더링이 가능하게 만들어 주는 것이다.<code>push</code> <code>splice</code> 로는 자동으로 렌더링을 가능하게 할 수가 없다. 댓글 하나의 덩어리는 텍스트로만 이루어진 것이 아니고 여러 요소를 가지고 있는 배열 안의 객체로 이루어져있다.이 말인 즉슨 내가 원하는 댓글만 지우기 위해서는 지우고 싶은 배열안의 객체 즉 인덱스에 접근을 해야 한다는 말이다. 그러기 위해서는 댓글이 추가 될 때마다 각각의 댓글마다 <code>고유한ID</code>를 제공해 주어야 한다.그래서 이 아이디와 클릭이벤트가 발생한 아이디를 비교하여 같은 아이디를 가지고 있을 때만 삭제가 가능하도록 하는 것이다.작성된 코드를 보면</p>
<blockquote>
<p>const handleDelete = id =&gt; {
    const index = commentsList.findIndex(value =&gt; value.id === id);
    const deleteCommentList = [
      ...commentsList.slice(0, index),
      ...commentsList.slice(index + 1),
    ];
    setCommentsList(deleteCommentList);
  };</p>
</blockquote>
<p>삭제하기 원하는 댓글에서 클릭이벤트가 일어날 때 삭제 버튼이 클릭되어지는 <code>고유한id</code>와 삭제가 되어지는 댓글의 <code>고유한id</code>가 같을 때만 삭제 이벤트가 발생을 한다. 여기서 중요한 부분은 내가 원하는 인덱스만 삭제가 되어져야 한다는 것이다.내가 원하는 인덱스를 삭제하기 위해서는 지워질 인덱스를 찾고 그 앞에 있는 인덱스 그리고 그 뒤에 나오는 인덱스들을 <code>구조분해할당</code>하여 앞, 뒤에 인덱스를 합쳐 새로운 배열을 만들어 준다!    </p>
<pre><code class="language-js">const newCommentData = [
      ...commentsList,
      {
        id: Math.floor(Math.random() * 100),
        userId: &#39;jonghyeok&#39;,
        text: newComment,
        isLiked: false,
        createdAt: &#39;16분전&#39;,
      },
    ];
    setCommentsList(newCommentData);
    setNewComment(&#39;&#39;);
  };

  const handleCommentEnter = e =&gt; {
    if (e.key === &#39;Enter&#39;) {
      addComment();
    }
  };

  const handleDelete = id =&gt; {
    const index = commentsList.findIndex(value =&gt; value.id === id);
    const deleteCommentList = [
      ...commentsList.slice(0, index),
      ...commentsList.slice(index + 1),
    ];
    setCommentsList(deleteCommentList);
  };

  const handleMainLike = () =&gt; {
    if (mainLike === true) {
      setMainLike(false);
    } else {
      setMainLike(true);
    }
  };

  const handleLike = id =&gt; {
    const index = commentsList.findIndex(value =&gt; value.id === id);
    const isLikedCommentList = [...commentsList];
    if (isLikedCommentList[index].isLiked === true) {
      isLikedCommentList[index].isLiked = false;
    } else {
      isLikedCommentList[index].isLiked = true;
    }
    setCommentsList(isLikedCommentList);
  };</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]Code Kata Day4]]></title>
            <link>https://velog.io/@dev_marco/TILCode-Kata-Day4</link>
            <guid>https://velog.io/@dev_marco/TILCode-Kata-Day4</guid>
            <pubDate>Thu, 14 Apr 2022 23:57:13 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>숫자인 num을 인자로 넘겨주면, 뒤집은 모양이 num과 똑같은지 여부를 반환해주세요.
num: 숫자 return: true or false (뒤집은 모양이 num와 똑같은지 여부)
예를 들어, num = 123 return false =&gt; 뒤집은 모양이 321 이기 때문
num = 1221 return true =&gt; 뒤집은 모양이 1221 이기 때문
num = -121 return false =&gt; 뒤집은 모양이 121- 이기 때문
num = 10 return false =&gt; 뒤집은 모양이 01 이기 때문</p>
</blockquote>
<p>문제를 보고 두번째 문제와 굉장히 유사하다는 생각이 들었다. 먼저 접근한 방법으로는 숫자를 문자열로 만들고 리버스를 해서 if문을 사용하려고 했다. 첫 코드를 작성하고 체크를 해보니 2문제만 통과가 되고 나머지 문제는 통과가 되지 않는 것이었다.검색을 해서 이유를 찾아내게 되었다. 이유는 넘버는 넘버와 비교를 해야하고 스트링은 스트링과 비교를 해야 하는 것이었다. <code>num</code>에서 전달 받은 인자는 넘버타입이고 내가 리버스를 해준 값은 스트링타입이라 둘의 <code>===</code>같다는 연산자는 절대 성립이 불가능했다. 또 굳이 <code>if 문</code> 을 사용해서 블리언타입을 가져올 필요없이 바로 들어온 인자와 리버스한 인자를 비교하면 되는 것이었다.</p>
<blockquote>
<p>const sameReverse = num =&gt; {
  return num===Number(num.toString().split(&#39;&#39;).reverse().join(&#39;&#39;))
}</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL]Code Kata Day2]]></title>
            <link>https://velog.io/@dev_marco/TILCode-Kata-Day2</link>
            <guid>https://velog.io/@dev_marco/TILCode-Kata-Day2</guid>
            <pubDate>Wed, 13 Apr 2022 00:08:39 GMT</pubDate>
            <description><![CDATA[<p>문제</p>
<blockquote>
</blockquote>
<p>reverse 함수에 정수인 숫자를 인자로 받습니다. 그 숫자를 뒤집어서 return해주세요.
x: 숫자 return: 뒤집어진 숫자를 반환!
예들 들어, x: 1234 return: 4321
x: -1234 return: -4321
x: 1230 return: 321</p>
<p>문제를 보고 처음 들었던 생각은 들어온 숫자를 스트링으로 바꿔주는 메서드를 사용해서 배열로 다시 담은뒤 반복문을 사용하고 반복문을 역을로 돌려서 자리를 바꾼 뒤 다시 배열에 담은 뒤에 음수로 들어온 인자는 곱하기-1을하고 양수로 들어온 인자는 들어온데로 배열만 역으로 바꿔서 출력을 할려고 했었다.
그런데 개인적으로 반복문을 여러번 사용하는 로직은 약간의 거부감이 들기 때문에 (사용하는데 아직 어려움) 다른 메서드들을 찾아보았다</p>
<pre><code class="language-js">const reverse = x =&gt; {
  // 여기에 코드를 작성해주세요.
 let array = Math.abs(x).toString().split(&quot;&quot;);
 // 음수를 양수로 전환, 스트링으로 전환, 쪼개기
 let result = array.reverse().join(&quot;&quot;);
 // 뒤집고, 합치기
  return (x &gt;= 0) ? result * 1 : result * -1;
  //x가 0보다 크면 그대로, 반대면 *-1(음수는 음수로 반환)
}
console.log(reverse(1234))</code></pre>
<p>위에 나온 결과가 최종 코드이다.더 좋은 방법도 많겠지만 한번 코드를 설명해보면 </p>
<blockquote>
<p><code>Math.abs()</code> 함수는 주어진 숫자의 절대값을 반환합니다. <code>x</code>가 양수이거나 0이라면 <code>x</code>를 리턴하고, <code>x</code>가 음수라면 <code>x</code>의 반대값, 즉 양수를 반환합니다.(출처 mdn)</p>
</blockquote>
<p>이 메서드를 사용해 전부 양수로 전환을 시켜버렸다.그 뒤에 순서를 바꾸기 위해 문자열로 전환하는 <code>toString()</code>메서드를 사용하고 <code>split(&quot;&quot;)</code>으로 하나하나 분리를 시켜준 뒤에 이 값들을 <code>reverse()</code>를 사용해 순서를 역으로 바꿔주고 <code>join(&quot;&quot;)</code>을 사용해 다시 합쳐주었다.
이 부분에서 새롭게 알게 된 부분이 있다. 처음 로직을 완성했을때는</p>
<blockquote>
<p>let result = array.reverse().join(&quot;&quot;);</p>
</blockquote>
<p>이 부분이 </p>
<blockquote>
<p>let result = Number(array.reverse().join(&quot;&quot;));</p>
</blockquote>
<p><code>Number()</code> 함수를 사용하여 스트링을 다시 넘버로 바꿔주는 로직이 하나 더 있었다. 다른 분의 설명을 듣고 스트링 타입에 <code>*</code> 연산자를 넣어주면 스트링이 넘버로 변한 다는 것을 알게 되었다.</p>
<blockquote>
<p>return (x &gt;= 0) ? result * 1 : result * -1;</p>
</blockquote>
<p>return에서 <code>*</code> 하나를 추가하여 <code>Number()</code> 함수 사용을 제거해 주었다.코드가 이해하기 더 쉬워졌다.</p>
<p>정리하자면<code>Math.abs()</code> 메서드와 스트링에 <code>*</code>를 하면 넘버로 변환되는 것을 경험해 보았다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[EHL]알고리즘 코드카타 Day 1]]></title>
            <link>https://velog.io/@dev_marco/EHL%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%BD%94%EB%93%9C%EC%B9%B4%ED%83%80-Day-1</link>
            <guid>https://velog.io/@dev_marco/EHL%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%BD%94%EB%93%9C%EC%B9%B4%ED%83%80-Day-1</guid>
            <pubDate>Mon, 11 Apr 2022 23:53:46 GMT</pubDate>
            <description><![CDATA[<p>문제</p>
<pre><code>twoSum함수에 숫자배열과 &#39;특정 수&#39;를 인자로 넘기면, 더해서 &#39;특정 수&#39;가 나오는 index를 배열에 담아 return해 주세요.

nums: 숫자 배열
target: 두 수를 더해서 나올 수 있는 합계
return: 두 수의 index를 가진 숫자 배열

예를 들어,
nums은 [4, 9, 11, 14] target은 13

nums[0] + nums[1] = 4 + 9 = 13 이죠?

그러면 [0, 1]이 return 되어야 합니다.

# 가정
target으로 보내는 합계의 조합은 배열 전체 중에 2개 밖에 없다고 가정하겠습니다.</code></pre><p>처음 문제를 보고 수기코드로 모델링을 시작하였다. 역시나 지금의 실력으로는 문제를 보고 바로 머리속에 어떤방식으로 풀어야 할지 생각이 나지 않았다. 
천천히 다시 읽어보니 어떤로직으로 풀어가야 할 지 생각이 들기 시작했다. 배열로 들어오는 인자들을 돌아가면서 겹치지 않도록 한번씩 더해준뒤 인덱스로 다시 반환을 하는 것이었다. 여기서 반환의 기준은 <code>target</code>의 전달인자와 두개의 인덱스의 수를 더했을 때 값이 같을 때 이 <code>target</code>의 값과 더해진 <code>nums</code>의 인덱스의 합이 같을 때 두개의 인덱스를 반환 하면 되는 것이다.
처음 로직은 두 수를 더해서 빈 배열에 반환 하려 했으나 이미 더해지는 전달인자 자체가 배열이기 때문에 굳이 빈 배열을 만들어서 반환 할 필요가 없었다.
두번째 고민으로는 [0],[1],[2],[3] 각각의 자리마다 배열을 할 생각을 했으나 반복문 자체가 더하기 앞에 들어오는 인덱스를 계속 바꿔주기 때문에 더하기 앞자리의 반복문을 중첩으로 돌릴 필요가 없었다.그래서 더하기 뒤에 들어오는 인덱스도 한번만 반복을 하면 되는 것이었다.
그래서 첫번째 고민에서 완성하게 된 함수는</p>
<pre><code class="language-js">const twoSum = (nums, target) =&gt; {
  // 아래 코드를 작성해주세요.

  for(let i=0; i&lt;nums.length; i++){
    for(let j=1; j&lt;nums.length; i++){
      if (nums[i] + nums[j] === target){
        return [i, j]
      }
    }
  }
}

console.log(twoSum([4, 9, 11, 14], 13))</code></pre>
<p>두번째 다시 만든 함수는</p>
<pre><code class="language-js">const twoSum = (nums, target) =&gt; {
  // 아래 코드를 작성해주세요.

  for(let i=0; i&lt;nums.length; i++){
     for(let j=i+1; j&lt;nums.length; j++){
       if (nums[i] + nums[j] === target){
         return [i, j]
       }
     }
  }
}

console.log(twoSum([1, 9, 9, 14], 18))</code></pre>
<p>둘의 차이점은 바로 두번째 반복문의 기준점이다!</p>
<blockquote>
<p>for(let <strong>j=1</strong>; j&lt;nums.length; i++)</p>
</blockquote>
<blockquote>
<p>for(let <strong>j=i+1</strong>; j&lt;nums.length; j++)</p>
</blockquote>
<p>첫번째 로직도 테스트에서는 통과가 가능하다.문제에서 주어진 인풋을 넣어보면 같은 값이 나온다.그러나 반복문에 기준점을 다시 생각해 보면 두번째 로직에 있는 수를 넣으면 다른 값을 받게 된다.
같은 값을 넣었을 때 첫번째 로직에서는 <code>[1, 1]</code>
두번째 로직에서는 <code>[1,2]</code> 와 같은 다른 값을 반환하게 된다.이유는 첫번째 로직에서는 두번째 반복문이 시작될때 자기 자신과도 비교를 하게 되기 때문에 같은 자리의 인덱스와도 더하기 연산이 실행이 된다. 이런 점을 잘 이해하고 조건이 더 까다로운 상황에도 대비를 해야하겠다.</p>
]]></description>
        </item>
    </channel>
</rss>