<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>wheezy.log</title>
        <link>https://velog.io/</link>
        <description> 🧀 개발을 하면서 도움이 되었던 부분을 기록하는 공간입니다 🧀</description>
        <lastBuildDate>Thu, 22 Sep 2022 08:12:47 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>wheezy.log</title>
            <url>https://images.velog.io/images/wheezy_han/profile/9dd990ad-552d-44fa-8199-90df6d7b34db/위지.PNG</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. wheezy.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/wheezy_han" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[react] tooltip 적용]]></title>
            <link>https://velog.io/@wheezy_han/react-tooltip-%EC%A0%81%EC%9A%A9</link>
            <guid>https://velog.io/@wheezy_han/react-tooltip-%EC%A0%81%EC%9A%A9</guid>
            <pubDate>Thu, 22 Sep 2022 08:12:47 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>리스트형 목록 화면에서 이름이 긴 value에 대해서는 일정 길이 이상이 되면 <code>...</code> 표출 후 tooltip으로 value 값을 표출하는 것을 했다.</p>
<h1 id="value-제한">value 제한</h1>
<pre><code class="language-js">const test = [
  {id: 0,
   name: kim,
   city: 서울특별시 마포구 연남동
  },
  {id: 1,
   name: lee,
   city: 서울특별시 송파구 가락동
  },
  {id: 2,
   name: han,
   city: 서울특별시 도봉구 쌍문동
  }
];

&lt;div&gt;
          {test.city.substr(0, 7) + &quot;...&quot;} // 원하는 만큼 길이 제한
&lt;/div&gt;</code></pre>
<h1 id="tooltip-적용">tooltip 적용</h1>
<h2 id="tooltip-설치">tooltip 설치</h2>
<pre><code class="language-bash">$ npm install react-tooltip</code></pre>
<h2 id="적용">적용</h2>
<p>아래에서 핵심은 아래이다. 아래를 해주지 않으면 모든 data가 한번에 뜨는 오류가 있었다.</p>
<pre><code class="language-js">data-html={true} data-tip={test.city}</code></pre>
<pre><code class="language-js">import ReactTooltip from &quot;react-tooltip&quot;;

 &lt;div data-html={true} data-tip={test.city} data-for=&quot;cityTip&quot;&gt;
          {test.city.substr(0, 7) + &quot;...&quot;}
          &lt;ReactTooltip id=&quot;cityTip&quot; place=&quot;top&quot; effect=&quot;solid&quot; multiline={true}/&gt;
  &lt;/div&gt;
</code></pre>
<h2 id="길이가-길은-value값에만-tooltip-적용">길이가 길은 value값에만 tooltip 적용</h2>
<p>위와 같이 적용하면 길이가 짧아도 tooltip이 적용된다. 좀 더 깔끔하게 길이가 길은 value값에만 tooltip을 적용을 아래와 같이 조건을 적용하면 된다.</p>
<pre><code class="language-js">{
  test.city.length &gt; 7
 ?
    &lt;div data-html={true} data-tip={test.city} data-for=&quot;cityTip&quot;&gt;
          {test.city.substr(0, 7) + &quot;...&quot;}
          &lt;ReactTooltip id=&quot;cityTip&quot; place=&quot;top&quot; effect=&quot;solid&quot; multiline={true}/&gt;
    &lt;/div&gt;
:
      &lt;div&gt;
        {test.city}
    &lt;/div&gt;
}</code></pre>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://github.com/wwayne/react-tooltip#readme">https://github.com/wwayne/react-tooltip#readme</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React]useEffect 초기 렌더링 방지하는 법]]></title>
            <link>https://velog.io/@wheezy_han/ReactuseEffect-%EC%B4%88%EA%B8%B0-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%B0%A9%EC%A7%80%ED%95%98%EB%8A%94-%EB%B2%95</link>
            <guid>https://velog.io/@wheezy_han/ReactuseEffect-%EC%B4%88%EA%B8%B0-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%B0%A9%EC%A7%80%ED%95%98%EB%8A%94-%EB%B2%95</guid>
            <pubDate>Wed, 21 Sep 2022 09:22:58 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-js">const useDidMountEffect = (func, deps) =&gt; {
    const didMount = useRef(false);

    useEffect(() =&gt; {
        if (didMount.current) func();
        else didMount.current = true;
    }, deps);
}

useDidMountEffect(() =&gt; {
   // 원하는 함수
    }, [state.key]);    </code></pre>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://stackoverflow.com/questions/53253940/make-react-useeffect-hook-not-run-on-initial-render/63776262#63776262">https://stackoverflow.com/questions/53253940/make-react-useeffect-hook-not-run-on-initial-render/63776262#63776262</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[mybatis] string 값 timestamp로 변경(milliseconds format)]]></title>
            <link>https://velog.io/@wheezy_han/mybatis-string-%EA%B0%92-timestamp%EB%A1%9C-%EB%B3%80%EA%B2%BDmilliseconds-format</link>
            <guid>https://velog.io/@wheezy_han/mybatis-string-%EA%B0%92-timestamp%EB%A1%9C-%EB%B3%80%EA%B2%BDmilliseconds-format</guid>
            <pubDate>Tue, 30 Aug 2022 03:28:06 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>insert 시 <code>2022-08-30 11:16:47.000</code> 이와 같은 형식이 string으로 되어 있을 때 
DB등록 시 timestamp형식으로 바꿔야 했다.</p>
<h2 id="잘못된-예">잘못된 예</h2>
<pre><code>&lt;insert parameterType=&quot;testDto&quot;&gt;
        INSERT INTO public.&quot;tbl&quot;
        (
        &lt;trim suffixOverrides=&quot;,&quot;&gt;
            &quot;ID&quot;,
            &quot;REGIST_ID&quot;,
            &quot;REGIST_DT&quot;,
            &quot;UPDT_ID&quot;,
            &quot;UPDT_DT&quot;
        &lt;/trim&gt;
        ) VALUES (
        &lt;trim suffixOverrides=&quot;,&quot;&gt;
            #{id},
            #{registId},
            #{registDt},
            #{updtId},
            now()
        &lt;/trim&gt;
        )
    &lt;/insert&gt;</code></pre><h2 id="해결된-예">해결된 예</h2>
<pre><code>&lt;insert parameterType=&quot;testDto&quot;&gt;
        INSERT INTO public.&quot;tbl&quot;
        (
        &lt;trim suffixOverrides=&quot;,&quot;&gt;
            &quot;ID&quot;,
            &quot;REGIST_ID&quot;,
            &quot;REGIST_DT&quot;,
            &quot;UPDT_ID&quot;,
            &quot;UPDT_DT&quot;
        &lt;/trim&gt;
        ) VALUES (
        &lt;trim suffixOverrides=&quot;,&quot;&gt;
            #{id},
            #{registId},
            // 여기를 그냥 #{registDt}하면 timestamp 오류 발생
            To_TIMESTAMP(#{registDt},&#39;YYYY-MM-DD HH24:mi:ss.SSSSSX&#39;),
            #{updtId},
            now()
        &lt;/trim&gt;
        )
    &lt;/insert&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Git] 원격에 올라가있는 상태에서 폴더명, 파일명을 변경하는 법 (camelCase로)]]></title>
            <link>https://velog.io/@wheezy_han/Git-%EC%9B%90%EA%B2%A9%EC%97%90-%EC%98%AC%EB%9D%BC%EA%B0%80%EC%9E%88%EB%8A%94-%EC%83%81%ED%83%9C%EC%97%90%EC%84%9C-%ED%8F%B4%EB%8D%94%EB%AA%85-%ED%8C%8C%EC%9D%BC%EB%AA%85%EC%9D%84-%EB%B3%80%EA%B2%BD%ED%95%98%EB%8A%94-%EB%B2%95-camelCase%EB%A1%9C</link>
            <guid>https://velog.io/@wheezy_han/Git-%EC%9B%90%EA%B2%A9%EC%97%90-%EC%98%AC%EB%9D%BC%EA%B0%80%EC%9E%88%EB%8A%94-%EC%83%81%ED%83%9C%EC%97%90%EC%84%9C-%ED%8F%B4%EB%8D%94%EB%AA%85-%ED%8C%8C%EC%9D%BC%EB%AA%85%EC%9D%84-%EB%B3%80%EA%B2%BD%ED%95%98%EB%8A%94-%EB%B2%95-camelCase%EB%A1%9C</guid>
            <pubDate>Wed, 24 Aug 2022 03:09:46 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<h2 id="문제-발생한-상황">문제 발생한 상황</h2>
