<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>.</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sun, 25 Dec 2022 05:19:47 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. .. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/x_sunyoung" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[React] 배열 데이터 렌더링하기 (Feat.map)]]></title>
            <link>https://velog.io/@x_sunyoung/map</link>
            <guid>https://velog.io/@x_sunyoung/map</guid>
            <pubDate>Sun, 25 Dec 2022 05:19:47 GMT</pubDate>
            <description><![CDATA[<h3 id="map-이란">map() 이란?</h3>
<blockquote>
<p>  arr.map(callbackFunction(currentValue, index, array), thisArg);</p>
</blockquote>
<p><strong><code>callback</code> : 새로운 배열 요소를 생성하는 함수로 다음 세가지 인수를 갖는다.</strong>
    (1) <code>currentValue</code> : 처리할 현재 요소.
    (2)<code>index</code> : 처리해야하는 현재 요소의 인덱스(optional).
    (3)<code>array</code> : map()을 호출한 배열(optional).
    (4)<code>thisArg</code> 는 callbackFunction 안에서 사용할 this 레퍼런스를 의미(optional)</p>
<p>map은 callback함수를 각 각의 요소에 대해 한 번씩 순서대로 불러 그 함수의 반환값으로 새로운 배열을 만든다. 
( 이 말 자체가 처음 map함수를 접했을 때 한 번에 이해되지 않아 console.log 로  찍어 어떤 새로운 배열을 만들어내는지 확인해보았다😂)</p>
<pre><code class="language-js">const array = [{id:1, name:&quot;김코딩&quot;, age:22, email:&quot;kimcoding@naver.com&quot;},
               {id:2, name:&quot;윤개발&quot;, age:30, email:&quot;devYoon@gmail.com&quot;},
               {id:3, name:&quot;위워크&quot;, age:25, email:&quot;wework@gmail.com&quot;}]

const nameList = array.map((value)=&gt;{return(value.name)})
const emailList = array.map((value)=&gt;{return(value.email)})
const List = array.map((value)=&gt;{return(`이름: ${value.name} , 나이: ${value.age}`)})
const index = array.map((value,index)=&gt;{return(index)})

console.log(nameList) // [ &#39;김코딩&#39;, &#39;윤개발&#39;, &#39;위워크&#39; ]
console.log(emailList) // [ &#39;kimcoding@naver.com&#39;, &#39;devYoon@gmail.com&#39;, &#39;wework@gmail.com&#39; ]
console.log(userList) // [ &#39;이름: 김코딩 , 나이: 22&#39;, &#39;이름: 윤개발 , 나이: 30&#39;, &#39;이름: 위워크 , 나이: 25&#39; ]
console.log(index) // [ 0, 1, 2 ]
</code></pre>
<h4 id="map에서-key-가-필요한-이유">map()에서 Key 가 필요한 이유</h4>
<ul>
<li><p>리액트에서 key는 배열을 렌더링 했을 때 어떤 엘리먼트에 변동이 있었는지 알아낼 때 사용한다.</p>
</li>
<li><p>Map에 key값이 없다면 중간의 값이 바뀌었을때 그 하위 값들이 전부 변해버린다. </p>
</li>
<li><p>고유 원소에 key 가 있어야만 배열이 업데이트 될 때 효율적으로 렌더링이 가능하다</p>
</li>
<li><p>만약에 배열안에 중복되는 key 가 있을 때에는 렌더링시에 오류메시지가 콘솔에 나타나게 되며, 업데이트가 제대로 이루어지지 않게 된다.</p>
</li>
<li><p>key 값이 없으면? 아래와 같이 콘솔창에 경고가 뜨고, 가상DOM을 비교하는 과정에서 리스트를 순차적으로 모두 비교하여 변화를 감지한다.
<img src="https://velog.velcdn.com/images/x_sunyoung/post/f9ece4fe-cce3-4030-89c1-f67a07169615/image.png" alt=""></p>
</li>
</ul>
<h4 id="map함수의-index-값을-key-값으로-사용한다면">map함수의 index 값을 key 값으로 사용한다면?</h4>
<p>이는 최후의 수단으로 사용해야한다. 
왜? index 를 key 값으로 사용 중에 배열이 재배열되면, 항목의 순서가 바뀌었을 때 key 또한 바뀔 것이기 때문에 그 결과로 컴포넌트의 state가 엉망이 되거나 의도하지 않은 방식으로 바뀔 수 있다.
따라서, key 값을 index 값이 아닌 특정한 id 값으로 주는 것을 적극 권장한다. </p>
<h4 id="배열-데이터를-통해-반복되는-ui-렌더링">배열 데이터를 통해 반복되는 UI 렌더링</h4>
<p>React로 UI를 작업할 때 반복되는 UI 구조를 구성하게 되는 경우가 있다. 이때, 새로운 배열을 반환하는 map 메서드의 특성을 JSX에서 활용할 수 있다. 배열 형태의 데이터와 map 메서드를 통해, 반복되는 UI를 어떻게 효율적으로 구성할 수 있는지 아래 예제를 통해 알아보자!</p>
<blockquote>
<p>일단 들어가기 전에 OUTDOOR_LIST 라는 배열 데이터를 만들었고, 이러한 배열 데이터를 가지고 리스트 페이지를 렌더링해보기로 했다.</p>
</blockquote>
<pre><code class="language-react">const List = () =&gt; {

return (
    &lt;div className=&quot;list&quot;&gt;
      &lt;h1&gt;인기 아웃도어 활동&lt;/h1&gt;
      &lt;&gt; 지금 바로 할인가로 예약하세요!&lt;/&gt;
      &lt;div className=&quot;listContainer&quot;&gt;
        {OUTDOOR_LIST.map((list {
          return (
            &lt;div className=&quot;fripList&quot; key={list.id&gt;
              &lt;div className=&quot;imgWrapper&quot;&gt;
                &lt;img src={list.img_src} /&gt;
              &lt;/div&gt;
              &lt;span className=&quot;location&quot;&gt; {list.location}&lt;/span&gt;
              &lt;span&gt; {list.title}&lt;/span&gt;
              &lt;span&gt; {list.price}&lt;/span&gt;
              &lt;span className=&quot;product_num&quot;&gt; {list.product_num}&lt;/span&gt;
            &lt;/div&gt;

          );
        })}
      &lt;/div&gt;
    &lt;/div&gt;
  );
};                                 </code></pre>
<pre><code class="language-js">const OUTDOOR_LIST = [
  {
    id: 1,
    img_src: &quot;/images/outdoor1.jpg&quot;,
    location: &quot;경기 전체&quot;,
    title: &quot;[2030 혼자여행] 국내최초 1박2일 혼펜 _따로 또 같이&quot;,
    price: &quot;159,000원&quot;,
    product_num: &quot;121737&quot;,
  },
  {
    id: 2,
    img_src: &quot;/images/outdoor2.jpg&quot;,
    location: &quot;송파/강동&quot;,
    title: &quot;헨리가 나혼자 탄 한강 카약&quot;,
    price: &quot;40,000원&quot;,
    product_num: &quot;110477&quot;,
  },
  ...
]

</code></pre>
<p> 코드 몇 줄로 예쁜 리스트 페이지가 탄생한 걸 볼 수 있다😳</p>
<p>  <img src="https://velog.velcdn.com/images/x_sunyoung/post/cc83e694-e14e-47a5-801b-dea0a66efce9/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git Rebase (+Conflict 해결하기)]]></title>
            <link>https://velog.io/@x_sunyoung/rebase</link>
            <guid>https://velog.io/@x_sunyoung/rebase</guid>
            <pubDate>Sun, 25 Dec 2022 04:58:08 GMT</pubDate>
            <description><![CDATA[<p>git rebase 명령어를 무작정 사용하기 이전에 <code>git merge</code>를 두고 왜 <code>git rebase</code>를 써야하는지부터 언급하려한다.
<code>git merge</code>를 사용해서 많은 개발자들이 큰 규모의 프로젝트를 작업해야하는 상황이라 가정해보자. </p>
<ul>
<li><p>각 각의 feature 브랜치가 머지될 때마다 &quot;merge commit&quot;이 남는다. 불필요한 커밋이 남는 셈이다. </p>
</li>
<li><p>commit history가 아래의 이미지처럼 복잡해진다. <code>git merge</code>는  시간 순서로 정렬되기 때문에 다른 브랜치에서의 커밋 이력들이 겹쳐 추적이 어렵다.
반면, <code>git rebase</code>를 이용한다면 같은 작업을 진행한 commit 끼리 모아주기 때문에 커밋 히스토리를 깔끔하게 관리할 수 있다. </p>
<p> <img src="https://velog.velcdn.com/images/x_sunyoung/post/16a9e5d8-9b80-42be-a478-7d727d6cb346/image.png" alt=""></p>
</li>
</ul>
<h3 id="git-rebase-란">Git Rebase 란?</h3>
<ul>
<li>Rebase는 이름 그대로 브랜치의 base 를 다시 설정한다는 의미이다.</li>
<li>base를 다시 정의함으로써 새롭게 커밋 라인을 정리하여 히스토리를 깔끔하게 볼 수 있게 해준다.</li>
</ul>
<h3 id="git-rebase-사용법">Git rebase 사용법</h3>
<p>각 branch에서 작업하다가 여러개의 commit 이 생기면 rebase로 병합해준다.</p>
<p>기존에 작업하던 브랜치를 remote에 push 하기 전 main 으로 가서 pull 진행을 먼저 해야한다. (아래와 같은 순서로 진행!)</p>
<pre><code>
$git add .
$git commit -m &quot;commit 메세지&quot;

$git checkout main 
$git pull origin main // main 브랜치를 최신화

$git checkout feature/login
$git rebase -i main // </code></pre><h3 id="rebase-하는동안-squash-진행할-때에는">rebase 하는동안 squash 진행할 때에는?</h3>
<p>1.여러개의 commit 들 앞에 <code>pick</code>이라고 적혀있다. 가장 오래된 commit을 pick으로 둔다.
<img src="https://velog.velcdn.com/images/x_sunyoung/post/51de56d9-e304-405e-b659-0639a268e012/image.png" alt=""></p>
<blockquote>
<p>📌
<code>p, pick</code> : 해당 커밋을 수정하지 않고 그냥 사용하겠다 라는 명령어이다.
텍스트 에디터로 들어오면 커밋에 pick 명령어가 디폴트 값이다.
<code>s, squash</code> : 여러개의 커밋 메세지를 하나로 합치는 명령어로로 커밋 히스토리를 깔끔하게 관리할 수 있다. git log에서 합쳐진 커밋 메세지를 확인할 수 있다.</p>
</blockquote>
<p>2.나머지 commit 메세지들은 <code>pick</code> 대신 <code>squash</code> 혹은 <code>s</code>라고  입력후  esc -&gt; :wq로 저장하고 창에서 빠져나온다.👇🏻<img src="https://velog.velcdn.com/images/x_sunyoung/post/1fc3843d-e333-4a75-8c0b-464c62741a1e/image.png" alt="">
3. 수정용 에디터가 하나 더 나타난다. 아래와 같이 현재까지 적은 커밋 메세지들 목록이 보일 것이다.👇🏻🏻
<img src="https://velog.velcdn.com/images/x_sunyoung/post/0c30408b-65ff-4d40-a5a8-46eca81e042b/image.png" alt="">4. 하나의 커밋 메세지만 남기고 나머지는 지워준다. 남길 커밋 메세지에는 해당 branch를 대표하는 커밋 메세지이니 상세하고 신중하게 적어준다. 작성이 끝나면 esc -&gt; :wq로 빠져나온다.
<img src="https://velog.velcdn.com/images/x_sunyoung/post/97ee06bf-4178-405b-8295-4dcd22a9b473/image.png" alt=""></p>
<ol start="5">
<li>리모트로 push해준다. <code>git push origin [branch 명]</code> </li>
</ol>
<h3 id="git-rebase-중에-conflict-가-발생했다면">Git Rebase 중에 conflict 가 발생했다면?</h3>
<p>충돌된 부분의 코드를 수정 후,</p>
<pre><code>$ git add . // add 후 commit 은 하지않는다.변경된 내용이 없기 때문에
$ git rebase --continue // 멈춰있던 rebase 가 진행된다.</code></pre><p>충돌이 여러번 일어나면 그 때마다 충돌된 부분을 수정하여 해결하고 
<code>git add .</code> -&gt; <code>git rebase --continue</code>를 반복한다. 
(commit을 한 만큼 오류가 발생될 것이니..겁먹지말자..)</p>
<p>위 과정이 끝나면,</p>
<pre><code>$ git push origin [branch 명]</code></pre><p>만약 아래와 같은 오류 메세지가 나온다면,(git은 history 가 다른 branch의 푸쉬를 허용하지 않기 때문에 에러가 발생한다)</p>
<div style="color:red">
  ![rejected] feature/~ -> feature/~ (non-fast-forward)</div><div style="color:red">error: failed to push some refs to 'http://github.com'
</div>

<p>아래의 명령어로 force push를 진행한다.</p>
<pre><code>$git push origin [branch 명] -f</code></pre><p>그래도 해결이 안되면, 아래의 명령어로 rebase 를 진행하기 전 상황으로 돌아갈 수 있다.</p>
<pre><code>$git rebase --abort </code></pre><p>혹은 git reflog로 [돌아갈 지점]을 찾은 후 git-reset --hard [돌아갈지점] 명령어로 복구할 수 있다.</p>
<blockquote>
<p>📌 &lt;git rebase 사용 시 주의사항&gt;</p>
</blockquote>
<ul>
<li>이미 공개 저장소(remote)에 push한 커밋을 Rebase 하지 말 것!</li>
<li>rebase는 혼자 작업하는 브랜치에 한해서만 해야한다. 여러 사람이 한 브랜치에서 작업하는 경우에 rebase를 사용하면 꼬일 수 있다.</li>
</ul>
<p>출처 ) wecode 에서 제공하는 학습 자료 참고</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 상수데이터 / Mock 데이터]]></title>
            <link>https://velog.io/@x_sunyoung/mockdata</link>
            <guid>https://velog.io/@x_sunyoung/mockdata</guid>
            <pubDate>Sun, 04 Dec 2022 02:55:03 GMT</pubDate>
            <description><![CDATA[<h3 id="상수데이터란">상수데이터란?</h3>
<ul>
<li>변하지 않는 데이터</li>
<li>UI 구성에 필요하지만 동적으로 변하지 않아서 백엔드 API등을 통해 가져올 필요가 없는 정적 데이터이다.<ul>
<li>반복되는 UI 구조는 상수데이터와 map 메서드를 활용해 간결하게 표현이 가능하다.</li>
</ul>
</li>
</ul>
<h3 id="상수데이터를-왜-사용하는가">상수데이터를 왜 사용하는가?</h3>
<p> 반복되는 UI를 하드코딩으로 일일이 만들어야한다고 생각해보자, 코드가 길어져 가독성도 떨어지고 수정이 필요할 때 해당 부분을 찾기 힘들어 추후 유지 보수가 힘들어진다.
 배열 안에 객체를 추가 혹은 삭제만으로 UI 수정에 유용하다.</p>
<hr>
<p><strong>💡상수 데이터 활용 방법</strong> (+ 아래 코드와 함께 참고)</p>
<ol>
<li>별도의 파일을 생성하고, 그 안에 상수 데이터를 선언한다.(상수데이터는 컴포넌트 파일 내부에 선언해줄 수도 있지만 가독성이 떨어지거나 다른 파일에서 동일한 데이터가 필요한 경우 파일로 분리하여 관리)</li>
<li>상수데이터 변수는 <code>대문자 + snake case</code>를 이용해서 변수의 이름을 짓는 컨벤션이 있다.</li>
<li>별도의 파일로 분리할 경우 export/ import를 통해 필요한 파일에서 사용한다.</li>
<li><code>Array.map()</code> 메소드를 이용해서 컴포넌트를 렌더링한다.</li>
<li>해당 상수데이터의 배열 안에 들어가 있는 요소의 갯수만큼 컴포넌트가 만들어진다.</li>
</ol>
<pre><code class="language-js">//Data.js

import React from &quot;react&quot;;
import { MENU_LIST } from &quot;./uiData&quot;;

// 상수데이터의 선언은 컴포넌트 밖에서 선언한다. (위치 A or 위치 B)
// 이 예제에서는 uiData.js 파일을 따로 만들어 데이터를 관리하였다.

// 위치 A 
const Data = () =&gt; {
  return (
    &lt;div&gt;
      &lt;ul&gt;
        {MENU_LIST.map((menuList) =&gt; {
          return &lt;li key={menuList.id}&gt;{menuList.menuName}&lt;/li&gt;;
        })}
        {/* 하드코딩을 했다면 아래 처럼 일일이 나열했을 것이다.
        &lt;li&gt;&lt;/li&gt;
        &lt;li&gt;김밥&lt;/li&gt;
        &lt;li&gt;라면&lt;/li&gt;
        &lt;li&gt;돈까스&lt;/li&gt;
        &lt;li&gt;사이드메뉴&lt;/li&gt; 
        &lt;li&gt;세트메뉴&lt;/li&gt; */}
      &lt;/ul&gt;
    &lt;/div&gt;
  );
};

export default Data;

// 위치 B
</code></pre>
<hr />


<pre><code class="language-js">// uiData.js

const MENU_LIST = [
  { id: 1, menuName: &quot;김밥&quot; },
  { id: 2, menuName: &quot;라면&quot; },
  { id: 3, menuName: &quot;돈까스&quot; },
  { id: 4, menuName: &quot;사이드메뉴&quot; },
  { id: 5, menuName: &quot;세트메뉴&quot; }
];

export default MENU_LIST;
</code></pre>
<hr />
<hr />

<h2 id="mock-data">Mock Data</h2>
<p>Mock : 흉내내다.
가짜 데이터, 샘플 데이터, 실제 API 에서 받아온 데이터가 아닌 프론트앤드 개발자가 필요에 의해 샘플로 만들어본 데이터이다.</p>
<h4 id="왜-mock-data를-쓰는가">왜 Mock Data를 쓰는가?</h4>
<ol>
<li>백엔드 API가 미완성인 상태에서도 차질없는 개발이 가능하다. 실제 API가 없어도 API 데이터처럼 UI 렌더링이 가능하다. mock data를 만들어 데이터가 들어오는 상황을 미리 대비하고 UI 기획에 맞게 구현되는지 먼저 확인해볼 수 있다.</li>
<li>백엔드와의 효율적인 소통이 가능하다. 주고 받는 데이터가 어떤 형태인지, key &amp; value 값을 미리 맞춰볼 수 있다.</li>
</ol>
<h4 id="왜-확장자가-js가-아니고-json인가">왜 확장자가 .js가 아니고 .json인가?</h4>
<p>실제로 받아올 데이터는 서버와 통신으로 json형태로 응답받는다. 그래서 실제 API 데이터를 흉내내서 만든 Mock data도 .json파일로 만든다.
생성된 Mock Data의 위치는 <code>public 폴더 &gt; data 폴더</code> 에서 관리한다. (로컬서버에서 통신으로 응답받아 구현하기때문에 public폴더에서 관리) </p>
<h4 id="fetch-함수란">fetch 함수란?</h4>
<p>fetch함수를 사용하여 데이터를 <code>비동기</code>로 요청할 수 있다. 
<span style="color:gray"> (비동기를 쉽게 예를 들어 설명하자면, 커피 주문하고 나올때까지 대기하는 것이 아니라,
진동벨 받아놓고 다른 일처리를 하다가 진동벨 울리면 커피 받으러가면 된다는 것과 비슷하다. 비동기적으로 코드를 실행하면 더 유동적으로 더 많은 일을 할 수 있다!)</span></p>
<ul>
<li><code>fetch 메서드의 첫번째 인자</code>:   API 주소를 전달하는데 이 주소에 Mock data 파일의 경로를 적거나 실제 백엔드로부터 받은 API주소를 적는다.</li>
<li><code>첫번째 then</code>: 요청이 성공할 경우 response객체를 받아 json형태로 파싱한다.</li>
<li><code>두번째 then</code>: json형태의 응답 body의 데이터를 출력한다.</li>
</ul>
<pre><code class="language-js">fetch(&#39;/data/파일명.json&#39;)
    .then(response=&gt;response.json())
    .then(result =&gt; setState(result))
</code></pre>
<p><code>두번째 then</code> 메서드 인자로 callback을 전달하고 매개변수에는 <code>첫번째 then</code>에서 반환된 객체를 result로 받아 setState함수로 result를 state에 저장한다. 그 다음 호출은 언제해야할까?</p>
<p>fetch로 통신을 하기 전에 데이터를 불러올 타이밍을 생각해봐야한다.</p>
<ul>
<li>컴포넌트가 브라우저에 그려지고 호출해야하는 상황 : useEffect안에서 fetch메서드 호출</li>
<li>특정 이벤트 함수가 실행될때 호출해야하는 상황 : 특정이벤트 함수 내에서 fetch메서드 호출</li>
</ul>
<hr / >

<p>💡<strong>mock data 활용 방법</strong> ( + 아래 코드와 함께 참고 )</p>
<ol>
<li>백엔드 API가 완성되지 않은 상태였을 때,  백엔드 개발자와 소통하여 필요한 데이터의 구조와 key value가 어떤 형태인지 확인한다.</li>
<li>그걸 가지고 프론트엔드에서 자체적으로 mock data를 만들고, 실제 API처럼 통신으로 요청해서 받아오기 떄문에 fetch 메서드를 사용한다.</li>
<li>브라우저에 마운트되자마자 화면에 그려야하기 때문에 useEffect 안에서 fetch메서드를 호출한다. </li>
<li>state에 데이터를 저장하여 필요한 데이터를 가져다가 UI로 그린다.</li>
</ol>
<p>아래 주소에서 데이터를 가져와서 활용한 코드이다.
<a href="https://jsonplaceholder.typicode.com/users">https://jsonplaceholder.typicode.com/users</a></p>
<pre><code class="language-js">import React, { useEffect, useState } from &quot;react&quot;;

const User = () =&gt; {
  const [userInfoList, setUserInfoList] = useState([]);
  console.log(userInfoList);

  useEffect(() =&gt; {
    fetch(&quot;/data/userInfoList.json&quot;)
      .then((response) =&gt; response.json())
      .then((result) =&gt; {
        setUserInfoList(result);
      });
  }, []);

  return (
    &lt;div&gt;
      User
      {userInfoList.map((userInfo) =&gt; {
        return (
          &lt;ul&gt;
            &lt;li&gt;{userInfo.name}&lt;/li&gt;
            &lt;li&gt;{userInfo.email}&lt;/li&gt;
            &lt;li&gt;{userInfo.phone}&lt;/li&gt;
          &lt;/ul&gt;
        );
      })}

    &lt;/div&gt;
  );
};

export default User;
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] useEffect]]></title>
            <link>https://velog.io/@x_sunyoung/useeffect</link>
            <guid>https://velog.io/@x_sunyoung/useeffect</guid>
            <pubDate>Sat, 26 Nov 2022 09:59:22 GMT</pubDate>
            <description><![CDATA[<h2 id="useeffect">useEffect</h2>
<p>어떠한 컴포넌트가 Mount(화면에 첫 렌더링) / Update(특정 props가 바뀔때) / Unmount (화면에서 사라질 때) 되었을 때 특정 작업을 처리할 코드를 실행시켜주기 위해 <code>useEffect</code>를 사용한다.</p>
<p>*<em>📌 <span style="color:blue"> useEffect( ( ) =&gt; { } ) <span> *</em>
<code>useEffect hook</code>은 인자로 콜백함수를 받는다.
콜백 함수란 다른 함수의 인자로 전달된 함수를 의미한다.
이 콜백 함수 내부에 우리가 원하는 작업을 해줄 코드를 작성하여준다.</p>
<h3 id="useeffect-함수는-두가지-형태가-있다">useEffect 함수는 두가지 형태가 있다.</h3>
<ol>
<li><code>useEffect</code> 의 인자로 하나의 콜백함수만 받는 형태</li>
</ol>
<ul>
<li>렌더링 될 때마다 매번 콜백이 실행된다.</li>
<li>즉, 컴포넌트가 맨 처음 화면에 렌더링 될때 &amp; 컴포넌트가 다시 렌더링될 때 실행된다.</li>
</ul>
<ol start="2">
<li><code>useEffect</code>의 첫 번째 인자로 콜백 함수, 두번째 인자로 배열을 받는 형태</li>
</ol>
<ul>
<li>2 번에서 말하는 배열은 다른 이름으로 <code>defendency array</code> 라고 한다.</li>
<li>매번 렌더링이 될 때마다 실행되는 것이 아니라 컴포넌트가 첫 렌더링 될 때 실행 &amp;  배열 안에 들어있는 요소의 value가 바뀔때 실행이된다.</li>
<li>만약 빈 배열을 전달해준다면 컴포넌트가 맨 처음 화면에 렌더링 될 때만 실행이 된다.</li>
</ul>
<h3 id="clean-up-함수--정리-작업을-처리">clean up 함수- 정리 작업을 처리</h3>
<p>ex) 타이머라고 치면 더이상 타이머가 필요 없을 때 타이머를 멈추는 정리 작업
ex) 어떤 이벤트리스너를 등록을 했다면 컴포넌트가 언마운트 될 때 등록한 이벤트를 제거해주는 작업</p>
<p>이러한 정리 작업을 처리하려면 <code>useEffect</code>의 return 값으로 함수를 넣어준다.
그러면 해당 컴포넌트가 언마운트될 때 혹은 다음 렌더링 시 불릴 <code>useEffect</code>가 실행되기 이전에 그 함수가 실행이 된다.</p>
<hr>
<h4 id="예제-1">예제 1</h4>
<pre><code class="language-js">import React, { useState, useEffect } from &quot;react&quot;;

const SideEffect = () =&gt; {
  const [count, setCount] = useState(0);
  const [text, setText] = useState(&quot;&quot;);


  // count 값이 변했을 때만 이 콜백함수를 호출되고 text값이 변할 때는 useEffecdt의 콜백함수가 호출되지 않는다.
  useEffect(() =&gt; {
    console.log(&quot;count changed&quot;);
  }, [count]);


    // 반대로, text 값이 변했을 때만 이 콜백함수를 호출되지만 count값이 변할 때는  이 useEffect는 실행되지 않는다.
  useEffect(() =&gt; {
    console.log(&quot;text changed&quot;);
  }, [text]);

  // count와 text 둘 중 하나라도 변했다면, 이 useEffect는 실행된다.
  useEffect(() =&gt; {
    console.log(&quot;count &amp; text when?&quot;);
  }, [count, text]); // 

  // 첫 번째 렌더링에서만 실행되고 두번째부터 마지막까지 절대 호출되지 않기를 원한다면, 의존생 배열에 [] 빈 배열을 넣는다.
  // 감지할 값이 없기때문에 첫번째 렌더링시에만 effect가 호출된다.
  useEffect(() =&gt; {
    console.log(&quot;only first render&quot;);
  }, []);

  useEffect(() =&gt; {
    console.log(&quot;------------------&quot;);
  });

  console.log(&quot;count&quot;, count);
  console.log(&quot;text&quot;, text);
  console.log(&quot;Render&quot;);

  return (
    &lt;div&gt;
      &lt;div className=&quot;wrapper&quot;&gt;
        &lt;h1&gt;Count : {count}&lt;/h1&gt;
        &lt;button onClick={() =&gt; setCount(count + 1)}&gt;count up&lt;/button&gt;
      &lt;/div&gt;
      &lt;input
        onChange={(e) =&gt; setText(e.target.value)}
        type=&quot;text&quot;
        value={text}
      /&gt;
    &lt;/div&gt;
  );
};

export default SideEffect;
</code></pre>
<h4 id="예제-2">예제 2</h4>
<pre><code class="language-js">
import React, { useState, useEffect } from &quot;react&quot;;

// 1. 컴포넌트를 count라는 state를 가지고 있고 useState를 통해 
// 버튼을 눌렀을 떄 state인 count가 올라가게끔 만들어준다.
// 2. useEffect 를 사용한다.

function UseEffect() {
  const [count, setCount] = useState(1);
  const [name, setName] = useState(&quot;&quot;);

  const handleCountUpdate = () =&gt; {
    setCount(count + 1);
  };
  const handleInputChange = (e) =&gt; {
    setName(e.target.value);
  };

  // 콘솔창이 언제 출력되는지 아래 코드를 실행시켜보자.

   // 렌더링마다 매번 실햄됨.
    useEffect(() =&gt; {
      console.log(&quot;렌더링 지옥!&quot;);
    });

    // 마운팅 + name이 변경될때만 실행.
    useEffect(() =&gt; {
      console.log(&quot;name 변화&quot;);
    }, [name]);

    // 마운팅 + count가 변화될때마다 실행.
    useEffect(() =&gt; {
      console.log(&quot;count 변화&quot;);
    }, [count]);

  // useEffect를 맨 처음 화면 렌더링될때만 부르고 싶다면? 
  // dependecy array를 빈 배열로 두번째 인자에 넣어두면된다.
  useEffect(() =&gt; {
    console.log(&quot;mounting!&quot;);
  }, []);

  return (
    &lt;div&gt;
      &lt;div&gt;
        &lt;button onClick={handleCountUpdate}&gt;Update&lt;/button&gt;
        &lt;span&gt;count : {count}&lt;/span&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;input type=&quot;text&quot; value={name} onChange={handleInputChange} /&gt;
        &lt;span&gt;name: {name} &lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
}

export default UseEffect;

</code></pre>
<hr>
<h4 id="예제-3-useeffect-를-사용해-타이머-만들기">예제 3. useEffect 를 사용해 타이머 만들기</h4>
<p>component 폴더를 하나 생성하고 그 안에 Timer.js파일을 만든다.</p>
<pre><code class="language-js">//Timer.js

import React, { useEffect } from &quot;react&quot;;

const Timer = (props) =&gt; {
  useEffect(() =&gt; {

    // setInterval : 정해진 주기마다 특정 로직을 반복해야할 때 사용하는 메서드.
    // 정리 작업을 해주는 코드가 없을 경우,
    // 타이머가 언마운트 되었을 때 1초마다 찍히는 콘솔창이 멈추지 않고 계속 작동될 것이다.
    // 정리 작업을 해주는 코드를 추가하여 타이머가 언마운트 되었을 때 timer가 종료되도록(멈추도록)해보자!
    // 정리를 하려면? useEffect의 return 값으로 함수를 넣어준다. 그리고 그 함수 안에서 정리작업을 처리해준다.

    const timer = setInterval(() =&gt; {
      console.log(&quot;타이머 돌아가는중...&quot;);
    }, 1000);
    return () =&gt; {
      clearInterval(timer);
      console.log(&quot;타이머가 종료되었습니다!&quot;);
    };
  }, []);

  return (
    &lt;div&gt;
      &lt;span&gt;타이머를 시작합니다. 콘솔을 보세요.&lt;/span&gt;
    &lt;/div&gt;
  );
};

export default Timer;
</code></pre>
<p>💡 App.js에 component 인 Timer import해야 화면에 렌더링되니 잊지말기!</p>
<pre><code class="language-js">//App.js//

import React, { useState, useEffect } from &quot;react&quot;;
import Timer from &quot;./component/Timer&quot;;

// Timer component를 계속 보여주는게 아니라 showTimer가 true일때만 타이머를 보여주고싶다.


function App() {
  const [showTimer, setShowTimer] = useState(false);

  return (
    &lt;div&gt;
      {/* 아래 코드가 쇼타이머가 true일때만 Timer를 보여주겠다는 코드  */}
      {showTimer &amp;&amp; &lt;Timer /&gt;}
      {/* 버튼이 클릭될 때 쇼타이머가 false-&gt;true 혹은 true -&gt; false 로 바뀌게하는 코드 */}
      &lt;button onClick={() =&gt; setShowTimer(!showTimer)}&gt;Toggle Timer&lt;/button&gt;
    &lt;/div&gt;
  );
}

export default App;
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] useState ]]></title>
            <link>https://velog.io/@x_sunyoung/usestate</link>
            <guid>https://velog.io/@x_sunyoung/usestate</guid>
            <pubDate>Sat, 26 Nov 2022 08:32:59 GMT</pubDate>
            <description><![CDATA[<h2 id="usestate">useState</h2>
<p>useState는 Hook의 기술이다. 함수형 컴포넌트에서는 클래스형 컴포넌트와 같이 state를 사용할 수 없기 때문에, Hook을 사용해서 state와 같은 기능을 할 수 있도록 만들어주었다.</p>
<p>useState는 설정할 state 값과 이 값을 업데이트하는 함수를 쌍으로 제공한다. 이 함수는 클래스 컴포넌트에서의 this.setState와 유사하지만 이전 state와 새로운 state를 합치지 않는다는 차이점이 있다.</p>
<p><strong>📌 <span style="color:blue">const [state, setState] = useState(초기값); </span></strong></p>
<ul>
<li>state : 컴포넌트의 상태</li>
<li>setState : state를 변경해주는 함수</li>
<li>state의 생성과 동시에 가져야할 초기값을 usestate 함수에 인자로 넣어주면
state와 setState라는 두가지 요소를 배열 형태로 return해준다.</li>
<li>현재 상태값을 state라는 변수에 들어있고, state의 값을 변경시켜주기위해 setState 함수를 이용한다.</li>
<li>setState 함수를 사용해서 state를 변경하면 해당 컴포넌트는 화면에 다시 렌더링(업데이트)된다.</li>
</ul>
<p>useState hook을 이용하여 아래와 같이 예제 코드를 작성해보았다.</p>
<pre><code class="language-js">
import React, { useState } from &quot;react&quot;;

function App() {
  const [names, setNames] = useState([&quot;홍길동&quot;, &quot;김민수&quot;]);
  const [input, setInput] = useState(&quot;&quot;);

  const handleInputChange = (e) =&gt; {
    setInput(e.target.value);
  };

  //새로 업데이트 시켜 줄 state는 이전에 이미 존재하던 state와 밀접하게 연관이 있다.
  //이 경우 setNames 인자 안에 바로 값을 주는 것이 아니라 콜백 함수를 전달해준다.

  const handleUpload = () =&gt; {
    setNames((prevState) =&gt; {
      return [input, ...prevState];
    }); 
    setInput(&quot;&quot;); // upload 버튼을 누른후 input을 빈칸으로 해주는 작업
  };

  // console.log(input); 

  return (
    &lt;div&gt;
      &lt;input type=&quot;text&quot; value={input} onChange={handleInputChange} /&gt;
      &lt;button onClick={handleUpload}&gt;Upload&lt;/button&gt;
      {names.map((name, index) =&gt; {
        return &lt;p key={index}&gt;{name}&lt;/p&gt;;
      })}
    &lt;/div&gt;
  );
}

export default App;


</code></pre>
<blockquote>
<p><strong>array.map()</strong>
array.map() 은 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환하는 메서드이다.
map의 index로 key를 잡도록 작성하였고 입력 버튼을 클릭하면 사람 이름이 요소로 추가되도록 설정하였다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/9bdcd55f-9335-4a21-9826-81592f4691c8/image.png" alt="">
input 창에 윤코딩과 김개발을 입력후 upload 버튼을 누르면 아래와 같이 list-up 되는것을 확인할 수 있다. 😊
<img src="https://velog.velcdn.com/images/x_sunyoung/post/fbba33f1-c20a-4b4d-8c02-46282afdbc4f/image.png" alt=""></p>
<p>출처 : [youtube] 별코딩 채널을 참고하여 작성된 글입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Basic Git flow &  팀단위 Git flow]]></title>
            <link>https://velog.io/@x_sunyoung/basicgitflow</link>
            <guid>https://velog.io/@x_sunyoung/basicgitflow</guid>
            <pubDate>Wed, 23 Nov 2022 23:08:04 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/e7ba2aaa-168a-4639-a23c-bf7dc3986633/image.png" alt=""></p>
<h3 id="git--github을-이용한-작업-방식">Git &amp; Github을 이용한 작업 방식</h3>
<p>크게 두 가지 공간이 있다는 개념을 이해하고 아래 순서로 진행한다.</p>
<p> 💡 remote = origin = github 상의 공간 
 💡 local = 내 컴퓨터 </p>
<ol>
<li><p>cd <code>Desktop 내 폴더</code></p>
</li>
<li><p>git clone <code>[repository 주소]</code> 
: <span style="color:gray"> clone을 하게되면 로컬에서는 최초로 default        branch에 위치하게된다.
여기서 defaul branch의 이름은 master 혹은 main이다.</span></p>
</li>
<li><p>cd <code>[프로젝트 폴더]</code> </p>
</li>
<li><p>git branch <code>feature/login</code><br>: <span style="color:gray">내 로컬에 별도의 브랜치를 생성하여 그 브랜치에서 작업을 진행해야한다.</span></p>
</li>
<li><p>git checkout <code>feature/login</code> 
: <span style="color:gray">생성한 브랜치로 이동</span></p>
</li>
<li><p>코드 작성 </p>
</li>
<li><p>git add .</p>
</li>
<li><p>git commit  </p>
</li>
<li><p>git push orgin <code>feature/login</code>
: <span style="color:gray">origin이라는 리모트에 feature/login 브랜치의 작업 내용을 리모트로 올린다. </span></p>
</li>
</ol>
<blockquote>
<p>📌 여기서 잠깐! 리모트로 해당 branch를 push했다고 끝난게 아니다!📌
<span> 리모트에 feature/login의 작업 내용은 생성되었지만, 아직 default branch인 master에는 feature/login의 작업 내역이 존재하지 않은 상태이다. 
 마스터에 feature/login의 작업 내용을 합쳐달라는 요청을 하기위해 다음 순서로 PR(pull request) 작성한다.</span> <br /></p>
</blockquote>
<ol start="10">
<li>PR(Pull Request)작성 
: <span style="color:gray">PR을 통해 브랜치의 작업 내역을 확인하고 관리자 또는 다른 팀원들이 확인 후 이상이 없다 판단되면 <code>feature/login</code> 브랜치가 master에 머지가 된다. 머지가 되고 나면 <code>feature/login</code>에 작성된 코드가 origin, 즉 리모트 상의 마스터에 최신화된다.</span>


</li>
</ol>
<ol start="11">
<li><p>git checkout master 
: <span style="color:gray"> origin master는 최신화 되어있지만 아직 내 로컬에 있는 default branch인 마스터는 최신화된 내용을 모르고 있다.
이 내용을 내 로컬로 가져오기 위해 현재 위치를 <code>feature/login</code>에서 <code>mater</code>로 체크아웃 해준다. </span></p>
</li>
<li><p>git pull origin master
: <span style="color:gray">origin master의 내역을 내 로컬 master로 가져와 준다.</span></p>
</li>
<li><p>git branch <code>[new branch name]</code>
로컬 master의 코드가 최신화된다.
: <span style="color:gray"> 만약 또 다른 작업을 하고 싶다면 master에서 새로운 브랜치를 생성하여 그 브랜치에서 현재 진행했던 과정들을 반복해 주면 된다.</span></p>
</li>
</ol>
<hr>
<h4 id="위-순서로-직접-git-command를-쳐보고-git-flow를-파악해보았다">위 순서로 직접 git command를 쳐보고 git flow를 파악해보았다.</h4>
<pre><code>$ cd gitflow // 1번
$ git clone https://github.com/syyyoon/git-flow-practice.git // 2번
$ cd git-flow-practice // 3번
$ code . // vs code 실행</code></pre><p>vs code 를 열어 <code>command+j</code> 로 터미널을 열고 아래 순서로 이어서 진행하였다.</p>
<pre><code>$ git branch feature/login // 4번
$ git checkout feature/login // 5번
Switched to branch &#39;feature/login&#39; //이런 문구가 나왔다면 브랜치 생성 및 이동 성공!
</code></pre><blockquote>
<p>** 💡실제로 vs code 왼쪽 하단 or git status 명령어를 통해 현재 로컬 상의 위치를 확인할 수 있다.**</p>
</blockquote>
<div>
    <img src="https://velog.velcdn.com/images/x_sunyoung/post/9a7385f0-9ceb-419b-86a7-8328b40066bf/image.png" align="center">
</div>
<p>local상의 default branch인 master에 위치한 상태</p>
><div><img src="https://velog.velcdn.com/images/x_sunyoung/post/5ca2e85e-230b-42e2-badc-9b641cefdae8/image.png" align="center">
</div> 
<p>branch 생성 후 feature/login로 checkout 후의 상태</p>


<p>생성된 branch에서 코드 작업이 끝났다면 아래와 같이 이어 진행한다.</p>
<pre><code>$ git add . // 7번
$ git commit -m &quot;index.html 수정&quot;  // 8번
$ git log // 커밋 이력 조회 - 생략해도 무관하다
$ git push origin feature/login // 9번
$ git log // 커밋 이력 조회 - 생략해도 무관하다
</code></pre><blockquote>
<p>💡 git을 이용할때 git log 명령어를 굳이 하지않아도 되지만 어떤 상태 변화가 있는지 확인해보기 위해 진행하였다.<br />
_&lt;8번 후 git log를 실행하면 나타나는 터미널 화면&gt;_
<img src="https://velog.velcdn.com/images/x_sunyoung/post/712f625c-0e49-4402-9ca3-e543770d94c2/image.png" alt="">
_&lt;9번 후 git log를 실행하면 나타나는 터미널 화면&gt;_
<img src="https://velog.velcdn.com/images/x_sunyoung/post/b5540e5f-1524-47b5-b656-33f76bfe897b/image.png" alt=""></p>
</blockquote>
<p>PR(Pull Request) 작성 후 origin master에 merge를 하면 추가 및 수정된 내용이 반영되었고 github상에서 어느 파일에 어떤 부분이 수정되었는지 확인 가능하다.
<img src="https://velog.velcdn.com/images/x_sunyoung/post/e820cd5d-8578-4c59-9bab-aba39ca11572/image.png" alt=""></p>
<p>다시 vs code  로 돌아와 아래와 같이 명령어를 입력한다.
위에서 언급했듯, origin master의 내역을 내 local master로 가져오기 위한 작업이다. 12 번까지 완료되었다면 위의 4번부터 다시 동일한 순서로 작업을 진행하면된다. </p>
<pre><code>$ git checkout master  // 11번

Switched to branch &#39;master&#39;//// feature/login --&gt; master 로 이동되었음을 알려준다.

$ git pull origin master // 12번
$ git branch feature/main // 13번
$ git checkout feature/main // 14번</code></pre><hr />

<h3 id="git--github을-이용한-작업-방식---team-project">Git &amp; Github을 이용한 작업 방식 - Team Project</h3>
<ul>
<li>팀원 총 3명 <ul>
<li>팀원 1 : 초기 세팅을 진행하는 사람.</li>
<li>팀원2과 팀원 3 : 초기 세팅된 파일을 clone받아 작업을 진행할 사람들. </li>
</ul>
</li>
</ul>
<h4 id="팀원-1이-먼저-아래와-같은-순서로-초기세팅을-진행하여준다">팀원 1이 먼저 아래와 같은 순서로 초기세팅을 진행하여준다.</h4>
<ol>
<li><p>cd <code>폴더명</code></p>
</li>
<li><p>npx create-react-app <code>프로젝트명</code><br>: <span style="color:gray">이때 <code>node_modules</code> 디렉토리가 생성되는데 이것은 <code>.gitignore</code> 에 추가되어 git으로 관리되지 않고 github에 push하여도 이 디렉토리는 올라가지 않기때문에.  추후 팀원들이 clone하여 받게되면 따로 설치해야한다.</span></p>
</li>
<li><p>cd <code>프로젝트명</code></p>
</li>
<li><p>초기세팅 진행 (ex. 폴더/파일 생성 및 ESLint / Prettier / Stylelint 등 install해주는 작업)</p>
</li>
<li><p>git add .</p>
</li>
<li><p>git commit -m &quot;Add : Initial Setting&quot;</p>
</li>
<li><p>git remote add origin <code>github상의 repository 주소</code> 
: <span style="color:gray"> 이 명령어는 리모트를 하나 추가할 건데 내가 넣은 주소로 리모트를 추가하고 앞으로 이 주소를 origin이라고 부르겠다라는 말이다.
이때 아직 로컬에 있는 레파지토리는 리모트에 연결되기 전이기때문에 리모트를 추가해주어야한다. </span></p>
</li>
<li><p>git push origin master 
: <span style="color:gray"> push를 통해 작업한 것을 리모트 상에 올려준다.
repository가 github상에 올라갔으니 다른 팀원들도 clone받아 레파지토리를 로컬에 만들 수 있는 단계이다.</span></p>
</li>
</ol>
<h4 id="나머지-팀원-23은-아래와-같은-순서로-진행하여준다">나머지 팀원 2,3은 아래와 같은 순서로 진행하여준다.</h4>
<ol>
<li>cd <code>폴더명</code></li>
<li>git clone <code>github상의 repository주소</code></li>
<li>cd <code>프로젝트명</code> </li>
</ol>
<ol start="4">
<li>npm install <blockquote>
<p>💡왜 npm install을 하는가? 
<span style="color:gray">  node_modules 디렉토리는 용량이 크고 <code>package.json</code>으로 대체할 수 있기때문에 <code>.gitignore</code>에 추가되어 git으로는 관리하지 않는다.
따라서 push를 하여도 github에는 올라가지않기 때문에 다른 팀원들이 clone을 받으면 필요한 패키지들이 설치되어 있지않은 상황이다.
따라서 팀원들은 패키지를 설치하기위해 <code>npm install</code> 명령어를 실행해준다.
그러면 <code>package.json</code>의 dependencies 기준으로 패키치가 설치된다.</p>
</span>
</blockquote>
</li>
</ol>
<ol start="5">
<li>git branch <code>feature/kimcoding</code>
: <span style="color:gray">  default branch인 master branch에서 작업을 하는 것이 아니라 
작업을 위한 새로운 branch를 생성해서 작업을 진행해야한다.</span>


</li>
</ol>
<ol start="6">
<li>git checkout <code>feature/kimcoding</code></li>
<li>코드 작성</li>
</ol>
<p>이것이 팀원2,3 이 동일한 과정으로 작업을 진행하게 되며 초기 세팅을 한 팀원1의 경우
이미 로컬에 레파지토리가 존재하고 있기 때문에 클론을 받을 필요는 없고 마스터 브랜치가 아닌 새로운 브랜치를 생성하여 작업을 진행한다.</p>
<hr />

<h3 id="브랜치-관리">브랜치 관리</h3>
<ol>
<li>기능 단위의 브랜치 생성 후 작업</li>
</ol>
<ul>
<li>&quot;feature/main&quot; or &quot;feature/login&quot;과 같이 브랜치를 생성</li>
<li>기능단위로 브랜치 생성 후 작업을 진행하게 되면 독립적인 공간(브랜치)에서 여러 개발자가 동시에 다양한 기능을 작업할 수 있다.</li>
<li>기능별로 브랜치 나눠서 작업 후 작업이 완료되면 master 브랜치에 병합하는 방식으로 작업을 진행할 수 있다.</li>
</ul>
<ol start="2">
<li>브랜치는 작은 단위로 나눠서 관리</li>
</ol>
<ul>
<li>브랜치는 작은 단위로 나눠서 관리하고 자주 병합하는 과정을 거치는 것이 좋다.
(왜? 하나의 브랜치에서 너무 많은 작업을 진행하게되면 최종적으로 master에 병합하는 과정에서 다른 브랜치와의 작업 이력이 겹쳐 발생하는 충돌(conflict)이 대규모로 발생한다.)</li>
</ul>
<ol start="3">
<li>feature 브랜치에서 또 다른 브랜치 생성하지 않기</li>
</ol>
<ul>
<li>브랜치들은 최종적으로 마스터에 병합되는것이 목표기에 마스터 기준으로 새로운 브랜치를 생성해야한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript]setAttribute : 요소의 속성값을 정하는 메서드]]></title>
            <link>https://velog.io/@x_sunyoung/setAttribute</link>
            <guid>https://velog.io/@x_sunyoung/setAttribute</guid>
            <pubDate>Sun, 20 Nov 2022 14:56:13 GMT</pubDate>
            <description><![CDATA[<h1 id="setattribute">setAttribute</h1>
<blockquote>
<p>기본 형태
element.setAttribute(속성명,속성값);</p>
</blockquote>
<blockquote>
<p>setAttribute() 메서드는 지정된 요소의 속성 값을 설정한다. 만약 이미 속성값을 가지고 있었다면 그 값을 지우고 새로운 값을 적용한다.</p>
</blockquote>
<p><strong>&lt;예제&gt;</strong></p>
<p>[CSS]</p>
<pre><code class="language-css"> .democlass {
color: red;
background-color: yellow;
}</code></pre>
<p>[HTML]        </p>
<pre><code class="language-html">
&lt;h1&gt;setAttribute 메서드 적용해보기&lt;/h1&gt;       
&lt;button id=&quot;button&quot; onclick=&quot;myFunction()&quot;&gt;Add Class&lt;/button&gt;

</code></pre>
<p>[JS]    </p>
<pre><code class="language-javascript"> function myFunction() {
document.getElementById(&quot;myH1&quot;).setAttribute(&quot;class&quot;, &quot;democlass&quot;); 
}
</code></pre>
<p>&lt;버튼 클릭 전&gt;
<img src="https://velog.velcdn.com/images/x_sunyoung/post/da7884d1-74a3-4bf0-9e0f-02d36fcde597/image.png" alt=""></p>
<p>&lt;버튼 클릭 후 결과&gt; 
<img src="https://velog.velcdn.com/images/x_sunyoung/post/267429fd-4cf5-4331-85c7-d869f49bbb6b/image.png" alt=""></p>
<hr/>




<h2 id="setattribute를-이용한-댓글의-하트좋아요버튼-기능-구현">setAttribute를 이용한 댓글의 하트(좋아요)버튼 기능 구현</h2>
<p>하트 버튼을 눌렀을 때 하트가 빨간색으로 색칠된 이미지가 등장하고, 다시 눌렀을 때 빈 하트가 나오도록 구현해보았다.</p>
<p>먼저, 두 하트 이미지를 준비하여 img 파일에 넣어준다.</p>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/cb8d0363-77bb-43e9-aabf-7c8ca3536700/image.png" alt=""></p>
<pre><code class="language-javascript">

  //댓글 좋아요 기능 구현

 const likeComment = newComment.querySelector(&quot;#empty_heart&quot;);

  likeComment.addEventListener(&quot;click&quot;, function () {
    let currentImg = likeComment.getAttribute(&quot;src&quot;);
    if (currentImg.includes(&quot;empty&quot;)) {
      likeComment.setAttribute(&quot;src&quot;, &quot;img/red_heart.png&quot;);
    } else {
      likeComment.setAttribute(&quot;src&quot;, &quot;img/empty_heart.png&quot;);
    }
  });
}

// 위 코드 전후로 적힌 setAttribute와 관계없는 코드들은 생략됨.
</code></pre>
<p>&lt;버튼 클릭 전&gt;
<img src="https://velog.velcdn.com/images/x_sunyoung/post/d3964243-8a58-414c-b7c2-a84b791e352e/image.png" alt=""></p>
<p>&lt;버튼 클릭 후 결과&gt; 
<img src="https://velog.velcdn.com/images/x_sunyoung/post/3e0c9376-eca9-47c0-b014-141db23f64d3/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git & GitHub]]></title>
            <link>https://velog.io/@x_sunyoung/git</link>
            <guid>https://velog.io/@x_sunyoung/git</guid>
            <pubDate>Sun, 20 Nov 2022 12:26:51 GMT</pubDate>
            <description><![CDATA[<h1 id="💡-git--github">💡 Git &amp; GitHub</h1>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/8aa1b387-9707-4d03-bd5b-34babc0a1fa2/image.png" alt=""></p>
<p>개발자라면 Git과 GitHub이 무엇인지 알고 넘어가야하며 익숙해져야하는 툴이다.</p>
<p> <strong>Git</strong>: 로컬 파일의 변경 사항을 기록하고 해당 파일에 대한 여러 사용자 간의 작업을 조율하기 위한 <code>버전 관리 시스템(VCS : Version Control System)</code>이다. 
소스 코드 관리에 주로 사용되지만 어떠한 집합의 파일 변경사항을 지속적으로 추적하기 위해 사용될 수 있다.</p>
<p><strong>Github</strong>: 깃을 클라우드 방식으로 구현된 버전 관리 시스템이다. 분산 버전 관리 툴인 깃을 사용하는 프로젝트를 지원하는 <code>웹호스팅 서비스</code>이다. </p>
<blockquote>
<p>중요한 건 Git은 local이고, github는 cloud라는 것을 기억할 것!</p>
</blockquote>
<p><strong>그렇다면 깃은 왜 써야하나?</strong></p>
<p>프로젝트를 진행함에 있어서 생성, 수정, 삭제 등 수없이 변경 사항이 발생하게 된다. 
이 때 깃은 아래와 같은 이점이 있다.</p>
<ul>
<li>이전 코드를 다시 복원 (오류가 난 코드를 되돌려야하는 상황) </li>
<li>코드의 변경 사항을 추적하여 어느 부분이 바뀌었는지를 확인 가능</li>
<li>분산 개발이 가능 ( 각 개발자의 로컬 컴퓨터로 복사하여 작업 후 합칠 수 있다)</li>
</ul>
<p><strong>깃을 사용하지 않았다면?</strong>
우리는 파일을 수정할 때 마다 &#39;다른이름으로저장&#39;하기를 여러 번 반복하여 file 명에 최종 혹은 진짜 최종, 진짜 진짜 최종 등의 이름으로 저장해서 팀원들에게 파일이 담긴 usb 파일을 넘겨주거나 메일 등의 수단을 이용해 공유해야하는데 이건 너무나 번거로운 짓이다. </p>
<hr />


<h2 id="💡-기본적인-git-명령어">💡 기본적인 Git 명령어</h2>
<p>다음은 Git을 을 사용하기 위한 몇 가지 일반적인 명령이다. 앞으로 프로젝트를 진행하면서 사용해야하는 명령어들이니 숙지하는 것이 좋겠다.</p>
<ul>
<li><code>git init</code>:  이 명령어는 프로젝트 폴더 내에 숨겨진 .git 디렉토리를 생성한다. git은 현재 저장소에 대한 모든 변경사항을 추적/관리할 수 있게된다. </li>
</ul>
<pre><code class="language-javascript">$ ls -a //  이 명령어는 숨은 폴더가 있는지 확인할 수 있는 명령어로 git 폴더가 있는지 확인할 것!
. .. .git</code></pre>
<ul>
<li><p><code>git clone</code>:  코드 복제. 기존 레파지토리를 내 로컬로 가져온다.</p>
<pre><code class="language-javascript">$ git clone [레파지토리 주소]</code></pre>
</li>
<li><p><code>git add</code> :  프로젝트 폴더에서 <code>git add [파일명]</code>라는 명력어를 사용해 우리가 원하는 파일들을 스테이징 상태로 올리는 것이다 (장바구니에 담는다고 생각하자!)</p>
</li>
<li><p><code>git status</code> : 작업폴더와 스테이징 영역의 상태를 확인하기 위해 사용 (Unstazing 또는 stazing되었는지 확인)</p>
</li>
<li><p><code>git commit</code> : 로컬 저장소에 수정사항을 반영한다.</p>
</li>
</ul>
<pre><code class="language-javascript">$ git commit -m &quot;Add: README.md revised&quot;
// -m 은 메세지의 약자이고, 뒤에 &quot;&quot;안에 공유할 메시지 내용을 적어준다.
</code></pre>
<ul>
<li><p><code>git log</code>: commit 내역을 찾아보기 위한 명령어</p>
</li>
<li><p><code>git remote</code> : 내 원격지로의 경로 연결을 위한 명령어</p>
</li>
<li><p><code>git push</code> : 나의 로컬 디렉토리로에서 origin remote로 보내기 위해서 사용하는 명령어</p>
<pre><code class="language-javascript">$ git push origin master</code></pre>
</li>
<li><p><code>git branch</code> : 독립적으로 개발을 할 수 있는 나만의 공간(브랜치)을 만든다.</p>
</li>
</ul>
<pre><code class="language-javascript">$ git branch [브랜치 이름]  </code></pre>
<ul>
<li><code>git checkout</code> : check out을 하여 branch를 넘나들 수 있는 명령어</li>
<li><code>git pull</code> : 다른 사람이 원격 저장소에 업데이트한 파일이 있을 때, 원격저장소와 내 로컬저장소의 상태를 동일하게 만들기 위해 pull을 이용한다. </li>
<li><code>git merge</code> : branch와 Master를 이어주는 명령어</li>
</ul>
<hr />
출처 

<p>-<a href="https://ifuwanna.tistory.com/193">https://ifuwanna.tistory.com/193</a><br>-<a href="https://devlog-wjdrbs96.tistory.com/5#recentEntries">https://devlog-wjdrbs96.tistory.com/5#recentEntries</a>
<a href="https://lwoongh38.github.io/github">https://lwoongh38.github.io/github</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript]  Array.filter() ]]></title>
            <link>https://velog.io/@x_sunyoung/filter</link>
            <guid>https://velog.io/@x_sunyoung/filter</guid>
            <pubDate>Sat, 12 Nov 2022 14:34:21 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트에서 Array.filter()는 배열의 요소들 중에 특정 조건을 만족하는 요소들을 모아서 새로운 배열로 리턴한다. 
아래 예제를 통해 filter()의 사용 방법에 대해서 알아보자!</p>
<p><strong>&lt;예제 1&gt;</strong>
배열 words의 요소 중에 문자열의 길이가 6보다 큰 것들만 찾아서 새로운 배열에 추가하고 리턴해보자</p>
<pre><code class="language-javascript">
const words = [&#39;lemon&#39;,&#39;banana&#39;, &#39;tomato&#39;, &#39;apple&#39;, &#39;strawberry&#39;, &#39;cherry&#39;, &#39;watermelon&#39;];

const result = words.filter(word =&gt; word.length &gt; 6);

console.log(result); // [&#39;strawberry&#39;, &#39;watermelon&#39;]
</code></pre>
<p><strong>&lt;예제 2&gt;</strong>
배열의 Number 요소 중에 value가 10보다 크거나 같은 값을 찾아 새로운 배열에 추가하고 리턴해보자.</p>
<pre><code class="language-javascript">
function isBigEnough(value) {
  return value &gt;= 10;
}


const numbersInArray = [12, 5, 8, 130, 44, 10]
const filtered = numbersInArray.filter(isBigEnough); // filter()안에 function의 이름을 넣어 해당 조건에 맞는 값 찾아낼 수 있다.


console.log(filtered) // [ 12, 130, 44, 10]
</code></pre>
<p><strong>&lt;예제3&gt;</strong> 배열의 넘버 요소중에 짝수를 찾아 새로운 배열에 추가하고 리턴해보자.</p>
<pre><code class="language-javascript">
const num = [1,2,3,4,5,6,7,8]; 

function isEven(num) {
   return num % 2 === 0;
}


// num.filter(isEven)
num.filter(isEven) // [ 2, 4, 6, 8 ]

</code></pre>
<p><strong>&lt;예제 4&gt;</strong>  오브젝트 배열 속 원하는 요소만 갖는 배열 만들어보자.</p>
<pre><code class="language-javascript">

const friends = [
  {
    name: &#39;조아랑&#39;,
    age: 30,
    job: &#39;사운드 디렉터&#39;,
    married: false,
  },
  {
    name: &#39;고다소미&#39;,
    age: 30,
    job: &#39;의류브랜드 MD&#39;,
    married: true,
  },
  {
    name: &#39;우호성&#39;,
    age: 29,
    job: &#39;회사원&#39;,
    married: false,
  },
  {
    name: &#39;서진아&#39;,
    age: 32,
    job: &#39;해외영업사원&#39;,
    married: true}
];

// 현재 싱글이면서 나이가 30살 이상인 친구를 뽑아봅시다.
const single = friends.filter((friend) =&gt; {

  return friend.married === false &amp;&amp; friend.age &gt;= 30 ;
})
console.log(&#39;현재 자유의 몸.. &#39;, single); 
</code></pre>
<p>( 결과 ) </p>
<pre><code class="language-javascript">&#39;현재 자유의 몸.. &#39; [
  {
    name: &#39;주아랑&#39;,
    age: 30,
    job: &#39;사운드 디렉터&#39;,
    married: false
  }
]</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] array - push, pop, shift,  unshift]]></title>
            <link>https://velog.io/@x_sunyoung/array</link>
            <guid>https://velog.io/@x_sunyoung/array</guid>
            <pubDate>Fri, 11 Nov 2022 05:47:06 GMT</pubDate>
            <description><![CDATA[<p>push() : 배열의 끝에 요소를 추가한다.</p>
<pre><code class="language-javascript">const arr = [1,2,3,4];
const push = arr.push(5); 
console.log(arr); // [ 1, 2, 3, 4, 5 ]
</code></pre>
<p>pop(): 배열의 마지막 요소를 제거한다</p>
<pre><code class="language-javascript">
const arr = [1,2,3,4,100];
const remove100 = arr.pop();  
console.log(remove100); // 100
console.log(arr); // [1,2,3,4] 
</code></pre>
<p>shift():  배열의 첫 번째 요소를 제거한다.</p>
<pre><code class="language-javascript">const fruits = [&quot;Apple&quot;, &quot;Banana&quot;, &quot;Orange&quot;, &quot;Strawberry&quot;];
const  shift = fruits.shift();
console.log(shift); // &#39;Apple&#39;
console.log(fruits); // [ &#39;Banana&#39;, &#39;Orange&#39;, &#39;Strawberry&#39; ]
</code></pre>
<p>unshift() : 새로운 요소를 배열의 맨 앞쪽에 추가하고 그 배열의 길이를 반환한다.</p>
<pre><code class="language-javascript">const fruits = [&quot;Apple&quot;, &quot;Banana&quot;, &quot;Orange&quot;, &quot;Strawberry&quot;];
const unshift = fruits.unshift(&quot;Grape&quot;);
console.log(unshift); // 5 =&gt; array 의 새로운 길이를 반환
console.log(fruits); // [ &#39;Grape&#39;, &#39;Apple&#39;, &#39;Banana&#39;, &#39;Orange&#39;, &#39;Strawberry&#39; ]</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] flex  정리]]></title>
            <link>https://velog.io/@x_sunyoung/flex</link>
            <guid>https://velog.io/@x_sunyoung/flex</guid>
            <pubDate>Thu, 03 Nov 2022 06:56:19 GMT</pubDate>
            <description><![CDATA[<p>우선 Flex는 2개의 개념으로 나눈다.
첫 번째는 Container 두 번째는 Items 이다. 아래 코드와 함께 살펴보자!
Container는 Items를 감싸는 부모 요소이며, <strong>각 Item을 정렬하기 위해선 Container가 필수</strong>이다.</p>
<blockquote>
<p>주의할 부분은 Container와 Items에 적용하는 속성이 구분되어 있다는 것이다.
Container에는 <code>display</code>, <code>flex-flow</code>, <code>justify-content</code> 등의 속성을 사용할 수 있으며,
Items에는 <code>order</code>, <code>flex</code>, <code>align-self</code> 등의 속성을 사용할 수 있다.</p>
</blockquote>
<p><code>주 축(main-axis)</code>과 <code>교차 축(cross-axis)</code>의 개념 :</p>
<p>값 row는 Items를 수평축으로 표시하므로 이때는 주 축이 수평이며 교차 축은 수직이 된다.
반대로 값 column은 Items를 수직축으로 표시하므로 주 축은 수직이며 교차 축은 수평이 된다.
즉, 방향(수평, 수직)에 따라 주 축과 교차 축이 달라진다.
<img src="https://velog.velcdn.com/images/x_sunyoung/post/5d171fd8-1054-4861-be7e-cd6d6116f793/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/36d42732-ab81-4f67-943a-38d09ef30225/image.png" alt=""></p>
<p>[HTML]</p>
<pre><code class="language-html">
    &lt;link rel=&quot;stylesheet&quot; href=&quot;css.css&quot; /&gt;
  &lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
      &lt;div class=&quot;item&quot;&gt;1&lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;2&lt;/div&gt;
      &lt;div class=&quot;item&quot;&gt;3&lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;

</code></pre>
<p>[CSS]</p>
<pre><code class="language-css">.container {
  width: 800px;
  height: 400px;
  border: 4px solid black;
  background-color: slategrey;
  /* flex - 정렬을 위한 컨테이너  */
  display: flex;

  /* 주축(좌에서 우로) 방향 정렬 */
  justify-content: center;

  /* 교차측(위에서 아래로) 방향 정렬 */
  align-items: center;
}

.item {
  margin: 10px;

  width: 100px;
  height: 100px;
  border: 4px solid black;
  background-color: hotpink;
  font-size: 60px;

  /* 숫자도 박스 안에 가운데 정렬하고싶다면 */
  display: flex;
  justify-content: center;
  align-items: center;
}
</code></pre>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/ba9983b7-9421-4b77-a01c-3abe2d765c17/image.png" alt=""></p>
<blockquote>
<p>item들을 세로로 정렬하고 container의 오른쪽 끝 점에 고르게 정렬해보자!</p>
</blockquote>
<pre><code class="language-css">.container {
  width: 800px;
  height: 500px;
  border: 4px solid black;
  background-color: slategrey;
  /* flex - 정렬을 위한 컨테이너  */
  display: flex;
  flex-direction: column;
  /* 주 축 방향 정렬 */
  justify-content: space-between;

  /* 교차측 방향 정렬 */
  align-items: flex-end;
}</code></pre>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/842d7e32-5a12-4f32-91ca-7a312a8ad02c/image.png" alt=""></p>
<p>출처 : 
<a href="https://heropy.blog/2018/11/24/css-flexible-box/">https://heropy.blog/2018/11/24/css-flexible-box/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Array.map() 메서드]]></title>
            <link>https://velog.io/@x_sunyoung/array.map</link>
            <guid>https://velog.io/@x_sunyoung/array.map</guid>
            <pubDate>Mon, 31 Oct 2022 06:47:26 GMT</pubDate>
            <description><![CDATA[<p><code>map()</code> 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.</p>
<blockquote>
<p> 구문 : 
arr.map(callback(currentValue[, index[, array]])[, thisArg])</p>
</blockquote>
<p> 여기서 콜백함수는 세 가지 인자를 전달하고 두 번째로 this값을 인자로 받을 수 있다.
 각 각 다음과 같이 사용된다.</p>
<ul>
<li><p>current value // 현재 반환할 값</p>
</li>
<li><p>index // <code>Option</code>, 현재 해당하는 인덱스의 값</p>
</li>
<li><p>array //<code>Option</code>, 배열에 접근 가능</p>
</li>
<li><p>this // <code>Option</code>, 사용할 this 키워드의 값</p>
</li>
</ul>
<p>이처럼 위에서 value, array, this는 선택 가능한 옵션값입니다</p>
<p><strong>&lt; map메서드를 이용한 예제1 &gt;</strong></p>
<pre><code class="language-javascript">const nums = [1, 2, 3];
const newNums = nums.map(x =&gt; x * x);

console.log(newNums); // [ 2, 4, 6 ]
</code></pre>
<p><strong>&lt; map메서드를 이용한 예제2 &gt;</strong></p>
<pre><code class="language-javascript">
const sites = [
  { id: 1, name: &#39;윤선영&#39;},
  { id: 2, name: &#39;김개발&#39;},
  { id: 3, name: &#39;박코딩&#39;},
];

const newSites = sites.map(site =&gt; site[&#39;id&#39;] + &#39; - &#39; + site[&#39;name&#39;]);
console.log(newSites);
// 결과 : [ &#39;1 - 윤선영&#39;, &#39;2 - 김개발&#39;, &#39;3 - 박코딩&#39; ]</code></pre>
<p><strong>&lt; map메서드를 이용한 예제3 &gt;</strong></p>
<pre><code class="language-javascript">const test = [
  { coffee : &quot;아이스 아메리카노&quot;, brand : &quot;스타벅스&quot;},
  { coffee : &quot;블루베리 스무디&quot;, brand : &quot;투썸&quot;},
  { coffee : &quot;녹차 라떼&quot;, brand : &quot;할리스&quot;}
];

const newArray = test.map(test =&gt; test.coffee+ &#39; : &#39; + test.brand);

console.log(newArray);

// 결과 : [ &#39;아이스 아메리카노 : 스타벅스&#39;, &#39;블루베리 스무디 : 투썸&#39;, &#39;녹차 라떼 : 할리스&#39; ]</code></pre>
<p><strong>&lt; map메서드를 이용한 예제4&gt;</strong></p>
<pre><code class="language-javascript">
// &lt; map을 이용해서 string을 숫자로 바꿔보자 &gt;

const str = [&#39;100&#39;,&#39;200&#39;,&#39;300&#39;,&#39;400&#39;]

str.map(str =&gt; parseInt(str));// [ 100, 200, 300, 400 ]
str.map(Number);[ 100, 200, 300, 400 ]


//
</code></pre>
<blockquote>
<p><code>.split().</code> : 문자열을 분할하여 배열에 담는 메서드이다.</p>
</blockquote>
<ul>
<li>구문 : string.split( separator, limit )</li>
<li>separator 에는 분할의 기준을 넣는다. Ex)     <code>&#39;-&#39;</code>, <code>&#39;:&#39;</code>, <code>&#39;=&#39;</code> 와 같은;
limit으로 최대 분할 개수를 정할수있다. 선택 사항으로, 값을 정하지 않으면 전체를 다 분할한다.
👇🏻 아래 예제5번에서 <code>split</code>메서드를 활용하여 문자열을 분할하여 배열에 담는것을 확인할 수 있다.</li>
</ul>
<p><strong>&lt; map메서드와 split 메서드를 사용한 예제 5&gt;</strong></p>
<pre><code class="language-javascript">// string으로 선언된 변수가 숫자로 이루어진 string 타입의 문자열이다. 이것을 number 타입으로 배열 안에 담아보자!


const string = &quot;100 200 300 400&quot; 
string.split(&#39; &#39;)// [ &#39;100&#39;, &#39;200&#39;, &#39;300&#39;, &#39;400&#39; ] 

const result  = string.split(&#39; &#39;).map((x) =&gt; Number(x));// 
console.log(result); // [ 100, 200, 300, 400 ]</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] indexOf 함수]]></title>
            <link>https://velog.io/@x_sunyoung/indexOf</link>
            <guid>https://velog.io/@x_sunyoung/indexOf</guid>
            <pubDate>Fri, 28 Oct 2022 07:07:13 GMT</pubDate>
            <description><![CDATA[<p><code>indexOf(&quot;찾을 문자열&quot;)</code></p>
<p>찾은 문자열의 시작 위치를 반환한다. 찾을 문자열이 없을 경우 -1을 반환한다.</p>
<p><code>indexOf(&quot;찾을 문자열&quot;, &quot;시작 위치&quot;)</code></p>
<p>찾을 위치를 두 번째 인자에 부여하면 시작 위치부터 문자열을 찾는다.</p>
<p>아래 예제를 통해 확인해보자.</p>
<pre><code class="language-javascript">var str = &#39;저는클로이입니다.예제니까클로이한번더넣을게요&#39;;

//indexOf(&quot;찾을 문자열&quot;)
var result1 = str.indexOf(&#39;클로이&#39;);
console.log(result1); // 결과 : 2

//indexOf(&quot;찾을 문자열&quot;, &quot;시작 위치&quot;)
var result2 = str.indexOf(&#39;클로이&#39;,3) 
console.log(result2); // 결과 :  13 (&quot;시작 위치&quot;를 index 3으로 입력하였기때문에 str문자열에서 두번째 클로이의 인덱스 13이 반환된다.)

//찾는 문자열이 없을 경우 결과는 -1 이다.
var result3 = str.indexOf(&#39;에밀리&#39;);
console.log(result3); // 결과 : -1
</code></pre>
<blockquote>
<p><code>str</code>의 전체 문장에서 <code>클로이</code>라는 문자열은 2개가 존재한다. 
<code>result1</code> 과 <code>result2</code>는 동일하게 &#39;클로이&#39;라는 문자열을 찾지만 결과는 다르다. 
_왜? _<code>문자열의 시작 위치</code>를 입력했는지에 대한 여부에 따라 반환하는 index가 달라지기 때문이다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] array의 splice & slice 함수 정리]]></title>
            <link>https://velog.io/@x_sunyoung/spliceslice</link>
            <guid>https://velog.io/@x_sunyoung/spliceslice</guid>
            <pubDate>Fri, 28 Oct 2022 05:26:19 GMT</pubDate>
            <description><![CDATA[<h2 id="array의-splice">array의 Splice</h2>
<p>자바스크립트의 배열(Array) 객체에서 제공되는 함수인 splice를 이용하면 원하는 위치에 요소를 추가하거나 삭제할 수 있다. </p>
<blockquote>
<p>문법 :    array.splice(start[, deleteCount[, item1[, item2[, ...]]]])</p>
</blockquote>
<p>splice 함수를 사용해 요소를 삭제하고 원하는 위치에 요소를 추가하는 것을 정리해보았다.</p>
<blockquote>
<ol>
<li>배열에서 원하는 요소 제거하기 </li>
</ol>
</blockquote>
<pre><code class="language-javascript">
// 배열에서 3을 지워보자
const a = [1,2,3,4,5]

a.splice(2,1) // [3] : 삭제되는 요소 반환한다.
console.log(a); // [ 1, 2, 4, 5 ] : &#39;a&#39; 배열을 다시 콘솔로 찍으면 바뀐 배열을 볼 수 있다.
</code></pre>
<blockquote>
<ol start="2">
<li>배열에서 요소를 제거 + 원하는 위치에 다른 값 넣어보기</li>
</ol>
</blockquote>
<pre><code class="language-javascript">// 배열안에 4,5를 지우고 10,11 을 넣어보자
const newA = [1,2,4,5]
newA.splice(2,2,10,11) // [4,5] : 삭제되는 요소 반환한다.
console.log(newA); // [1,2,10,11] : index 2부터 2개의 값 &#39;4,5&#39;을 삭제하고, &#39;10,11&#39; 요소가 추가됨을 확인할 수 있다.

</code></pre>
<hr/>


<h2 id="array의-slice">array의 Slice</h2>
<p>배열의 일부분을 잘라내어, 새로운 배열로 리턴하기 위해서는 slice() 함수를 사용한다.</p>
<blockquote>
<p>문법 : arr.slice([begin[, end]])</p>
</blockquote>
<pre><code class="language-javascript">const array = [1,2,3,4,5,6]

// array 배열에서 3~6 까지의 요소만을 반환시켜보자.

array.slice(2,6) // [3,4,5,6] 잘라낼 배열의 시작index와 end index를 파라미터로 받아 새로운 배열을 return 한다.
console.log(array);  // [1,2,3,4,5,6] 이때 원본 배열인 array는 변경되지 않는다.</code></pre>
<pre><code class="language-javascript">// index 를 음수를 넣었을 때 결과값 확인해보자!

const stringArray = [&#39;사과&#39;,&#39;바나나&#39;,&#39;토마토&#39;,&#39;포도&#39;,&#39;메론&#39;,&#39;오렌지&#39;]

const result1 = stringArray.slice(-5) 
const result2 = stringArray.slice(-5,-2)

console.log(result1) // [ &#39;바나나&#39;, &#39;토마토&#39;, &#39;포도&#39;, &#39;메론&#39;, &#39;오렌지&#39; ]
console.log(result2) // [ &#39;바나나&#39;, &#39;토마토&#39;, &#39;포도&#39; ]
console.log(stringArray); // [ &#39;사과&#39;, &#39;바나나&#39;, &#39;토마토&#39;, &#39;포도&#39;, &#39;메론&#39;, &#39;오렌지&#39; ]</code></pre>
<p>아래 빨간색으로 표시된 index를 같이 보면 위의 결과가 좀 더 이해가 잘 될 것이다.</p>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/6af8ab07-44ea-4891-b8e0-5e45f3238b51/image.png" alt=""></p>
<ul>
<li><code>result1</code> 은 <code>slice</code>함수에 시작index만 넣어주었다. 이 경우 -5 index 부터 
배열의 끝에 있는 요소까지의 구간을 반환시킨다.</li>
<li><code>result2</code> 은 <code>slice</code>함수에 시작index와 end index를 모두 넣어주었다. 지정해준 구간의 배열이 반환됨을 확인할 수 있었다.</li>
<li>⭐️ <code>slice</code>함수를 사용할 경우 - 원본 배열인 <code>stringArray</code>는 변경되지 않는다는 것이 <code>splice</code>와 차이점이다.(<code>splice</code>는 배열 안 기존 요소 삭제/ 다른 요소 추가 후에 원본 배열을 console.log로 찍어보면 바뀐 배열을 반환한다!)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] isEven]]></title>
            <link>https://velog.io/@x_sunyoung/isEven</link>
            <guid>https://velog.io/@x_sunyoung/isEven</guid>
            <pubDate>Thu, 20 Oct 2022 07:15:12 GMT</pubDate>
            <description><![CDATA[<p><code>isEven</code> 함수는 주어진 숫자가 짝수인지의 여부를 반환한다.
<code>나머지 연산자(%)</code>를 활용하여 아래와 같이 홀/짝인지 확인할 수 있는 코드를 짤 수 있다.</p>
<pre><code class="language-javascript">
function isEven(value) {
    if (value%2 === 0)
        return true;
    else
        return false;
}


const output = isEven(11);
console.log(output);  // false

const output = isEven(12);
console.log(output);  // true

</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Javascript] null vs undefined]]></title>
            <link>https://velog.io/@x_sunyoung/nullundefined</link>
            <guid>https://velog.io/@x_sunyoung/nullundefined</guid>
            <pubDate>Tue, 18 Oct 2022 07:58:30 GMT</pubDate>
            <description><![CDATA[<p><code>null</code>과 <code>undefined</code>는 모두 자바스크립트의 데이터 타입이다.</p>
<p><code>undefined</code>는 변수를 선언하고 값을 할당하지 않은 상태. 즉, 자료형이 없는 상태.
<code>null</code>은 변수를 선언하고 빈 값을 할당한&#39;빈 값(blank)&#39;을 할당한 상태이다. 
따라서 typeof를 통해 자료형을 확인해보면     <code>null</code>은 object로, <code>undefined</code>는 undefined가 출력되는 것을 확인할 수 있다.</p>
<blockquote>
<p>포괄적인 의미로 &#39;값이 없다&#39;는 점에서 null과 undefined가 비슷한 것 같지만, 엄밀히 말하자면 둘은 같지 않다.</p>
</blockquote>
<blockquote>
<p>이렇게 생각하자, 어떤 상자에 이름을 붙였냐 아직 붙이지 않았냐로 따진다면 
undefined는 이름을 붙이지 않은 상태(value를 할당하지 x) 인거고, null은 은 이름을 붙인 상태인 것이다 (아래 그림 참고!)
<img src="https://velog.velcdn.com/images/x_sunyoung/post/0a89920a-47a8-4c5d-8c72-810890426735/image.png" alt=""></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] Position]]></title>
            <link>https://velog.io/@x_sunyoung/position</link>
            <guid>https://velog.io/@x_sunyoung/position</guid>
            <pubDate>Sun, 16 Oct 2022 01:02:03 GMT</pubDate>
            <description><![CDATA[<h2 id="position--static">position : static</h2>
<p><code>static</code> : 기본값이다.  position 프로퍼티를 지정하지 않았을 때와 같다.
기본적으로 이 값을 지정할 일은 없지만 이미 설정된 position을 무력화하기 위해 사용될 수 있다.</p>
<h2 id="position--relative">position : relative</h2>
<p><code>relative</code> : 별도의 프로퍼티를 지정하지 않는 이상 static과 동일하게 동작한다
상대 위치가 지정된 엘리먼트에 <code>top</code>이나 <code>right</code>, <code>bottom</code>, <code>left</code>를 지정하면 기본 위치와 다르게 위치가 조정된다. 다른 콘텐츠는 해당 엘리먼트에서 남긴 공백에 맞춰 들어가게끔 조정되지 않을 것이다.</p>
<pre><code class="language-css">
.relative1 {
  position: relative;
  border: 3px solid red;
  padding: 15px;
}
.relative2 {
  position: relative;
  top: -20px;
  left: 20px;
  background-color: white;
  width: 500px;
  border: 3px solid blue;
  padding: 10px;
}
</code></pre>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/aa4758d1-2150-465e-879b-37942f1a36e4/image.png" alt=""></p>
<h2 id="position--fixed">position : fixed</h2>
<p><code>fixed</code> : 이 엘리먼트는 뷰포트(viewport)에 상대적으로 위치가 지정되는데, 이는 페이지가 스크롤되더라도 늘 같은 곳에 위치한다는 뜻이다. <code>relative</code>와 마찬가지로 <code>top</code>이나 <code>right</code>, <code>bottom</code>, <code>left</code> 프로퍼티가 사용되어야한다.</p>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/c9ab87df-e230-4482-938a-cf5cd10e31e9/image.png" alt=""></p>
<p>스크롤을 내렸을때 fixed가 적용된 엘리먼트는 저 위치를 유지한채 그대로 보여진다.</p>
<h2 id="position-absolute">position: absolute</h2>
<p><code>absolute</code>는 가장 다루기 까다로운 위치 지정 값이다.</p>
<blockquote>
<p>부모 요소 또는 가장 가까이 있는 조상 요소(static 제외)를 기준으로 좌표 프로퍼티(<code>top</code>, <code>bottom</code>, <code>left</code>, <code>right</code>)만큼 이동한다. 
즉, relative, absolute, fixed 프로퍼티가 선언되어 있는 <strong>부모 또는 조상 요소를 기준으로 위치가 결정된다.</strong>
따라서,  부모 요소를 배치의 기준으로 삼기 위해서는 부모 요소에 <code>relative</code>를 정의하여야 한다.
이때 다른 요소가 먼저 위치를 점유하고 있어도 뒤로 밀리지 않고 덮어쓰게 된다. (이런 특성을 부유 또는 부유 객체라 한다)</p>
</blockquote>
<pre><code class="language-css">.relative {
  position: relative;
  width: 600px;
  height: 400px;
  border: 3px solid red;
}
.absolute {
  position: absolute;
  border: 3px solid rgb(40, 189, 72);
  top: 120px;
  right: 0;
  width: 300px;
  height: 200px;
}
</code></pre>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/aacbd72a-07fc-4e7b-9dd7-e57d25f7fb01/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] float & clear]]></title>
            <link>https://velog.io/@x_sunyoung/float</link>
            <guid>https://velog.io/@x_sunyoung/float</guid>
            <pubDate>Sat, 15 Oct 2022 22:54:54 GMT</pubDate>
            <description><![CDATA[<h2 id="float">float</h2>
<p><code>float</code> 속성은 정렬을 위해 사용하는 속성이다.
일반적인 정렬과는 다르게 float 정렬된 것 주위로 다른 컨텐츠가 흐르듯이 배치가 된다.
즉 공간은 차지하지만 다른 element들의 배치에 영향을 안주는 element가 되는 것이다.</p>
<blockquote>
<p>float 의 사전적 의미는 &#39;뜨다&#39;,&#39;뜨는 물건&#39;이라는 의미를 가지고 있다.</p>
</blockquote>
<p><code>float</code>에서 사용할 수 있는 값 : <code>left</code>,<code>right</code>,<code>none</code> </p>
<p><code>float</code> 속성을 사용할 수 있는 태그 :기본적으로 block element에서만 사용 가능하다.
ex) <code>&lt;div&gt;</code>, <code>&lt;p&gt;</code>, <code>&lt;ul&gt;</code>, <code>&lt;table&gt;</code>, <code>&lt;img&gt;</code> 등</p>
<p>아래 예시를 보며 정리해보자!</p>
<blockquote>
<p>아래의 고양이<code>img</code>태그에 <code>float: right</code> 를 적용시켜보았더니 이미지가 오른쪽으로 정렬되고 
텍스들은 이미지 기준 왼쪽으로 배치가 된 것을 볼 수 있다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/ceb100a8-b99a-4cff-948e-e7ba10337aa0/image.png" alt=""> </p>
<pre><code class="language-css">img {
  height: 200px;
  float: right;
}
</code></pre>
<p>위와 같이 문단이 두개가 있다. 첫번째 문단은 이미지의 <code>float</code> 영향을 받았지만 두번째 문단은 <code>float</code> 적용을 피하고 싶다면? 아래와 같이  <code>clear</code> 속성을 사용하면 된다. </p>
<pre><code class="language-css">  img {
  height: 200px;
  float: right;
}

.secondContent {
  clear: both;
}
</code></pre>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/19d06b1d-dd26-4a71-89b8-c68951ed71a7/image.png" alt=""></p>
<p><code>clear</code>의 속성 종류는 아래와 같다.
<code>none</code>: 기본값
<code>left</code> : 왼쪽에 float된 요소의 아랫줄에 위치 시킴.
<code>right</code> : 오른쪽에 float된 요소의 아랫줄에 위치 시킴.
<code>both</code> : 양쪽에 float된 요소 모두의 아랫줄 위치시킴. (자주 사용됨)
<code>initial</code>: 이 속성의 기본값으로 설정.
<code>inherit</code>: 부모요소 속성값 상속.</p>
<p>출처: <a href="https://includestdio.tistory.com/34">https://includestdio.tistory.com/34</a> [includestdio:티스토리]
출처: <a href="https://ko.wikipedia.org/wiki/%EA%B3%A0%EC%96%91%EC%9D%B4">https://ko.wikipedia.org/wiki/%EA%B3%A0%EC%96%91%EC%9D%B4</a> </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTML] Table ]]></title>
            <link>https://velog.io/@x_sunyoung/table</link>
            <guid>https://velog.io/@x_sunyoung/table</guid>
            <pubDate>Wed, 12 Oct 2022 03:38:45 GMT</pubDate>
            <description><![CDATA[<p>테이블을 표현하기 위해서 여러 태그들의 조합이 필요하다.</p>
<p><code>&lt;table&gt;</code>,<code>&lt;thead&gt;</code>, <code>&lt;tbody&gt;</code>, <code>&lt;tr&gt;</code>, <code>&lt;th&gt;</code>, <code>&lt;td&gt;</code> 등의 태그를 이용하여 하나의 테이블을 완성시킬 수 있다.</p>
<h2 id="테이블에-제목-추가">테이블에 제목 추가</h2>
<pre><code class="language-html">&lt;table class=&quot;borderTable&quot;&gt;
  &lt;tr&gt;
    &lt;th&gt;&lt;/th&gt;
    &lt;th&gt;Dog&lt;/th&gt;
    &lt;th&gt;Cat&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th&gt;종&lt;/th&gt;   
    &lt;td&gt;Canine&lt;/td&gt;
    &lt;td&gt;Feline&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th&gt;짖는소리&lt;/th&gt;
    &lt;td&gt;Bark&lt;/td&gt;
    &lt;td&gt;Meow&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;th&gt;Immature&lt;/th&gt;
    &lt;td&gt;Puppy&lt;/td&gt;
    &lt;td&gt;Kitten&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;</code></pre>
<p>결과는 아래 화면과 같다.</p>
<blockquote>
<p><code>&lt;th&gt;</code> :  table heading의 줄임말로 테이블 안에서 가운데 정렬이되고 글씨가 두꺼워진다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/x_sunyoung/post/47550be9-1b3f-4aba-ab15-643944860d66/image.png" alt=""></p>
<hr >

<h2 id="css를-이용하여-테이블에-선-추가">css를 이용하여 테이블에 선 추가</h2>
<pre><code class="language-css">table {
  border-collapse: collapse;
}

.borderTable th,
.borderTable td {
  border: 1px solid black;
}</code></pre>
<p>선이 생기니 테이블이 좀 더 예뻐졌다!
<img src="https://velog.velcdn.com/images/x_sunyoung/post/6b816702-e28c-4867-941b-5dc08eeb047d/image.png" alt=""></p>
<hr>


<h2 id="셀-병합---열-병합">셀 병합 /  열 병합</h2>
<blockquote>
<p>병합은 <code>&lt;td&gt;</code> 나 <code>&lt;th&gt;</code> 태그에 colspan, rowspan 이라는 attribute를 추가해서 구현할 수 있다.</p>
</blockquote>
<p><code>colspan</code>은 세로로 정보를 읽고 싶을때 사용하는데 그 결과 가로 방향(➡️)으로 셀이 합쳐진다.
<code>rowspan</code>은 가로로 정보를 읽고 싶을 때 사용하고 그 결과 세로 방향(⬇️)으로 셀이 합쳐진다.</p>
<p>이해를 돕기 위해 아래 예제를 확인하자!
(실제로 아래 과제는 내가 직접 짠 코드이다)
<img src="https://velog.velcdn.com/images/x_sunyoung/post/82eeaf45-0a93-4d1c-891f-76516ea8a564/image.png" alt=""></p>
<pre><code class="language-html"> &lt;h1&gt; Assignment - table 직접 만들어보기! &lt;/h1&gt;
  &lt;table class=&quot;assignmentTable&quot;&gt;
    &lt;tr&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;td&gt;1pm&lt;/td&gt;
      &lt;td&gt;2pm&lt;/td&gt;
      &lt;td&gt;3pm&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Gym&lt;/th&gt;
      &lt;td&gt;Dodge ball&lt;/td&gt;
      &lt;td&gt;Kick boxing&lt;/td&gt;
      &lt;td&gt;Sack racing&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Exercise Room&lt;/th&gt;
      &lt;td&gt;Spinning&lt;/td&gt;
      &lt;td class=&quot;bgcolorGray&quot; colspan=&quot;2&quot;&gt;Yoga marathon&lt;/td&gt; /
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Pool&lt;/th&gt;
      &lt;td class=&quot;bgcolorGray&quot; colspan=&quot;3&quot;&gt;Water polo&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
  &lt;br&gt;</code></pre>
<pre><code class="language-css">table {
  border-collapse: collapse;
}

.assignmentTable {
  width: 500px;
}
.assignmentTable th, .assignmentTable td{
  border: 1px solid black;
  font-weight: unset;
  text-align: left;
}

.bgcolorGray {
  background-color:#c9c6c6;
}</code></pre>
<p>추가로 테이블에 부분적으로 색상을 입히고 싶다면 아래와 같은 방법이 있다.</p>
<blockquote>
</blockquote>
<ol>
<li>HTML 에서 아래와 같이 attribute를 사용하여 색을 입힌다.(css에서 별도 작업 필요x)
<code>bgcolor</code>=&quot;color_name | hex_number | rgb_number&quot;&gt;</li>
<li><code>th</code>나 <code>td</code>에 class name을 지정하여 해당 클래스를 css에서 셀렉터하여 색을 입힌다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] 순서를 이용한 선택자 : nth / first or last-child
]]></title>
            <link>https://velog.io/@x_sunyoung/selector</link>
            <guid>https://velog.io/@x_sunyoung/selector</guid>
            <pubDate>Wed, 12 Oct 2022 01:19:52 GMT</pubDate>
            <description><![CDATA[<p>CSS selector를 표기하는 방법중에 해당 태그의 첫 번째 순서인지, 마지막 순서인인지,</p>
<p>홀수/짝수 인지 등을 알 수 있는 다양한 selector 표기법이 있다. </p>
<p>⭐️ 다시 짚고 넘어가자ㅡ selector는 <code>tag</code>, <code>.class</code>, <code>#id</code> 모두 가능하다!⭐️</p>
<blockquote>
<p><code>:nth-child(N)</code> = 부모안에 모든 요소 중 N번째 요소
<code>:nth-child(odd)</code> = 부모안에 모든 요소 중 홀수 요소
<code>:nth-child(even)</code> = 부모안에 모든 요소 중 짝수 요소
<code>A:nth-of-type(N)</code> = 부모안에 A라는 요소 중 N번째 요소</p>
</blockquote>
<p><code>:first-child</code> = 부모안에 모든 요소 중 첫번째 요소
<code>:last-child</code> = 부모안에 모든 요소 중 마지막 요소
<code>A:first-of-type</code>= 부모안에 A라는 요소 중 첫번째 요소
<code>A:last-of-type</code>= 부모안에 A라는 요소 중 마지막 요소</p>
<p>좀 더 심화된 버전이니 아래 참고하자!</p>
<blockquote>
<p><code>:nth-child(2n)</code> = 두번째 마다 선택
<code>:nth-child(2n+1)</code> = 첫번째 요소부터 2번째 마다 선택
<code>:nth-child(2n+5)</code> = 다섯번째 부터 2개 마다 선택
<code>:nth-child(n+5)</code> = 5번째 부터 모두 선택</p>
</blockquote>
<p><strong>특정 선택자를 제외하고</strong> 모든 요소에 스타일을 적용하고싶다면? 아래 예제의 코드를 활용하자!</p>
<p> 
첫번째 자식 요소를 제외한 나머지 요소에 컬러값을 적용한다.👇🏻</p>
<pre><code class="language-css">ul li:not(:first-of-type) {
  color: red;
}</code></pre>
<p> 
마지막 자식 요소를 제외한 나머지 요소에 아래에 여백을 적용한다.👇🏻</p>
<pre><code class="language-css">ul li:not(:last-of-type) {
  margin-bottom: 20px;
}</code></pre>
<p>출처: <a href="https://hohoya33.tistory.com/145">https://hohoya33.tistory.com/145</a> [개발 메모장:티스토리]</p>
]]></description>
        </item>
    </channel>
</rss>