<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>moonBack.log</title>
        <link>https://velog.io/</link>
        <description>개발, 오류, 무한루프</description>
        <lastBuildDate>Thu, 25 Jul 2024 04:02:11 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>moonBack.log</title>
            <url>https://velog.velcdn.com/images/moon_back/profile/35de89a2-6781-4df9-b9bc-d28f7674cd01/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. moonBack.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/moon_back" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[scroll bar design]]></title>
            <link>https://velog.io/@moon_back/scroll-bar-design</link>
            <guid>https://velog.io/@moon_back/scroll-bar-design</guid>
            <pubDate>Thu, 25 Jul 2024 04:02:11 GMT</pubDate>
            <description><![CDATA[<p>윈도우와 맥의 가장 큰 차이점 중 하나는 scroll bar의 기본 디자인이 매우 다르다는 것이다. 이 때문에 원하는 디자인을 만들 수가 없는 경우가 있다. 따라서 디자인을 통일시켜야 하며 이를 위해 기본적인 scroll bar의 디자인을 살펴보자.</p>
<p>webkit 브라우저(파이어폭스 외)에 대해서만 먼저 살펴보자</p>
<h1 id="wibkit-브라우저-스크롤바-속성">wibkit 브라우저 스크롤바 속성</h1>
<p align="center"><img src="https://velog.velcdn.com/images/moon_back/post/816fdada-54dd-461a-845b-d6257372bc75/image.png" width=50%/></p>

<ol>
<li>::webkit-scrollbar: 스크롤바 전체</li>
<li>::webkit-scrollbar-thumb: 페이지의 위치를 알려주는 막대</li>
<li>::webkit-scrollbar-track: 스크롤이 움직이는 영역</li>
<li>::webkit-scrollbar-button: 스크롤 방향 버튼</li>
<li>::webkit-scrollbar-track-piece: track에서 thumb을 제외한 부분</li>
<li>::webkit-scrollbar-corner: 수직, 수평 스크롤이 만나는 부분</li>
<li>::webkit-scrollbar-resizer: 크기 조정 핸들</li>
</ol>
<p>firefox와 IE이용자가 매우 드물기에 이 속성만 이용해서 스크롤 설정해도 충분하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React 매개변수에 관하여]]></title>
            <link>https://velog.io/@moon_back/React-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC</link>
            <guid>https://velog.io/@moon_back/React-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC</guid>
            <pubDate>Thu, 04 Jul 2024 09:01:23 GMT</pubDate>
            <description><![CDATA[<p>자식 컴포넌트로 데이터를 전달해줄 때 유의해야되는 것이 있다. 실행한 함수가 참조하는 매개변수는 실행할 때를 기준으로 실행된다는 것이다.</p>
<p>크게 문제가 되지 않지만 socket과 같이 맨처음에만 실행하고 그 뒤에 데이터를 받는다면 참조하는 데이터가 실행했을 때 값을 가지고 있다는 것이다. ㅋㅋㅋ......</p>
<p>내 3시간</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[useEffect에서 async await사용]]></title>
            <link>https://velog.io/@moon_back/useEffect%EC%97%90%EC%84%9C-async-await%EC%82%AC%EC%9A%A9</link>
            <guid>https://velog.io/@moon_back/useEffect%EC%97%90%EC%84%9C-async-await%EC%82%AC%EC%9A%A9</guid>
            <pubDate>Mon, 17 Jun 2024 13:48:23 GMT</pubDate>
            <description><![CDATA[<p>useEffect에서는 async await을 사용할 수 없다.</p>
<p>다음과 같이 써야 한다.</p>
<pre><code>useEffect(()=&gt;{
    async function data() {
    ...
    }
    data()
})</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[React build시 코드 난독화]]></title>
            <link>https://velog.io/@moon_back/React-build%EC%8B%9C-%EC%BD%94%EB%93%9C-%EB%82%9C%EB%8F%85%ED%99%94</link>
            <guid>https://velog.io/@moon_back/React-build%EC%8B%9C-%EC%BD%94%EB%93%9C-%EB%82%9C%EB%8F%85%ED%99%94</guid>
            <pubDate>Fri, 17 May 2024 12:16:43 GMT</pubDate>
            <description><![CDATA[<p>웹 상에서 코드를 확인하지 못하도록 난독화할 필요가 있다.(보안적 측면으로)</p>
<pre><code>&quot;scripts&quot;: {
    ...
    &quot;build&quot;: &quot;GENERATE_SOURCEMAP=false react-scripts build&quot;
    ...
}</code></pre><p>로 pachage.json을 수정하면 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[아래로 항상 스크롤]]></title>
            <link>https://velog.io/@moon_back/%EC%95%84%EB%9E%98%EB%A1%9C-%ED%95%AD%EC%83%81-%EC%8A%A4%ED%81%AC%EB%A1%A4</link>
            <guid>https://velog.io/@moon_back/%EC%95%84%EB%9E%98%EB%A1%9C-%ED%95%AD%EC%83%81-%EC%8A%A4%ED%81%AC%EB%A1%A4</guid>
            <pubDate>Mon, 13 May 2024 05:33:52 GMT</pubDate>
            <description><![CDATA[<p>메시지 창을 구현하면 항상 아래로 가야할 때가 있다</p>
<p>useRef로 구현가능하다.</p>
<pre><code>LiveChat.js

import { useEffect, useState, useRef } from &quot;react&quot;

export function LiveChat() {
    const [chatList, setChatList] = useState([]);
    const messageEndRef = useRef(null);

    useEffect(() =&gt; {
        messageEndRef.current.scrollIntoView({ behavior: &#39;smooth&#39; });
    }, [chatList]);

    return (
        &lt;div className = &quot;chatList&quot;&gt;
            {chatList...}
            &lt;div ref={messageEndRef}&gt;&lt;/div&gt;
        &lt;/div&gt;

    )

}</code></pre><p>이런식으로 ref를 마지막에 줌으로써 해결가능하다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[socketio 사용법]]></title>
            <link>https://velog.io/@moon_back/socketio-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@moon_back/socketio-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Mon, 13 May 2024 04:58:01 GMT</pubDate>
            <description><![CDATA[<p>실시간으로 통신하기 위해서 Socket.io를 사용하기로했다.</p>
<ol>
<li><p>설치</p>
<pre><code>npm install socket.io-client</code></pre></li>
<li><p>통신환경 설정</p>
<pre><code>socket.js
</code></pre></li>
</ol>
<p>import io from &#39;socket.io-client&#39;;</p>
<p>export const sio = io(&#39;<a href="https://localhost&#39;">https://localhost&#39;</a>, 
    {path: &#39;/api/socket.io/&#39;, 
    cors: {
        origin: &quot;*&quot;,
        methods: [&quot;GET&quot;, &quot;POST&quot;],
        transports: [&#39;websocket&#39;, &#39;polling&#39;],
        credentials: true
    },
    allowEIO3:true
});</p>
<pre><code>
3. 사용법
사용할 때 connect, 연결이 끝났을 때 disconnect로 socket을 제어해야한다. 안그러면 쓸일없는 데이터가 계속해서 전송되는 참사가..
</code></pre><p>useEffect(()=&gt;{
    setIsConnect(true);
    sio.connect();
    console.log(&#39;socket connected&#39;)</p>
<pre><code>return () =&gt; {
  if(isConnect) {
    setIsConnect(false);
    sio.disconnect();
    console.log(&#39;socket disconnected&#39;)
  }</code></pre><p>  };
  }, [])</p>
<pre><code>
emit를 이용하면 backend에 데이터를 전달해줄 수 있다.</code></pre><p>useEffect(()=&gt;{
    if(isConnect) {
        sio.emit(&#39;start&#39;)
        console.log(&#39;socket start&#39;)
    } else {
        sio.emit(&#39;stop&#39;)
    }
  }, [])</p>
<pre><code>on을 이용해서 이벤트를 받아온다.
</code></pre><p>useEffect(() =&gt; {
        sio.on(&#39;comment&#39;, (data) =&gt; {
            setChatList([...chatList, {user: data[0], message:data[1]}])
        })</p>
<pre><code>    console.log(chatList)

    return () =&gt; {
        sio.off(&#39;comment&#39;)
    }

  })</code></pre><p>```
이벤트가 끝나면 꼭 off해줘야 한다.</p>
<p>만약 통신이 안된다면 backend에서 CORS에러가 발생하지 않았는지 확인해보자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[input 기본 스타일 없애는법]]></title>
            <link>https://velog.io/@moon_back/input-%EA%B8%B0%EB%B3%B8-%EC%8A%A4%ED%83%80%EC%9D%BC-%EC%97%86%EC%95%A0%EB%8A%94%EB%B2%95</link>
            <guid>https://velog.io/@moon_back/input-%EA%B8%B0%EB%B3%B8-%EC%8A%A4%ED%83%80%EC%9D%BC-%EC%97%86%EC%95%A0%EB%8A%94%EB%B2%95</guid>
            <pubDate>Mon, 06 May 2024 07:39:15 GMT</pubDate>
            <description><![CDATA[<pre><code>/* input 기본 스타일 초기화 */
input {
    -webkit-appearance: none;
       -moz-appearance: none;
            appearance: none;
}

input:focus {
    outline: none;
}

/* IE10 이상에서 input box 에 추가된 지우기 버튼 제거 */
input::-ms-clear { display: none; }</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[react-router-dom 사용하기]]></title>
            <link>https://velog.io/@moon_back/react-router-dom-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@moon_back/react-router-dom-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 06 May 2024 07:19:21 GMT</pubDate>
            <description><![CDATA[<p>조금 더 사이트를 동적으로 만들고 싶다면 react-router-dom사용이 필수적이다.</p>
<p>여러 기능들이 있지만 많이 쓰는 요소만 정리한다.</p>
<ol>
<li><p>react-router-dom 설치</p>
<pre><code>npm install react-router-dom</code></pre></li>
<li><p>요소들을 web link에 따라 다르게 작동시키고 싶을 때</p>
</li>
</ol>
<p>index.js</p>
<pre><code>import React from &#39;react&#39;;
import ReactDOM from &#39;react-dom/client&#39;;
import { BrowserRouter, Routes } from &#39;react-router-dom&#39;;
import App from &#39;./App&#39;;

const root = ReactDOM.createRoot(document.getElementById(&#39;root&#39;));
root.render(
  &lt;BrowserRouter&gt;
      &lt;App /&gt;
  &lt;/BrowserRouter&gt;
);</code></pre><p>App.js</p>
<pre><code>import { Route, Routes } from &quot;react-router-dom&quot;;
import FirstPage from &quot;./firstPage&quot;;
import { PrivacyPolicy, TermsOfService } from &quot;./footerMenu&quot;;
import { Login } from &quot;./login&quot;;
import Dashboard from &quot;./dashboard&quot;;

function App() {
  return (
    &lt;div&gt;
        &lt;Routes&gt;
            &lt;Route path=&quot;/&quot; element={&lt;FirstPage/&gt;}&gt;&lt;/Route&gt;
            &lt;Route path=&quot;/login&quot; element={&lt;Login/&gt;}&gt;&lt;/Route&gt;
            &lt;Route path=&quot;/dashboard&quot; element={&lt;Dashboard/&gt;}&gt;&lt;/Route&gt;
            &lt;Route path=&quot;/terms-of-service&quot; element={&lt;TermsOfService/&gt;}&gt;&lt;/Route&gt;
            &lt;Route path=&quot;/privacy-policy&quot; element={&lt;PrivacyPolicy/&gt;}&gt;&lt;/Route&gt;
        &lt;/Routes&gt;
    &lt;/div&gt;
  );
}

export default App;</code></pre><p>이런식으로 Routes가 Route를 감싸는 형식으로 존재해야 한다.</p>
<ol start="3">
<li>Link활용하기
단순히 a태그를 사용하면 웹 사이트 전체가 리로딩되면서 로딩시간이 길어진다. 이를 줄이기 위해 Link태그를 이용해서 부분만 리로딩한다.</li>
</ol>
<pre><code>import { Link } from &#39;react-router-dom&#39;

.
.
.

&lt;Link to=&quot;/privacy-policy&quot;&gt;Privacy Policy&lt;/Link&gt;</code></pre><p>이런식으로 a태그 자리에 Link를 쓰면 된다.</p>
<ol start="4">
<li>useNavigate
조건에 따라 로그인이 안되어있으면 login페이지로 redirect하고 싶을 때가 있다. 이때 다음과 같이 써주면 자연스레 쓸 수 있다.</li>
</ol>
<pre><code>import { useNavigate } from &#39;react-router-dom&#39;;

.
.
.

const navigate = useNavigate();

  useEffect(() =&gt; {
    axios.get(&#39;/api/auth/test&#39;)
      .then(response =&gt; {
        console.log(response)
      })
      .catch(error =&gt; {
        console.error(&#39;Authentication error:&#39;, error);
        navigate(&#39;/login&#39;);
      });
  }, [navigate]);</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[react에서 state를 중복해서 갱신하지 않는 법]]></title>
            <link>https://velog.io/@moon_back/react%EC%97%90%EC%84%9C-state%EB%A5%BC-%EC%A4%91%EB%B3%B5%ED%95%B4%EC%84%9C-%EA%B0%B1%EC%8B%A0%ED%95%98%EC%A7%80-%EC%95%8A%EB%8A%94-%EB%B2%95</link>
            <guid>https://velog.io/@moon_back/react%EC%97%90%EC%84%9C-state%EB%A5%BC-%EC%A4%91%EB%B3%B5%ED%95%B4%EC%84%9C-%EA%B0%B1%EC%8B%A0%ED%95%98%EC%A7%80-%EC%95%8A%EB%8A%94-%EB%B2%95</guid>
            <pubDate>Thu, 11 Apr 2024 12:55:49 GMT</pubDate>
            <description><![CDATA[<p>만약 state를 useEffect를 통해 갱신했다면 값이 바뀔때마다 state가 변할것이다. state를 시간차없이 출력하면 크게 신경쓰지 않아도 되지만, 시간차를 두고 출력한다면 useEffect의 값이 바뀔 때마다 값들이 혼란스럽게 바뀌는 것을 볼 수 있다.</p>
<p>여러 검색을 통해 알아낸 결과 단순히 useEffect에 return을 넣어주면 해결된다...</p>
<pre><code>const [time, setTime] = useState(0)
let retry;
useEffect(()=&gt;{
    setTime(time++)
    return(()=&gt;{
        setTime(0)
    })
},[retry])</code></pre><p>검색을 일상화하자. chatGPT는 신이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[react 구성]]></title>
            <link>https://velog.io/@moon_back/react-%EA%B5%AC%EC%84%B1</link>
            <guid>https://velog.io/@moon_back/react-%EA%B5%AC%EC%84%B1</guid>
            <pubDate>Tue, 02 Apr 2024 16:40:46 GMT</pubDate>
            <description><![CDATA[<p>react를 오랜만에 써본다. Backend는 요즘 팀원이 빠져있는 fastAPI를 사용하기로 했다. 이 페이지에서는 react만을 구성해보려한다.</p>
<p>먼저 backend가 있는 디렉토리에서 아래와 같이 작성하여 react를 구성한다.</p>
<pre><code>npx create-react-app frontend</code></pre><p>Docker를 사용하고 있기에 frontend를 위한 Dockerfile을 만들어준다.</p>
<pre><code># frontend/Dockerfile
FROM node

WORKDIR /workspace
RUN npm install axios

CMD [&quot;npm&quot;, &quot;start&quot;]</code></pre><p>이후 backend,nginx와 도커를 합치기 위해 docker-compose.yml에 다음과 같이 작성한 코드를 추가한다.</p>
<pre><code>frontend:
    build:
      context: frontend/.
      dockerfile: Dockerfile
    container_name: my-web-frontend
    tty: true
    ports:
      - 3000:3000
    volumes:
      - ./frontend:/workspace
      - ./assets:/assets
    command: npm start</code></pre><p>이후 docker가 생성되길 기다린 뒤 실행시키면 react가 돌아가는 것을 확인할 수 있다.</p>
<pre><code>docker-compose up</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[블로그를 시작한 이유]]></title>
            <link>https://velog.io/@moon_back/%EB%B8%94%EB%A1%9C%EA%B7%B8%EB%A5%BC-%EC%8B%9C%EC%9E%91%ED%95%9C-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@moon_back/%EB%B8%94%EB%A1%9C%EA%B7%B8%EB%A5%BC-%EC%8B%9C%EC%9E%91%ED%95%9C-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Tue, 02 Apr 2024 15:56:22 GMT</pubDate>
            <description><![CDATA[<p>일단 이렇게 글을 쓰는게 정말 오랜만이다. 글을 쓰는 걸 그닥 좋아하지 않고 기록을 별로 좋아하지 않았다. 귀찮으니깐. </p>
<p>하지만 기록의 필요성을 느끼게 되었다.</p>
<ol>
<li>기억은 휘발성이다. 
점차 배워가는 게 많아지고 여러 언어를 접하게 되니 내가 모든 걸 기억할 수 없었다. </li>
<li>나의 개발 경력을 누가 알아줄까.
대회, 해커톤을 도전할때마다 팀원들은 나에게 물어봤다. &quot;지금까지 뭐하셨어요?&quot;. 이 말에 구구절절 설명하는 내 모습이 보였다. &#39;저들이 과연 내 말을 믿어줄까?&#39;라는 생각이 드는 순간 나의 커리어는 허상이 되어버렸다.</li>
</ol>
<p>사실 두번째 이유가 거의 전부이다. 운동을 하면 몸이 변화하고 공부를 하면 성적이 변하는데 개발을 하면 단시간 내에 내가 보여줄 수 있는게 무엇인가. 이 생각을 통해 나온 결론은 &#39;개발일지와 포트폴리오를 쓰자.&#39;였다. 개발일지는 월 4회, 포트폴리오는 분기당 1개씩 쌓아가는 걸로 목표를 세웠다. </p>
<p>성공해야지.</p>
]]></description>
        </item>
    </channel>
</rss>