<ol>
<li>팀원들과 git으로 협업하기 때문에 git push를 한 상태</li>
<li>폴더명 및 파일명을 camelCase로 작성하지 않은 것 발견</li>
<li>local에서 폴더,파일명 변경</li>
<li>local에서는 변경되었지만 git에는 그대로 </li>
</ol>
<h1 id="solution">Solution</h1>
<p>찾아보니 <strong>git은 대소문자 구분을 하지 않는다고 한다</strong>. 따라서 내가 파일명 자체를 다르게 바꾸지 않는 이상 대소문자 변경만 일어났을 경우에는 변경으로 인식되지 않는다.</p>
<p>아래와 같은 형식으로 작성하면 된다.</p>
<pre><code class="language-bash">git mv oldname newname</code></pre>
<p>하지만 대소문자만 변경할 경우에는 </p>
<ol>
<li>바꾸려하는 파일명을 임시로 작성뒤 </li>
<li>임시파일명을 원래 하려던 파일명으로 해주는 2번의 과정을 거쳐야한다. </li>
</ol>
<pre><code class="language-bash">git mv hellocode temp
git mv temp helloCode</code></pre>
<p>참고로 폴더 및 파일명을 변경해줄 때 경로도 같이 적어줘야한다! 
안그럼 fatal오류가 날 것이다.</p>
<pre><code>git mv ./src/components/hellocode.jsx temp 
git mv temp ./src/components/helloCode.jsx</code></pre><p>이렇게 하고  <code>git status</code>를 하면 rename으로 변경사항이 뜰것이다!</p>
<p><img src="https://velog.velcdn.com/images/wheezy_han/post/10175ed5-c10b-4c39-b6ec-8c595b75f562/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 수정 시 input box event value 관리 방법]]></title>
            <link>https://velog.io/@wheezy_han/React-%EC%88%98%EC%A0%95-%EC%8B%9C-input-box-event-value-%EA%B4%80%EB%A6%AC-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@wheezy_han/React-%EC%88%98%EC%A0%95-%EC%8B%9C-input-box-event-value-%EA%B4%80%EB%A6%AC-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Mon, 22 Aug 2022 09:50:34 GMT</pubDate>
            <description><![CDATA[<h1 id="구조-및-문제">구조 및 문제</h1>
<h2 id="구조">구조</h2>
<p>일단 나의 구조는 <code>input에 세팅되는 값은 부모</code>에서 받아오는 값이다.
그리고 <code>input box 세팅은 자식</code>에서 해준다.</p>
<h2 id="문제">문제</h2>
<p>수정하는 화면의 <code>input box</code>에 기존 값을 가져오고 
onChangeHandler를 이용해 변환된 값을 표출시키는 과정에서 아무리해도 부모의 값이 바뀌지 않는 문제가 있었다.</p>
<p>_원인을 먼저 말하자면 input의 value값을 부모의 값으로 세팅_해서 그렇다. 
그래서 아무리 바꾸려고 해도 부모의 값이 바뀌지않았다.</p>
<h1 id="해결">해결</h1>
<p>🥕원래의 값을 바로 input의 value의 값에 세팅하는 것이 아닌 <code>useEffect를 이용하여 부모값을 세팅</code>해주고 <strong>변경되는 값을 상태관리</strong>는 하는 것이 포인트다.</p>
<pre><code class="language-js">const children = (props) =&gt; {
    // userId 상태관리
    const [data, setData] = useState({
        userId: null
    });

    // 기존 부모의 값 세팅
    useEffect(() =&gt; {
        if (props.data) { // 부모에 값이 있다고 가정
            setData(prevState =&gt; ({
                ...prevState,
                userId: props.data.userId
            }));
        }
    }, [props.data]);

    // userId 값을 바꾸는 이벤트
    const onChangeHandler = useCallback((type, event) =&gt; {
        setData(prevState =&gt; ({
            ...prevState,
            [type]: event.value
        }))
    }, [data]);


    return (
        &lt;Fragment&gt;
            &lt;div&gt;
                &lt;div&gt;
                    &lt;Input
                          onChange={(event) =&gt; onChangeHandler(&quot;userId&quot;, event)}
                        value={data.userId} // 여기의 값을 props.data.userId로 하면 input 값이 안바뀜
                    /&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/Fragment&gt;
    );
};</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[react] 동적으로 행 생성(숫자일 때 리스트를 생성하여 map 사용)]]></title>
            <link>https://velog.io/@wheezy_han/react-%EB%8F%99%EC%A0%81%EC%9C%BC%EB%A1%9C-%ED%96%89-%EC%83%9D%EC%84%B1%EC%88%AB%EC%9E%90%EC%9D%BC-%EB%95%8C-%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EC%97%AC-map-%EC%82%AC%EC%9A%A9</link>
            <guid>https://velog.io/@wheezy_han/react-%EB%8F%99%EC%A0%81%EC%9C%BC%EB%A1%9C-%ED%96%89-%EC%83%9D%EC%84%B1%EC%88%AB%EC%9E%90%EC%9D%BC-%EB%95%8C-%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%83%9D%EC%84%B1%ED%95%98%EC%97%AC-map-%EC%82%AC%EC%9A%A9</guid>
            <pubDate>Tue, 09 Aug 2022 01:56:39 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>셀렉트박스에 숫자 선택 시 <code>그 숫자만큼 행을 동적으로 생성</code>시키면 된다.</p>
<h2 id="problem">problem</h2>
<p>동적으로 행을 생성하려면 map함수를 사용하는 것이 일반적인것 같다. 하지만 map을 이용하려면 리스트를 사용하여야하는데 내가 이용하는 데이터는 숫자이다. 
아래의 데이터의 <code>key값을 numberOfPeople</code>이라고 해보자.</p>
<pre><code class="language-json">// 1을 선택하면 
numberOfPeople : 1
// 2를 선택하면 
numberOfPeople : 2
        .
        .
        .</code></pre>
<p>이런식으로 값이 넘어온다. </p>
<p>이 문제 때문에 시간이 걸렸지만 해결방안은 _index값을 넘겨주어 그 값으로 리스트를 만들어서 map함수에서 사용하는 것_이다!
<img src="https://velog.velcdn.com/images/wheezy_han/post/6cc67f17-8923-4188-a56a-3f511d85dc34/image.png" alt=""></p>
<h1 id="코드">코드</h1>
<h2 id="부모">부모</h2>
<pre><code class="language-js">const parent = (props) =&gt; {
  const [formData, setFormData] = useState({
        numberOfPeople : null, // db에서 데이터가 넘어옴. 1,2,3..이런식으로
        numberOfPeopleList : [] // 위의 숫자만큼 값을 담을 빈배열
    })

  // numberOfPeople 값이 변할 때 마다 numberOfPeopleList에 새로운 배열 생성
  // 2 선택 시 [0,1]
  // 5 선택 시 [0,1,2,3,4]
  useEffect(() =&gt; {
        formData.numberOfPeopleList = [];
        for (let i= 0; i &lt; formData.numberOfPeople; i++) {
            formData.numberOfPeopleList.push(i)
        }
    }, [formData.numberOfPeople]);

  // 이벤트 핸들러
  const onChangeHandler = useCallback((name, event, idx) =&gt; {
        let value = event.value;
        switch (name) {
            case &quot;numberOfPeople&quot;:
                value = (value.numberOfPeople != null ? value.numberOfPeople : &quot;&quot;)
                break;
            default:
                break;
        }
        setFormData(prevState =&gt; ({
            ...prevState,
            [name]: value
        }));
    }, [formData]);

   return (
        &lt;Fragment&gt;
           {
               formik =&gt; {
               return (
                 &lt;Form className={&quot;form&quot;} onSubmit={formik.handleSubmit} ref={formRef}&gt;
                     // kendo를 사용
                     &lt;table&gt;
                       &lt;div&gt;
                         &lt;kendo-dropdownlist
                                [data]=&quot;[&quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;, &quot;5&quot;]&quot;
                         &gt;&lt;/kendo-dropdownlist&gt;
                       &lt;/div&gt;
                     &lt;/table&gt;
                      &lt;div&gt;
                          &lt;div&gt;
                             // numberOfPeopleList의 리스트 값으로 map
                            {formData.numberOfPeopleList.map((index)=&gt;(
                              &lt;div key={index}&gt;
                              &lt;ListItem idx={index}
                                        onChangeHandler={onChangeHandler}
                                        /&gt; 
                              &lt;/div&gt;
                            ))}
                          &lt;/div&gt;
                    &lt;/div&gt;    

                  &lt;/From&gt;
               )
            }
            }

         &lt;/Fragment&gt;
     )
}</code></pre>
<h2 id="자식">자식</h2>
<pre><code class="language-js">const child = (props) =&gt; {
    return (
            &lt;Fragment&gt;
                &lt;div&gt;
                      &lt;div&gt;
                      &lt;Input
                            name={&quot;numberOfPeople&quot;}
                            // onChangeHandler로 값을 선택 할 때 이벤트 핸들러가 발생
                            onChange={(event) =&gt; props.onChangeHandler(&quot;numberOfPeople&quot;, event, props.idx)}
                        /&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/Fragment&gt;
    );
};</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[react] checkBox 구현 (전체, 개별)]]></title>
            <link>https://velog.io/@wheezy_han/react-checkBox-%EA%B5%AC%ED%98%84-%EC%A0%84%EC%B2%B4-%EA%B0%9C%EB%B3%84</link>
            <guid>https://velog.io/@wheezy_han/react-checkBox-%EA%B5%AC%ED%98%84-%EC%A0%84%EC%B2%B4-%EA%B0%9C%EB%B3%84</guid>
            <pubDate>Mon, 08 Aug 2022 02:31:22 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/wheezy_han/post/d9d67ede-7086-4fc6-8cb3-462ab1198afc/image.png" alt=""></p>
<h1 id="구현-기능">구현 기능</h1>
<ul>
<li>전체 체크 기능</li>
<li>개별 체크 기능</li>
<li>개별 체크 모두 체크 시 자동으로 전체 체크 </li>
<li>전체 체크일 때 개별 체크 하나라도 미체크시 전체 체크 미체크<h1 id="구조">구조</h1>
</li>
<li>내가 한 프로젝트의 구조는 아래와 같이 부모 컴포넌트와 자식 컴포넌트가 두개인 구조이다😎</li>
</ul>
<p><code>부모 컴포넌트</code>
<code>자식 컴포넌트</code>
    - 헤더 컴포넌트 : 전체 선택 체크박스
    - 내용 컴포넌트 : 개별 선택 체크박스</p>
<h2 id="부모-컴포넌트-함수선언">부모 컴포넌트 (함수선언)</h2>
<pre><code class="language-js">
const parent = (props) =&gt; {
      const [data, setData] = useState({
            testInfo : {id : 1, data : &quot;11&quot;},
                       {id : 2, data : &quot;22&quot;},
                       {id : 3, data : &quot;33&quot;}
        }
    );

  // 체크박스 선택 시 삭제할 리스트
    const [delCheckedList, SetDelCheckedList] = useState([]);

    // 전체 체크 클릭 시 발생하는 함수
    const onCheckedAll = useCallback(
        (checked) =&gt; {
            if (checked) {
                const checkedListArray = [];

                data.testInfo.forEach((list) =&gt;                                
                checkedListArray.push(list.id));
                SetDelCheckedList(checkedListArray);
            } else {
                SetDelCheckedList([]);
            }
        },
        [data.testInfo]);

    // 개별 체크 클릭 시 발생하는 함수
    const onCheckedElement = useCallback(
        (checked, intsId) =&gt; {
            if (checked) {
                SetDelCheckedList([...delCheckedList, intsId]);
            } else {
                SetDelCheckedList(delCheckedList.filter((el) =&gt; el !== id));
            }
        },[delCheckedList]);
}
</code></pre>
<h2 id="헤더-컴포넌트-전체-체크">헤더 컴포넌트 (전체 체크)</h2>
<pre><code class="language-js">const header = (props) =&gt; {
    return (
        &lt;Fragment&gt;
            &lt;table&gt;
                &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;
                        &lt;Checkbox
                            checked={
                                props.delCheckedList.length === 0
                                    ? false
                                    : props.delCheckedList.length === props.data.testInfo .length
                                    ? true
                                    : false
                            }
                            onChange={(e) =&gt; props.onCheckedAll(e.target.value)}
                        /&gt;
                    &lt;/th&gt;
                    &lt;th&gt;test1&lt;/th&gt;
                    &lt;th&gt;test2&lt;/th&gt;
                    &lt;th&gt;test3&lt;/th&gt;
                &lt;/tr&gt;
                &lt;/thead&gt;
            &lt;/table&gt;
        &lt;/Fragment&gt;
    );
};</code></pre>
<h2 id="내용-컴포넌트-개별-체크">내용 컴포넌트 (개별 체크)</h2>
<pre><code class="language-js">const content = (props) =&gt; {
    return (
        &lt;Fragment&gt;
            &lt;div&gt;
                &lt;div&gt;
                    &lt;Checkbox
                        checked={
                           // data를 식별할 수 있는 컬럼에 key 값을 넣어줌
                          props.delCheckedList.includes(props.dataItem.id) ? true : false
                        }
                        onChange={(e) =&gt; props.onCheckedElement(e.target.value, props.dataItem.id)}
                    /&gt;
                &lt;/div&gt;
                &lt;div&gt;{props.dataItem.test1}&lt;/div&gt;
                &lt;div&gt;{props.dataItem.test2}&lt;/div&gt;
                &lt;div&gt;{props.dataItem.test3}&lt;/div&gt;  
            &lt;/div&gt;
        &lt;/Fragment&gt;
    );
};</code></pre>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://velog.io/@tunakim/React-CheckBox-%EC%A0%95%EB%A6%AC-%EC%A0%84%EC%B2%B4-%EC%84%A0%ED%83%9D-%ED%95%98%EA%B8%B0">https://velog.io/@tunakim/React-CheckBox-%EC%A0%95%EB%A6%AC-%EC%A0%84%EC%B2%B4-%EC%84%A0%ED%83%9D-%ED%95%98%EA%B8%B0</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] 국제 표준 시를 한국 표준 시로 변환]]></title>
            <link>https://velog.io/@wheezy_han/Java-%EA%B5%AD%EC%A0%9C-%ED%91%9C%EC%A4%80-%EC%8B%9C%EB%A5%BC-%ED%95%9C%EA%B5%AD-%ED%91%9C%EC%A4%80-%EC%8B%9C%EB%A1%9C-%EB%B3%80%ED%99%98</link>
            <guid>https://velog.io/@wheezy_han/Java-%EA%B5%AD%EC%A0%9C-%ED%91%9C%EC%A4%80-%EC%8B%9C%EB%A5%BC-%ED%95%9C%EA%B5%AD-%ED%91%9C%EC%A4%80-%EC%8B%9C%EB%A1%9C-%EB%B3%80%ED%99%98</guid>
            <pubDate>Sat, 23 Jul 2022 11:58:35 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>db에서 timestamp로 되어있는 컬럼의 값을 등록할 때 client 단에서는 
아래와 같이 한국 표준시로 데이터를 넘겼다. </p>
<pre><code>day: Wed May 12 2022 00:00:00 GMT+0900 (한국 표준시)</code></pre><p>하지만 service단에서 가지고 온 데이터는 하루 전날인 즉, -1일인 데이터 값을 가지고 왔다.</p>
<pre><code>2022-05-11T15:00:00.000Z</code></pre><h1 id="해결방법">해결방법</h1>
<p>우리 나라 표준 시인 +9를 넘겼지만, 받을 땐 국제 표준 시인 <code>24 -9 인 15</code>인 값을 가지고 온 것이다.</p>
<pre><code class="language-java">Timestamp Time = Timestamp.valueOf(holidayDto.getHday().replace(&#39;T&#39;,&#39; &#39;).replace(&#39;Z&#39;,&#39; &#39;));
            Calendar cal = Calendar.getInstance();
            cal.setTimeInMillis(Time.getTime());
            cal.add(Calendar.HOUR, 9);


            String koreaTime = new Timestamp(cal.getTime().getTime()).toString();

            testDto.set컬럼명(koreaTime);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[PostgreSQL] db에서 timpestamp타입 컬럼을 date 타입으로 삽입하고 싶은 경우 ]]></title>
            <link>https://velog.io/@wheezy_han/PostgreSQL-db%EC%97%90%EC%84%9C-timpestamp%ED%83%80%EC%9E%85-%EC%BB%AC%EB%9F%BC%EC%9D%84-date-%ED%83%80%EC%9E%85%EC%9C%BC%EB%A1%9C-%EC%82%BD%EC%9E%85%ED%95%98%EA%B3%A0-%EC%8B%B6%EC%9D%80-%EA%B2%BD%EC%9A%B0</link>
            <guid>https://velog.io/@wheezy_han/PostgreSQL-db%EC%97%90%EC%84%9C-timpestamp%ED%83%80%EC%9E%85-%EC%BB%AC%EB%9F%BC%EC%9D%84-date-%ED%83%80%EC%9E%85%EC%9C%BC%EB%A1%9C-%EC%82%BD%EC%9E%85%ED%95%98%EA%B3%A0-%EC%8B%B6%EC%9D%80-%EA%B2%BD%EC%9A%B0</guid>
            <pubDate>Wed, 20 Jul 2022 01:44:22 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>등록/수정하는 쿼리 작성에서 타입으로 문제가 빈번히 발생했다.
각각 <code>data type</code>을 아래와 같이 설정해두었다.</p>
<ul>
<li>postsql(db) : timestamp</li>
<li>dto : string</li>
<li>원하는 insert/update 컬럼 형식 : date(YYYY-MM-DD)</li>
</ul>
<h1 id="error">Error</h1>
<h3 id="쿼리">쿼리</h3>
<p><code>xml : mybatis</code></p>
<pre><code class="language-sql">INSERT INTO public.&quot;LOGIN_TABLE&quot;
    &quot;NAME&quot;,
    &quot;ID&quot;,
    &quot;PW&quot;,
    &quot;LOGIN_DATE&quot;
VALUES (
    #{name},
    #{id},
    #{pw},
    #{loginDate}
)</code></pre>
<h3 id="test-data">test data</h3>
<p>_<strong>swagger나 postman</strong>_에서 테스트를 아래와 같이 작성하였다.  </p>
<pre><code>{
&quot;name&quot; : &quot;han&quot;,
&quot;id&quot; : &quot;test&quot;,
&quot;pw&quot; : &quot;1234&quot;,
&quot;loginDate&quot; : &quot;2022-07-20&quot;
}</code></pre><p>이렇게 하니 loginDate가 dto에서 string으로 정의되어 있으나 db에서는 timpestamp여서 오류가 발생하였다.</p>
<h1 id="solution">Solution</h1>
<p>아래와 같이 <code>TO_DATE( #{loginDate}, &#39;YYYY-MM-DD&#39;)</code> 작성해 주면 오류가 해결되고 db에 time 값이 0으로 세팅된다.</p>
<h3 id="ex">ex</h3>
<pre><code>TO_DATE(text,format) // 2022-07-07 00:00:00.000</code></pre><h3 id="쿼리-1">쿼리</h3>
<p><code>xml : mybatis</code></p>
<pre><code class="language-sql">INSERT INTO public.&quot;LOGIN_TABLE&quot;
    &quot;NAME&quot;,
    &quot;ID&quot;,
    &quot;PW&quot;,
    &quot;LOGIN_DATE&quot;
VALUES (
    #{name},
    #{id},
    #{pw},
    TO_DATE( #{loginDate}, &#39;YYYY-MM-DD&#39;)
)</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[sql] 테이블 조인 시 컬럼 count 하는 법]]></title>
            <link>https://velog.io/@wheezy_han/sql-%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%A1%B0%EC%9D%B8-%EC%8B%9C-%EC%BB%AC%EB%9F%BC-count-%ED%95%98%EB%8A%94-%EB%B2%95</link>
            <guid>https://velog.io/@wheezy_han/sql-%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%A1%B0%EC%9D%B8-%EC%8B%9C-%EC%BB%AC%EB%9F%BC-count-%ED%95%98%EB%8A%94-%EB%B2%95</guid>
            <pubDate>Mon, 11 Jul 2022 10:23:54 GMT</pubDate>
            <description><![CDATA[<h4 id="참고">참고</h4>
<ul>
<li><a href="https://www.wake-up-neo.com/ko/mysql/mysql%EC%9D%98-%EC%97%AC%EB%9F%AC-%ED%85%8C%EC%9D%B4%EB%B8%94%EC%97%90%EC%84%9C-count/970967252/">https://www.wake-up-neo.com/ko/mysql/mysql%EC%9D%98-%EC%97%AC%EB%9F%AC-%ED%85%8C%EC%9D%B4%EB%B8%94%EC%97%90%EC%84%9C-count/970967252/</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SpringBoot, mybatis] Dto 변수명과 DB의 컬럼명이 달라 null값이 들어올 때]]></title>
            <link>https://velog.io/@wheezy_han/SpringBoot-mybatis-Dto-%EB%B3%80%EC%88%98%EB%AA%85%EA%B3%BC-DB%EC%9D%98-%EC%BB%AC%EB%9F%BC%EB%AA%85%EC%9D%B4-%EB%8B%AC%EB%9D%BC-null%EA%B0%92%EC%9D%B4-%EB%93%A4%EC%96%B4%EC%98%AC-%EB%95%8C</link>
            <guid>https://velog.io/@wheezy_han/SpringBoot-mybatis-Dto-%EB%B3%80%EC%88%98%EB%AA%85%EA%B3%BC-DB%EC%9D%98-%EC%BB%AC%EB%9F%BC%EB%AA%85%EC%9D%B4-%EB%8B%AC%EB%9D%BC-null%EA%B0%92%EC%9D%B4-%EB%93%A4%EC%96%B4%EC%98%AC-%EB%95%8C</guid>
            <pubDate>Mon, 04 Jul 2022 00:26:29 GMT</pubDate>
            <description><![CDATA[<h1 id="java-vs-db">Java vs DB</h1>
<h2 id="java">Java</h2>
<ul>
<li>자바는 일반적으로 변수명에 <strong>Camel case</strong> 사용 <ul>
<li>userId</li>
</ul>
</li>
</ul>
<h2 id="db">DB</h2>
<ul>
<li><strong>snake case</strong>로 사용<ul>
<li>user_id </li>
</ul>
</li>
</ul>
<h2 id="문제">문제</h2>
<p>xml 파일에서 select sql문을 작성하였을 때, java의 Dto 변수명이 해당 DB 컬럼명과 다를 경우 null 값이 출력된다. </p>
<p>하지만 반드시 Dto와 DB네이밍을 일치시킬 필요는 없다. 오히려 java는 언더바(-)사용을 권장하지 않는다고 한다.</p>
<p>3가지 방법이 있다.</p>
<h1 id="사용방법">사용방법</h1>
<h2 id="mybatis-configxml-파일-설정">mybatis-config.xml 파일 설정</h2>
<p>이 방법이 보통 내가 프로젝트를 하면 사용하는 방법이다.</p>
<pre><code class="language-xml">&lt;setting name=&quot;mapUnderscoreToCamelCase&quot; value=&quot;true&quot; /&gt;</code></pre>
<h2 id="sql문에-별칭as-alias-설정">sql문에 별칭(AS, Alias) 설정</h2>
<pre><code class="language-sql">select user_id as userId,
       ...
from USER_TB </code></pre>
<h2 id="resultmap의-property-설정-적용">resultMap의 property 설정 적용</h2>
<ul>
<li>Mapper 파일에서 해당 SQL문에 해당하는 resultMap을 사용<pre><code class="language-sql">&lt;resultMap id=&quot;userResultMap&quot; type=&quot;User&quot;&gt;
&lt;id property=&quot;id&quot; column=&quot;user_id&quot; /&gt;
&lt;result property=&quot;username&quot; column=&quot;username&quot;/&gt;
&lt;result property=&quot;password&quot; column=&quot;password&quot;/&gt;
&lt;/resultMap&gt;
</code></pre>
</li>
</ul>
<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>
```
#### 참고
- https://blog.naver.com/PostView.naver?blogId=pinktenshi&logNo=222281350349&parentCategoryNo=&categoryNo=24&viewDate=&isShowPopularPosts=true&from=search
- https://mybatis.org/mybatis-3/ko/sqlmap-xml.html#Result_Maps]]></description>
        </item>
        <item>
            <title><![CDATA[POSTCSS란?]]></title>
            <link>https://velog.io/@wheezy_han/POSTCSS%EB%9E%80</link>
            <guid>https://velog.io/@wheezy_han/POSTCSS%EB%9E%80</guid>
            <pubDate>Mon, 27 Jun 2022 08:21:15 GMT</pubDate>
            <description><![CDATA[<h1 id="css-전처리기">CSS 전처리기</h1>
<ul>
<li>편리한 문법을 이용해서 css를 작성하고 추후에 다시 순수 css로 변환해 주는 것</li>
<li>다시 말하면 프레임워크의 문법에 맞게 css를 작성하면 사용자에게 배포할 브라우저가 이해할 수 있는 css로 변환이 됨.</li>
</ul>
<h2 id="✅-필요한-이유">✅ 필요한 이유?</h2>
<ul>
<li>기본적인 CSS만으로는 중복적으로 작성해야됨</li>
<li>브라우저 호환성 위해 필요</li>
<li>중복되는 코드를 최소화하기 위해 필요</li>
</ul>
<h2 id="✅-종류">✅ 종류</h2>
<ul>
<li>LESS</li>
<li>SASS</li>
<li>Stylus(스타일러스)</li>
</ul>
<h1 id="postcss란">PostCSS란?</h1>
<ul>
<li><p>SASS와 LESS와 같은 프레임워크와 비슷하지만 SASS와 LESS는 제공이 한정적임.
하지만 <strong>POSTCSS는 플러그인이 다양함</strong></p>
</li>
<li><p><code>create react app</code> 을 할 때 기본적으로 PostCSS가 설치됨 </p>
<ul>
<li><strong>package.json or node_modules</strong>에서 확인 가능!</li>
</ul>
</li>
</ul>
<h2 id="✅-autoprefix란">✅ autoprefix란?</h2>
<h3 id="prefix란">prefix란?</h3>
<ul>
<li>브라우저 별 따로 놀던 CSS3 속성을 잡어주기 위해 사용되기 시작</li>
<li>마크업 시 CSS의 Class 앞에 <code>-moz-, -webkit-, -o-, -ms-</code> 와 같이 각 브라우저에서 판독 가능한 접두어를 붙여서 해당 브라우저에서 인식할 수 있게 하는 것</li>
</ul>
<p>만약 index.css에 아래와 같이 작성하고 빌드를 하면 (최종적으로 사용자에게 배포될 것) 빌드된 css가 생성됨</p>
<pre><code class="language-css">:fullscreen {
    background-color: pink;
}</code></pre>
<ul>
<li>빌드된 css를 보면 자동적으로 prefix가 붙어있는 것을 볼 수 있음<ul>
<li>PostCSS의 autoprefix가 모든 prefix를 붙여줌.<ul>
<li><strong>현재 브라우저들의 시장 점유율과 호환성 문제를 자동으로 정보 수집해서 처리가 되는 것 (신뢰 가능!!)</strong></li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="참고">참고</h1>
<ul>
<li><a href="https://postcss.org/">PostCSS</a></li>
<li><a href="https://www.postcss.parts/">postcss/plugins</a></li>
<li><a href="https://github.com/postcss/postcss/blob/main/docs/plugins.md">postcss/plugins_github</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 프로젝트 배포 방법(GitHub, Netlify)]]></title>
            <link>https://velog.io/@wheezy_han/React-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%B0%B0%ED%8F%AC-%EB%B0%A9%EB%B2%95GitHub-Netlify</link>
            <guid>https://velog.io/@wheezy_han/React-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%B0%B0%ED%8F%AC-%EB%B0%A9%EB%B2%95GitHub-Netlify</guid>
            <pubDate>Wed, 22 Jun 2022 07:38:29 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/wheezy_han/post/e1747085-0f29-4c97-af83-f5feb4025962/image.png" alt=""></p>
<h1 id="intro">Intro</h1>
<p>개인적으로 프로젝트를 하다가 배포하고 싶거나 해야할 일이있다. 
이때 내가 해본 방법은 GitHub와 Netlify를 이용한 방법이다.</p>
<h2 id="github">GitHub</h2>
<ol>
<li>생성한 repository의 Settings에서 GitHub Pages로 이동한다.</li>
<li>master Branch로 변경하면 배포하면 얻게될 주소가 생성된다. 
<img src="https://velog.velcdn.com/images/wheezy_han/post/ab4f776f-650c-4607-b866-ba849ea73935/image.png" alt=""></li>
<li>프로젝트의 <strong>package.json에서</strong> private밑에 homepage작성한다.</li>
</ol>
<pre><code class="language-js">&quot;homepage&quot;: &quot;https://yunkyunghan.github.io/habit-tracker&quot;</code></pre>
<ol start="4">
<li><strong>터미널</strong>에서 npm 혹은 yarn을 이용해서 GitHub 페이지에 install</li>
</ol>
<pre><code class="language-js">npm install --save gh-pages
yarn add gh-pages</code></pre>
<ol start="5">
<li>다시 <strong>package.json scripts에서</strong> 아래 플러스 된 것 추가한다.<ul>
<li>yarn start를 하면 프로젝트 실행</li>
<li>yarn build를 하면 프로젝트를 빌드해서 사용자에게 배포할 수 있는 소스코드가 만들어짐.</li>
</ul>
</li>
</ol>
<pre><code class="language-js">&quot;scripts&quot;: {
+   &quot;predeploy&quot;: &quot;npm run build&quot;, // deploy를 실행하기 전에 자동으로 호출. 따라서 deploy만 호출하면 됨. 
+   &quot;deploy&quot;: &quot;gh-pages -d build&quot;, // 만들어진 빌드를 GitHub에 배포
    &quot;start&quot;: &quot;react-scripts start&quot;,
    &quot;build&quot;: &quot;react-scripts build&quot;, </code></pre>
<ol start="6">
<li>프로젝트 빌드한다.</li>
</ol>
<pre><code class="language-js">yarn build</code></pre>
<ol start="7">
<li>아래 명령어를 실행하여 사이트에 배포한다.<ul>
<li>성공하면 <strong>Published!</strong> 뜸</li>
</ul>
</li>
</ol>
<pre><code class="language-js">npm run deploy</code></pre>
<ol start="8">
<li>GitHub 브랜치에는 우리가 빌드한 것이 올라가 있기 때문에 설정이 필요하다.<ul>
<li><code>gh-pages</code>인것을 명심!</li>
</ul>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/wheezy_han/post/67382ad6-b532-4111-b3df-b32642111add/image.png" alt="">
9. homepage url 입력하면 배포된 페이지 볼 수 있음!😲</p>
<h2 id="netlify">Netlify</h2>
<ol>
<li><strong>build 폴더 안에서</strong> 아래 명령어 실행한다. (둘 중 선택)</li>
</ol>
<pre><code class="language-js">npm install netlify-cli -g
yarn global add netlify-cli</code></pre>
<ol start="2">
<li>설치에 성공하면 버전확인 가능하다.</li>
</ol>
<pre><code class="language-js">    $ netlify -v
    netlify-cli/10.5.1 win32-x64 node-v14.17.0</code></pre>
<ol start="3">
<li><strong>build 폴더에서 나와서</strong> 아래 명령어 입력하면 회원가입창이 뜬다.<ul>
<li>GitHub로 연결 (선택사항은 본인 자유)</li>
</ul>
</li>
</ol>
<pre><code class="language-js">netlify deploy</code></pre>
<ol start="4">
<li><p>승인을 해주면 터미널에서 선택사항이 뜬다.
<img src="https://velog.velcdn.com/images/wheezy_han/post/b5f9d8af-cc43-4a3a-8e60-9eb43ea85ab1/image.png" alt=""></p>
</li>
<li><p>team 이름, site name, publish directory(deploy할 폴더)설정해주면 된다.</p>
<ul>
<li><p><strong>publish directory는 build</strong>입력</p>
</li>
<li><p>📍 주의 ) <strong>만약 package.json에 GitHub 배포를 할 때 설정했던 hompage가 있으면 안됨.</strong></p>
<ul>
<li><p>만약 아무런 홈페이지가 뜨지 않는다면</p>
<pre><code class="language-js">&quot;homepage&quot;: &quot;.&quot;, // 삭제대신 이렇게 수정

yarn build
netlify deploy 재입력</code></pre>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/wheezy_han/post/26363578-ae51-4911-a84f-f1d1054407f7/image.png" alt=""></p>
<h3 id="배포-후-url-변경하는-법-netlify">배포 후 url 변경하는 법 (Netlify)</h3>
<ul>
<li>배포를 하게 되면 우리가 확인할 수 있는 검증, 테스트 용 url이 만들어짐(임시적인 배포상태)</li>
<li>그 후 실제로 기능이 완벽하고 이슈가 없는것이 확인이 되면 공식적으로 배포할 수 있음.</li>
<li>따라서 위에서 배포 시 terminal log에도 <code>Website Draft URL</code> 이라고 명칭이 되어져 있음</li>
<li>실제 배포 (최종 url)</li>
</ul>
<pre><code class="language-js">netlify deploy --prod</code></pre>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://create-react-app.dev/docs/deployment/">https://create-react-app.dev/docs/deployment/</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] Spread Operator]]></title>
            <link>https://velog.io/@wheezy_han/JS-Spread-Operator</link>
            <guid>https://velog.io/@wheezy_han/JS-Spread-Operator</guid>
            <pubDate>Mon, 20 Jun 2022 07:29:29 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/wheezy_han/post/4c5db2d5-1ec0-4bf1-a4f8-998ce718168d/image.png" alt=""></p>
<h1 id="spread-operator란">Spread Operator란?</h1>
<p>Spread Operator라고 해서 <code>...</code>을 이용하며 스프레드 오퍼레이터, 스프레드 연산자라고 불린다. 
ES^에서 새롭게 추가된 내용으로 연결, 복사 등에 활용도가 높다. </p>
<h2 id="배열-병합">배열 병합</h2>
<p>기존에서는 배열을 결합하는데 있어 concat 메서드를 많이 사용했다. spread 연산자를 이용하면 더 깔끔한 병합이 된다.</p>
<pre><code class="language-js">let arr1 = [1,2,3]; 
let arr2 = [4,5,6]; 

let newArr = arr1.concat(arr2); 
console.log(newArr); // [ 1, 2, 3, 4, 5, 6 ] 

// ES6 spread operator
let arr1 = [1,2,3]; 
let arr2 = [4,5,6]; 

let newArr = [...arr1, ...arr2]; 
console.log(newArr); // [ 1, 2, 3, 4, 5, 6 ] </code></pre>
<h2 id="배열-복사">배열 복사</h2>
<p>spread연산자는 _<strong>얕은 복사</strong>_를 한다. 
✨<strong>배열은 복사되지만 배열 안에있는 객체는 원본 값을 참조</strong>한다. 복사한 배열의 객체 값을 변경하면 참조하고 있는 원본 배열의 객체 값도 변경된다.
하지만 새로운 객체를 추가하면 복사한 배열에만 변경이된다. (원본배열에서 참조값이 없기 때문)</p>
<h3 id="배열의-값을-변경했을-경우">배열의 값을 변경했을 경우</h3>
<p>📍 배열의 값만 있을 때와 배열 안에 객체가 있을 때랑 헷갈리면 안된다!</p>
<pre><code class="language-js">// ES6 spread operator
let arr1 = [&#39;han&#39;,&#39;wheezy&#39;]; 
let arr2 = [...arr1]; 

arr2.push(&#39;coding&#39;); 

// 원본 배열은 변경되지 않습니다.
console.log(arr1); // [ &quot;han&quot;, &quot;wheezy&quot; ]
console.log(arr2); // [ &quot;han&quot;, &quot;wheezy&quot;, &quot;coding&quot; ]
</code></pre>
<pre><code class="language-js">// ES6 spread operator
let arr1 = [&#39;han&#39;,&#39;wheezy&#39;]; 
let arr2 = [...arr1]; 

arr1[0] = &quot;hello&quot;

console.log(arr1); // [ &quot;han&quot;, &quot;wheezy&quot;, &quot;coding&quot; ]
// 복사된 배열은 변경되지 않습니다.
console.log(arr2); // [ &quot;han&quot;, &quot;wheezy&quot; ]</code></pre>
<h3 id="원본-배열의-객체-값을-변경했을-경우">원본 배열의 객체 값을 변경했을 경우</h3>
<pre><code class="language-js">let arr1 = [{name: &#39;han&#39;, age: 10}]; 
let arr2 = [...arr1]; 

arr1[0].name = &#39;lee&#39;;

console.log(arr1); // [{name: &#39;lee&#39;, age: 10}]
console.log(arr2); // [{name: &#39;lee&#39;, age: 10}]</code></pre>
<h3 id="복사된-배열에-새로운-객체를-추가했을-경우">복사된 배열에 새로운 객체를 추가했을 경우</h3>
<pre><code class="language-js">let arr1 = [{name: &#39;han&#39;, age: 10}]; 
let arr2 = [...arr1]; 

arr2.push({name2: &#39;han2&#39;, age: 20})

console.log(arr1); // [{name: &#39;han&#39;, age: 10}]
console.log(arr2); // [{name: &#39;han&#39;, age: 10}, {name2: &#39;han2&#39;, age: 20}]</code></pre>
<h3 id="복사된-배열에-새로운-key-value값을-추가했을-경우원본-참조값에">복사된 배열에 새로운 key, value값을 추가했을 경우(원본 참조값에)</h3>
<pre><code class="language-js">let arr1 = [{name: &#39;han&#39;, age: 10}]; 
let arr2 = [...arr1]; 

arr2[0][&quot;city&quot;] = &quot;seoul&quot;;

console.log(arr1); // [{name: &#39;han&#39;, age: 10, city: &#39;seoul&#39;}]
console.log(arr2); // [{name: &#39;han&#39;, age: 10, city: &#39;seoul&#39;}]</code></pre>
<h2 id="slice-혹은-es5-map일-때">slice 혹은 ES5 map일 때</h2>
<p>만약 배열 참조가 아닌 복사를 위해서는 기존의 slice 혹은 ES5 map을 이용하면 된다. </p>
<pre><code class="language-js">// Javascript array 복사
let arr1 = [&#39;han&#39;,&#39;wheezy&#39;]; 
let arr2 = arr1.slice();

arr2.push(&#39;coding&#39;); 
console.log(arr2); // [ &quot;han&quot;, &quot;wheezy&quot;, &quot;coding&quot; ]
// 원본 배열은 변경되지 않습니다.
console.log(arr1); // [ &quot;han&quot;, &quot;wheezy&quot; ]


// ES5 map 
let arr1 = [&#39;han&#39;,&#39;wheezy&#39;]; 
let arr2 = arr1.map((item) =&gt; item);

arr2.push(&#39;coding&#39;); 
console.log(arr2); // [ &quot;han&quot;, &quot;wheezy&quot;, &quot;coding&quot; ]
// 원본 배열은 변경되지 않습니다.
console.log(arr1); // [ &quot;han&quot;, &quot;wheezy&quot; ]</code></pre>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://paperblock.tistory.com/62">https://paperblock.tistory.com/62</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 자바스크립트 오브젝트]]></title>
            <link>https://velog.io/@wheezy_han/JS-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@wheezy_han/JS-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Mon, 20 Jun 2022 06:30:43 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/wheezy_han/post/e71e0c42-4750-423d-8a8b-857dd5e24723/image.png" alt=""></p>
<h1 id="오브젝트란">오브젝트란?</h1>
<p>오브젝트는 key와 value의 집합체이다.</p>
<pre><code>object = { key: value };</code></pre><h2 id="생성방법">생성방법</h2>
<h3 id="object-literal">object literal</h3>
<pre><code class="language-js">const obj1 = {}</code></pre>
<h3 id="object-constructor">object constructor</h3>
<p>new class 키워드 사용</p>
<pre><code class="language-js">const obj2 = new Object();</code></pre>
<p>자바스크립트는 동적으로 타입이 runtime(프로그램이 동작하고 있을 때)결정되므로 오브젝트 생성 후 property를 후에 추가 및 삭제 할 수 있다. </p>
<pre><code class="language-js">// 기존
const wheezy = {name: &#39;wheezy&#39;, age: 20};

// 추가
wheezy.hasJob = true;

// 삭제
delete wheezy.hasJob; // undefined</code></pre>
<h1 id="오브젝트-할당">오브젝트 할당</h1>
<p>변수에 원시형 데이터 (문자열, 숫자)를 할당하면 데이터 자체가 그래도 변수가 할당되지만
오브젝트를 변수에 할당하면 <strong>오브젝트가 메모리에 들어있는 주소인 참조값이 변수에 할당</strong>된다.</p>
<pre><code class="language-js">const name = &quot;wheezy&quot;;
const nameObj = { name: &quot;wheezy&quot; }; // x111</code></pre>
<p>위에서 nameObj의 오브젝트는 메모리 주소값에 할당되어진다. (주소값을 x111이라고 가정) </p>
<pre><code class="language-js">const wheezy = { name: &quot;wheezy&quot;, age: 10 }; // x222
const han = { name: &quot;han&quot;, age: 20 }; // x333
const yk = wheezy; // x222</code></pre>
<p>위에서는 wheezy변수를 yk에 할당하게 되어 wheezy변수의 참조값이 yk에 복사되어져 할당된다. </p>
<p>추가적으로 오브젝트는 값 자체가 변수에 저장되는 것이아니라 참조값(Reference)이 저장된다.
따라서 아래와 같이 수정된 값을 적용받게 된다.</p>
<pre><code>wheezy.age = 30;
console.log(wheezy) // { name: &quot;wheezy&quot;, age: 30 }
console.log(yk) // { name: &quot;wheezy&quot;, age: 30 }</code></pre><h2 id="배열에서는">배열에서는?</h2>
<p>배열 안에 오브젝트가 있을 때 생성된 오브젝트수에는 배열 자체도 포함시켜줘야 한다. 
따라서 아래의 경우에는 총 3개의 오브젝트가 생선되었다.</p>
<pre><code class="language-js">const userInfo = [ // x666
    { name: &quot;wheezy&quot;, age: 10 }, // x444
      { name: &quot;han&quot;, age: 20 } // x555
];</code></pre>
<h3 id="spread-operator-경우에">Spread Operator 경우에</h3>
<p>✨ Spread Operator은 배열 안의 모든 오브젝트 내용을 하나하나 복사해오는 것이 아니라 <em><strong>오브젝트는 그대로 두고 array의 아이템들의 참조값을 복사한다.</strong></em></p>
<p>따라서 아래와 같이 userInfo3배열에는 새로 만들어진 참조값 x777안에 userInfo3[0]은 userInfo[0]과 동일한 참조값이 x444, userInfo3[1]은 userInfo[1]과 동일한 참조값이 x555를 갖게된다.</p>
<pre><code class="language-js">const userInfo = [ // x666
    { name: &quot;wheezy&quot;, age: 10 }, // x444
      { name: &quot;han&quot;, age: 20 } // x555
];
const userInfo2 = userInfo; // x666
const userInfo3 = [...userInfo]; // x777</code></pre>
<p>따라서 만약 userInfo[0].age = 30으로 고치면 userInfo, userInfo2, userInfo3 모두 age가 30으로 바뀐다. 
<strong>참조값이 모두 x444로 동일하기 때문에!!!</strong></p>
<p>📍 주의할 점
다만 만약 userInfo에 새로운 값을 추가하면 Spread Operator을 한 배열에는 해당이 안된다. 
다시 말해</p>
<pre><code class="language-js">userInfo.push({ name: &quot;yk&quot;, age: 90 });
console.log(userInfo[name].length); // 3
console.log(userInfo2[name].length); // 3
console.log(userInfo3[name].length); // 2</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React]render함수 호출에 따른 성능 분석과 PureComponent]]></title>
            <link>https://velog.io/@wheezy_han/Reactrender%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C%EC%97%90-%EB%94%B0%EB%A5%B8-%EC%84%B1%EB%8A%A5-%EB%B6%84%EC%84%9D%EA%B3%BC-PureComponent</link>
            <guid>https://velog.io/@wheezy_han/Reactrender%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C%EC%97%90-%EB%94%B0%EB%A5%B8-%EC%84%B1%EB%8A%A5-%EB%B6%84%EC%84%9D%EA%B3%BC-PureComponent</guid>
            <pubDate>Tue, 14 Jun 2022 03:19:45 GMT</pubDate>
            <description><![CDATA[<h1 id="🎨render-함수-호출">🎨render 함수 호출</h1>
<p>render() 안에 로그를 확인하여 Component에 이 render 함수가 언제  호출되는지 확인할 수 있다. 
코드에 console.log()를 찍고 화면을 refresh 해주면 로그들이 두번씩 찍힌다. </p>
<h2 id="🖋-render함수가-두번씩-찍히는-이유">🖋 render함수가 두번씩 찍히는 이유</h2>
<p>index.js에서 StrictMode를 사용하여서이다.</p>
<h3 id="strictmode란">StrictMode란?</h3>
<p>StrictMode를 사용함으로서 한번 더 호출되어 잘못되는 것이 없는지 검사한다.
개발하는 동안만 두번 호출이되고 <strong>실제 배포시는 두번씩 안되므로 걱정할 필요는 없을 것 같다!</strong></p>
<pre><code class="language-js">ReactDOM.render(
  &lt;React.StrictMode&gt;
    &lt;App /&gt;
  &lt;/React.StrictMode&gt;,
  document.getElementById(&#39;root&#39;)
);</code></pre>
<hr>
<h2 id="🖋-성능-분석">🖋 성능 분석</h2>
<p>다시 본론으로 돌아가면 
만약 onClick 함수가 호출되는 부분을 누르면 계속 모든 render함수가 호출된다.
하지만, <strong>React 자체에서 VDOM을 써서 실제로는 정말 업데이트 돼는 것들만 DOM요소에 업데이트 된다.</strong>😎</p>
<p>따라서 render함수가 계속 호출이되지만 성능이 괜찮은 이유는 <code>필요한 요소만 업데이트가 되기 때문</code>이다.(요소에서 확인 가능)</p>
<ul>
<li>즉, React 어플리케이션은 state가 변화되면 전체적으로 render가 호출이 되지만 (부모의 App에 state가 있음) VDOM 메모리상에 트리를 보관해 놓고 있기 때문에 이전의 데이터와 비교하여 실제로 필요한 부분만 DOM요소에 업데이트가 된다.</li>
</ul>
<blockquote>
<p>디버깅을 할 때, HTML Elements파트에서  DOM요소 전체가 사라지고 깜빡이면서 나타나거나 변화가 많이 일어나면 잘못하고 있는 것!</p>
</blockquote>
<h3 id="문제점">문제점</h3>
<p>이렇게 하나의 컴포넌트만 업데이트하였는데 전체 render 함수가 호출되면 발생할 수 있는 문제가 없지는 않다.
⇒ 화면 깜빡임, 불필요한 일 수행 등,,
실제로는 관련된 데이터가 전혀 변경되지 않았음에도 불구하고 render 함수가 계속 호출되는 것은 성능에 좋지 않다!</p>
<h3 id="호출-확인-방법">호출 확인 방법</h3>
<p>브라우저에서 불필요한 render함수들이 호출되는지 확인할 수 있다. </p>
<table>
<thead>
<tr>
<th>컴포넌트가 렌더링 될 때, 업데이트 되는 것은 하이라이트 해주는 기능</th>
<th>시각적으로 브라우저에서 확인 가능</th>
</tr>
</thead>
<tbody><tr>
<td><img src="https://velog.velcdn.com/images/wheezy_han/post/a7e0ef91-0fd7-43e5-b22c-84e8b3c6ad26/image.png" alt=""></td>
<td><img src="https://velog.velcdn.com/images/wheezy_han/post/71fe1a6c-f876-4803-9287-b9b39b181de4/image.png" alt=""></td>
</tr>
</tbody></table>
<h1 id="🎨purecomponent">🎨PureComponent</h1>
<p><code>PureComponent와 memo</code>는 <strong>컴포넌트 state나 props에 변화가 없으면 render함수가 호출이 안되게 한다.</strong></p>
<pre><code class="language-js">import React, { PureComponent } from &#39;react&#39;

class HabitAddForm extends PureComponent {
  ...
}</code></pre>
<p>위와 같이 코드를 PureComponent로 작성하게 되면 <strong>최상위에 있는 데이터가 변하지 않으면  props와 state안에 들어 있는 데이터의 render함수가 호출되지 않는다.</strong></p>
<ul>
<li>즉, re-rendering을 하지 않는다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] ref란?]]></title>
            <link>https://velog.io/@wheezy_han/React-ref%EB%9E%80</link>
            <guid>https://velog.io/@wheezy_han/React-ref%EB%9E%80</guid>
            <pubDate>Mon, 13 Jun 2022 05:18:04 GMT</pubDate>
            <description><![CDATA[<h1 id="ref란">ref란?</h1>
<p>HTML을 작성할 때, DOM 요소에 이름을 붙일 경우 <code>&lt;div id =&quot;testId&quot;&gt;</code> 와 같이 id 값을 준다. 
이렇게 하면 해당 id가 있는 DOM 요소에만 스타일을 따로 적용할 수 있다. </p>
<p>마찬가지로 <em><strong>리액트에서도 DOM을 선택해 직접 접근하기위해 ref를 사용한다.</strong></em></p>
<h1 id="어떤-경우에-ref를-사용">어떤 경우에 ref를 사용?</h1>
<p>React에서 State로 해결할 수 없고, DOM을 반드시 직접 건드려야 할 때 사용하게 된다. </p>
<ul>
<li>js로 DOM요소에 focus, 텍스트 선택 영역, 미디어의 재생을 관리</li>
<li>애니메이션 직접적으로 실행</li>
</ul>
<h2 id="ref-사용-예시">ref 사용 예시</h2>
<pre><code class="language-js">class Example extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      value: &quot;&quot;
    };
  }

  render() {
    return (
      &lt;input
        value={this.state.value}
        onChange={({ target: { value } }) =&gt;
          this.setState({ ...this.state, value })
        }
      /&gt;
    );
  }
}</code></pre>
<p>위 코드는 일반적인 React 상태로 제어하는 컴포넌트이다. 
<strong>State로 input의 value를 관리하기 때문에 Input에서 키보드를 입력할 때마다 state가 변하게 되고 <code>ui를 업데이트하기위해 re-rendering</code>이 일어난다</strong></p>
<p>이러한 프로세스는 불피요한 컴퓨팅 자원을 소모하는 이슈이다. </p>
<pre><code class="language-js">class Example2 extends React.Component {
  constructor(props) {
    super(props);

    this.ref = React.createRef();
  }

  render() {
    return (
      &lt;input ref={this.ref} /&gt;
    );
  }
}</code></pre>
<p>따라서 ref가 input을 가리키면 state를 변경하지 않기 때문에 re-rendering은 일어나지 않는다.</p>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://tecoble.techcourse.co.kr/post/2021-05-15-react-ref/">https://tecoble.techcourse.co.kr/post/2021-05-15-react-ref/</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Excel data를 DB로 INSERT(마이그레이션) 하는 법]]></title>
            <link>https://velog.io/@wheezy_han/Excel-data%EB%A5%BC-DB%EB%A1%9C-INSERT%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98-%ED%95%98%EB%8A%94-%EB%B2%95</link>
            <guid>https://velog.io/@wheezy_han/Excel-data%EB%A5%BC-DB%EB%A1%9C-INSERT%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98-%ED%95%98%EB%8A%94-%EB%B2%95</guid>
            <pubDate>Fri, 27 May 2022 05:47:57 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>대량의 데이터를 db에 insert할 때 엑셀로 보통 자료를 받는다고 한다.</p>
<p>하는 방법은 아래와 같다 😲</p>
<h2 id="엑셀에-data-입력">엑셀에 data 입력</h2>
<p>아래의 사진과 같이 data가 있다고 가정해보자.</p>
<table>
<thead>
<tr>
<th><strong>Excel로 받은 data 예시</strong></th>
</tr>
</thead>
<tbody><tr>
<td><img src="https://velog.velcdn.com/images/wheezy_han/post/15007557-ffdf-44b5-8f4b-2edbc12bd08f/image.png" alt=""></td>
</tr>
</tbody></table>
<h2 id="첫번째-행에-쿼리-작성">첫번째 행에 쿼리 작성</h2>
<p>데이터가 들어있는 첫번째 행에 쿼리를 작성해준다.</p>
<p>이때 number</p>
<ul>
<li>&quot; 셀번호 &quot;</li>
</ul>
<p>varchar는</p>
<ul>
<li>&#39;&quot; 셀번호 &quot;&#39;<pre><code class="language-sql">=CONCATENATE(&quot;INSERT INTO test  VALUES (&quot;,A2,&quot;, &#39;&quot;,B2,&quot;&#39;, &#39;&quot;,C2,&quot;&#39;, &quot;,D2,&quot;);&quot;)</code></pre>
<h2 id="드래그">드래그</h2>
첫번째 셀에 위와 같이 쿼리를 작성해주면 <strong><em>알아서 첫번째 행의 데이터가 들어간 쿼리가 작성</em></strong>될 것이다.
이후 드래그만 해주면 완성!</li>
</ul>
<table>
<thead>
<tr>
<th><strong>Excel 작성 예시</strong></th>
</tr>
</thead>
<tbody><tr>
<td><img src="https://velog.velcdn.com/images/wheezy_han/post/0b19231d-8b7e-4bf7-a324-5d59507efb5b/image.png" alt=""></td>
</tr>
</tbody></table>
<h2 id="데이터-베이스에-쿼리문-복사-및-실행">데이터 베이스에 쿼리문 복사 및 실행</h2>
<table>
<thead>
<tr>
<th><strong>데이터 베이스에 쿼리문 복사 및 실행 예시</strong></th>
</tr>
</thead>
<tbody><tr>
<td><img src="https://velog.velcdn.com/images/wheezy_han/post/5c813bac-8cde-44af-90fc-959dace8eeba/image.png" alt=""></td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[node.js]windows에서 프로젝트 node 버전 관리(nvm)]]></title>
            <link>https://velog.io/@wheezy_han/node.jswindows%EC%97%90%EC%84%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-node-%EB%B2%84%EC%A0%84-%EA%B4%80%EB%A6%ACnvm</link>
            <guid>https://velog.io/@wheezy_han/node.jswindows%EC%97%90%EC%84%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-node-%EB%B2%84%EC%A0%84-%EA%B4%80%EB%A6%ACnvm</guid>
            <pubDate>Tue, 17 May 2022 06:58:52 GMT</pubDate>
            <description><![CDATA[<h1 id="intro">Intro</h1>
<p>프로젝트마다 다른 node 버전이 필요해서 버전 관리가 필요했다.
A 프로젝트 - node v10.24.1
B 프로젝트 - node v13.14.0</p>
<h1 id="nvm이란">NVM이란?</h1>
<blockquote>
<p>Node Version Manager</p>
</blockquote>
<p>노드 버전을 업데이트하기 위한 패키지로 쉽게 Node.js 버전을 관리할 수 있다. 
nvm을 설치해놓으면 명령어 하나로 노드 버전을 변경할 수 있다. </p>
<h2 id="nvm-이점">NVM 이점</h2>
<ul>
<li>컴퓨터에 다양한 버전의 Node.js를 설치 가능</li>
<li>node 버전 간단하게 스위칭 가능</li>
<li>설정, 리스트 확인, 삭제 등 관리가 쉬움</li>
</ul>
<h1 id="사용방법">사용방법</h1>
<p>📍 핵심!</p>
<ul>
<li>기존에 node가 설치되어있으면 삭제</li>
<li><strong>nvm -&gt; node 순으로 설치</strong>
만약 <em>node 설치 후 nvm을 설치해주면 nvm에서 버전을 변경을 해줘도 반영이 안됨</em> </li>
</ul>
<h2 id="nvm-설치">NVM 설치</h2>
<p>아래 경로로 들어가 <code>nvm-setup.zip</code> 파일 다운로드 후 압축 풀기 및 exe 실행하면된다.
<a href="https://github.com/coreybutler/nvm-windows/releases">https://github.com/coreybutler/nvm-windows/releases</a></p>
<pre><code class="language-bash">nvm vesrion // 버전 확인

nvm ls // 설치된 node 리스트 확인. 만약 처음이면 설치된 리스트가 없음.
</code></pre>
<p><img src="https://velog.velcdn.com/images/wheezy_han/post/53ad31fd-e425-4c4d-b57f-616b26596b63/image.png" alt=""></p>
<p>그 다음 원하는 버전을 설치해주면 된다.</p>
<pre><code class="language-bash">nvm install v13.14.0</code></pre>
<p>만약에 여러 버전이 있다면 설치 후 원하는 버전을 사용해주면 된다.</p>
<pre><code class="language-bash">nvm use 13.14.0</code></pre>
<h2 id="오류-해결">오류 해결</h2>
<p>위의 방법으로 바로 되는 경우도 있지만 나는 그렇지 않았다...😥</p>
<p>원하는 버전을 쓰려고 아래처럼 명령어를 쳤을 때 오류가 발생하였다. 
관리자 권한으로 실행하면 <strong>exit status 145로 숫자만 변경</strong>되고 오류는 동일하였다.</p>
<pre><code class="language-bash">nvm use 원하는 버전</code></pre>
<p><img src="https://velog.velcdn.com/images/wheezy_han/post/a4e78976-f7bb-4580-aa95-c29d1c6e1982/image.png" alt=""></p>
<h3 id="순서">순서</h3>
<blockquote>
<ol>
<li>NVM 삭제</li>
<li>scoop 설치</li>
<li>scoop을 이용한 NVM 설치</li>
</ol>
</blockquote>
<ol>
<li>NVM 삭제</li>
</ol>
<ul>
<li>제어판에 들어가 앞서 설치한 NVM을 삭제</li>
</ul>
<ol start="2">
<li>scoop 설치</li>
</ol>
<ul>
<li>아래의 명령어를 차례로 치면 된다.<pre><code class="language-bash">&gt; Set-ExecutionPolicy RemoteSigned -scope CurrentUser 
&gt; $env:SCOOP = &#39;D:\Scoop&#39; // 원하는 드라이브로 경로 설정 가능
&gt; iex (new-object net.webclient).downloadstring(&#39;https://get.scoop.sh&#39;)</code></pre>
<img src="https://velog.velcdn.com/images/wheezy_han/post/7b4a19ff-2c57-443e-84ea-80194346a597/image.png" alt=""></li>
</ul>
<p>다시 <code>nvm use 원하는 버전</code>을 입력해주면 정상 작동이 된다 :&gt;</p>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://velog.io/@mayinjanuary/NVM-%EC%9D%B4%EB%9E%80-%EB%85%B8%EB%93%9CNode.js-%EB%B2%84%EC%A0%84-%EA%B4%80%EB%A6%AC%ED%95%98%EB%8A%94-%EB%B2%95">https://velog.io/@mayinjanuary/NVM-%EC%9D%B4%EB%9E%80-%EB%85%B8%EB%93%9CNode.js-%EB%B2%84%EC%A0%84-%EA%B4%80%EB%A6%AC%ED%95%98%EB%8A%94-%EB%B2%95</a></li>
<li><a href="https://jaegeun.tistory.com/62">https://jaegeun.tistory.com/62</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[GIT] warning: LF will be replaced by CRLF in README.md. 오류 해결]]></title>
            <link>https://velog.io/@wheezy_han/GIT-warning-LF-will-be-replaced-by-CRLF-in-README.md.-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0</link>
            <guid>https://velog.io/@wheezy_han/GIT-warning-LF-will-be-replaced-by-CRLF-in-README.md.-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0</guid>
            <pubDate>Fri, 13 May 2022 07:22:08 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/wheezy_han/post/215cb8f8-7ce3-41dc-890a-803505226a43/image.png" alt=""></p>
<pre><code>warning: LF will be replaced by CRLF in README.md.</code></pre><h2 id="error">Error</h2>
<p>git을 사용하면 이런 error을 보게 되는 경우가 있다.
이는 <strong>mac 또는 linux를 쓰는 개발자와 window 개발자가 Git으로 협업할 때 발생하는 whitespace 에러이다.</strong>
나또한 macOS를 사용하는 분의 코드를 clone 시키고 나의 windowOS에서 수정 후 올리려고 하다가 보게 되었다🙄</p>
<p>다시 말해 다른 시스템에서 new line (줄바꿈) 문자열에 차이가 있어 나오는 경고문이다. 
◾ 유닉스 시스템은 한줄의 끝이 <strong>LF(Line Feed)</strong>로 이루어짐
◾ 윈도우 시스템은 CR(Carriage Return)와 LF(Line Feed), 즉 <strong>CRLF(Carriage Return Line Feed)</strong>방식을 사용해 줄 바꿈 시 변환 오류가 날 수 있다고 한다.</p>
<h2 id="solution">Solution</h2>
<p><code>core.autocrlf</code>는 자동변환해주는 기능을 갖고 있어 이 기능을 켜주면 된다. </p>
<h3 id="window">window</h3>
<pre><code class="language-bash">git config --global core.autocrlf true</code></pre>
<h3 id="linux">Linux</h3>
<pre><code class="language-bash">git config --global core.autocrlf true input</code></pre>
<h4 id="참고">참고</h4>
<ul>
<li><a href="https://blog.jaeyoon.io/2018/01/git-crlf.html">https://blog.jaeyoon.io/2018/01/git-crlf.html</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>