<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>sloth.log</title>
        <link>https://velog.io/</link>
        <description>hi world</description>
        <lastBuildDate>Mon, 28 Sep 2026 06:15:15 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>sloth.log</title>
            <url>https://velog.velcdn.com/images/sloth_slys/profile/d2a5ba47-89f0-40b7-9fa5-cf3e2678e9ca/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. sloth.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sloth_slys" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[멋사 10주차 회고록]]></title>
            <link>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-10%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-10%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Mon, 28 Sep 2026 06:15:15 GMT</pubDate>
            <description><![CDATA[<h1 id="간단-개요">간단 개요</h1>
<p>이번 주차에서는 디자인 연습 대신, Type Script 학습이 주 내용이었어서 기존 코드를 타입스크립트로 변형하는 연습, 들은 강의 내용 정리 정도만 있을 예정이다.</p>
<h3 id="과제-코드-포팅자바스크립트---타입스크립트">과제: 코드 포팅(자바스크립트 -&gt; 타입스크립트)</h3>
<pre><code class="language-jsx">&lt;기존코드. TIL컴포넌트 변수,함수 부분&gt;
import React, { useState, useEffect } from &#39;react&#39;;

export default function TilSection() {
  const [tils, setTils] = useState(() =&gt; {
    const saved = localStorage.getItem(&#39;study_tils&#39;);
    return saved ? JSON.parse(saved) : [
      { 
        id: 1, 
        title: &#39;React useState로 상태 관리하기&#39;, 
        code: &#39;const [count, setCount] = useState(0);&#39;, 
        date: &#39;2026-09-14&#39;, 
        category: &#39;React&#39; 
      },
      { 
        id: 2, 
        title: &#39;(더미)Tailwind CSS v4 flex 레이아웃&#39;, 
        code: &#39;className=&quot;flex items-center justify-between gap-4&quot;&#39;, 
        date: &#39;2026-09-13&#39;, 
        category: &#39;CSS&#39; 
      }
    ];
  });

  const [newTitle, setNewTitle] = useState(&#39;&#39;);
  const [newCode, setNewCode] = useState(&#39;&#39;);
  const [newCategory, setNewCategory] = useState(&#39;React&#39;);
  const [openCodeId, setOpenCodeId] = useState(null);

  useEffect(() =&gt; {
    localStorage.setItem(&#39;study_tils&#39;, JSON.stringify(tils));
  }, [tils]);
const handleAddTil = (e) =&gt; {
  e.preventDefault(); // 폼 제출 시 페이지가 새로고침되는 기본 동작을 막음
  if (!newTitle.trim()) return; // 제목이 빈칸이거나 공백뿐이면 추가하지 않고 함수 종료

  const newItem = {
    id: Date.now(), // 현재 시각(밀리초)을 고유 id로 사용 (중복 방지)
    title: newTitle,
    code: newCode || &#39;// 작성된 코드가 없습니다.&#39;, // 코드를 안 적었다면 기본 안내 문구 삽입
    date: new Date().toISOString().split(&#39;T&#39;)[0], // 오늘 날짜를 &#39;YYYY-MM-DD&#39; 형식으로 추출
    category: newCategory,
  };

  setTils([newItem, ...tils]); // 기존 목록(...tils) 맨 앞에 새 아이템을 쏙 집어넣어 최신순 정렬 유지
  setNewTitle(&#39;&#39;); // 입력창 초기화
  setNewCode(&#39;&#39;);  // 코드창 초기화
};

  // 특정 ID의 TIL을 삭제하는 함수
  const handleDeleteTil = (id, e) =&gt; {
    e.stopPropagation(); // 카드 펼치기/접기 이벤트와 충돌하는 것 방지
    setTils(tils.filter(item =&gt; item.id !== id));
  };

  const toggleCode = (id) =&gt; {
    setOpenCodeId(openCodeId === id ? null : id);
  };
</code></pre>
<p>변형 </p>
<pre><code class="language-TypeScript">import React, { useState, useEffect } from &#39;react&#39;;

export default function TilSection() {

    interface Til {
        id: number;
        title: string;
        code: string;
        date: string;
        category: string;
    }


  const [tils, setTils] = useState&lt;Til[]&gt;(() =&gt; {
    const saved = localStorage.getItem(&#39;study_tils&#39;);
    return saved ? JSON.parse(saved) : [
      { 
        id: 1, 
        title: &#39;React useState로 상태 관리하기&#39;, 
        code: &#39;const [count, setCount] = useState(0);&#39;, 
        date: &#39;2026-09-14&#39;, 
        category: &#39;React&#39; 
      },
      { 
        id: 2, 
        title: &#39;(더미)Tailwind CSS v4 flex 레이아웃&#39;, 
        code: &#39;className=&quot;flex items-center justify-between gap-4&quot;&#39;, 
        date: &#39;2026-09-13&#39;, 
        category: &#39;CSS&#39; 
      }
    ];
  });

  const [newTitle, setNewTitle] = useState&lt;string&gt;(&#39;&#39;);
  const [newCode, setNewCode] = useState&lt;string&gt;(&#39;&#39;);
  const [newCategory, setNewCategory] = useState&lt;string&gt;(&#39;React&#39;);
  const [openCodeId, setOpenCodeId] = useState&lt;number | null&gt;(null);

  useEffect(() =&gt; {
    localStorage.setItem(&#39;study_tils&#39;, JSON.stringify(tils));
  }, [tils]);
const handleAddTil = (e:React.FormEvent) =&gt; {
    //number, string 같은 값이 아니라 이벤트 객체라서. 저런 이상한 타입이 붙음. 여기선 폼 제출
  e.preventDefault(); // 폼 제출 시 페이지가 새로고침되는 기본 동작을 막음
  if (!newTitle.trim()) return; // 제목이 빈칸이거나 공백뿐이면 추가하지 않고 함수 종료

  const newItem = {
    id: Date.now(), // 현재 시각(밀리초)을 고유 id로 사용 (중복 방지)
    title: newTitle,
    code: newCode || &#39;// 작성된 코드가 없습니다.&#39;, // 코드를 안 적었다면 기본 안내 문구 삽입
    date: new Date().toISOString().split(&#39;T&#39;)[0], // 오늘 날짜를 &#39;YYYY-MM-DD&#39; 형식으로 추출
    category: newCategory,
  };

  setTils([newItem, ...tils]); // 기존 목록(...tils) 맨 앞에 새 아이템을 쏙 집어넣어 최신순 정렬 유지
  setNewTitle(&#39;&#39;); // 입력창 초기화
  setNewCode(&#39;&#39;);  // 코드창 초기화
};

  // 특정 ID의 TIL을 삭제하는 함수
  const handleDeleteTil = (id: number, e:React.MouseEvent) =&gt; { //여기선 코드 짤렸지만, onclick으로 작동해서 마우스 이벤트 튀급
    e.stopPropagation(); // 카드 펼치기/접기 이벤트와 충돌하는 것 방지
    setTils(tils.filter(item =&gt; item.id !== id));
  };

  const toggleCode = (id:number) =&gt; {
    setOpenCodeId(openCodeId === id ? null : id);
  };
}
</code></pre>
<h2 id="type-script-강의-메모-내용">Type Script 강의 메모 내용</h2>
<p><strong>아직 정리 안해서 드러움(내용 게속 추가 중)</strong></p>
<p>변수타입 숫자형으로 하려면 int가 아니라 number로 설정해야 함!
참/거짓은 boolean</p>
<p>보통 변수에 타입을 지정하는 방식은 c언어랑 다르게 
아래처럼 다르면서 좀 나눠져 있음</p>
<p>let (변수): (타입)</p>
<p>function (변수) (조건들): (함수 값 반환 타입)
{
함수내용
}</p>
<p>[배열]
let (배열명):(타입)[] = [배열내용]
또는
let (배열명):Array&lt;타입&gt; = [배열내용]</p>
<p>[튜플]
let (튜플명): [타입1, 타입2...];
예) let b: [number, string];
 b = [10, &#39;f&#39;]</p>
<p>[enum]
서로 관련된 값들을 하나의 이름으로 묶어 정의하는 형식</p>
<p>enum Day {
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday
}
let today: Day = Day.Monday;
또한 순서대로 값이 매핑 됨. 여기선 따로 값을 안건드렸으니 월요일부터 0,1,2,3,4...이런 식, </p>
<p>문자열도 매핑 가능한데 그럼 자동 매핑이 안됨</p>
<p>[null / undefined]</p>
<p>let (변수명): null = null
let (변수명): undefined = undefined</p>
<p>[interface]</p>
<pre><code>c언어의 구조체와 비슷하게 객체의 구조를 정의하는 형식
interface User{ -&gt;명칭은 대문자로 시작
    name: string -&gt; 필수속성
    age: number
    char? : string -&gt; 물음표 붙이면 비필수 속성
    readonly birth: number -&gt; 읽기 전용 속성. 수정불가(c언어의 const 느낌)

    [grade:number]: sring; -&gt; 어디서 많이 본 키: 벨류 형식 느낌(인덱스 시그니쳐 형식이라 부른다고 함)
}

let sheet : User = {
    name: &#39;sfsdf&#39;
    age: 20
}(필수 속성 안 넣은건 넘어가도록 하자)
sheet.age = 10; -&gt; 이런식으로 변경가능</code></pre><p>[implements]</p>
<pre><code>class Person implements User {
    name: string;
    age: number;

    constructor(name: string, age: number) { -&gt; 파이썬 init 처럼 클래스 생성시 초기화 해주는 함수
        this.name = name; -&gt;파이썬 self.~~ 와 다르게 this.~~임
        this.age = age;
    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[멋사 8,9 주차 회고록]]></title>
            <link>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-89-%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-89-%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Mon, 21 Sep 2026 08:41:45 GMT</pubDate>
            <description><![CDATA[<h1 id="tailwind로-만든-웹페이지배포-아직-안함">Tailwind로 만든 웹페이지(배포 아직 안함)</h1>
<p>멋사 2학기 스터디로 오래만에 다시 써보는 회고록. 오랜만이지만 별로 할 말은 많지않아서 인사글에 뭘 써야하는지 모르겠다.</p>
<p>별로 생각나지는 않으니 방학 동안 한 일을 따로 적어보자면, 방학 동안 약 1달정도를 멋사본사가 주최하는 애니멀 리그 해컨톤에 참가하였다. 간단하게 말해서, 비록 1차 심사에도 못오르고 떨어지긴 했지만. 결과물 제출, 따로 여기선 언급하지 않은 미니 해커톤 떄 제대로 못끝내고 마무리 했던 백엔드 서버와의 연동을, 본선 해커톤 떈 완벽하게 했다는 점에 의의를 두고 싶다. 
그리고는....별로 딱히 뭘 안했다. 해커톤 전에 2주는 방학 시작쯔음이라 쉬었는데.... 해커톤 끝나고 나니 방학이 5일 밖에 없었던 것으로 기억한다. ㅠㅠ</p>
<p><del>사실 이 회고록은 원래 8주차 때 작성 시작함 근데 귀차니즘 이슈터짐</del></p>
<p>이렇게 벨로그 조작법 다시 복구하는 겸 취소선으로 밝히고 싶지 않은 것도 밝히면서 진짜로 본문 내용을 시작하겠다.</p>
<h3 id="8주차-개요">8주차 개요</h3>
<p>우선 이 프로젝트 파일은 자바스크립트 + VITE + TailWind css를 사용하였다.</p>
<ol>
  <li>웹페이지 제목,파비콘 수정</li>
  <li>프로필 컴포넌트</li>
  <li>목록 카드 컴포넌트</li>
  <li>로컬 스토리지를 이용한 메모장 컴포넌트</li>
  <li>헤더,푸터<br/>5.1. 메뉴창 시스템 수정하기</li></li>
  <li>8주차 결과물 완성</li>
</ol>

<h3 id="9주차-개요">9주차 개요</h3>
<ol>
  <li>시간대에 따른 창문 배경 변화</li>
  <li>플레이 리스트 페이지</li>
</ol>

<h2 id="18주차-웹페이지-제목-파비콘-수정">1.(8주차) 웹페이지 제목, 파비콘 수정</h2>
<p>이것만큼은 진짜 이제 AI도움 필요 없을 정도로 익숙해졌다. 
그렇다고 눈감고 해보라하면 못한다.</p>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/1952e2cf-25a8-4803-89a4-751d72ab40c4/image.png" alt="">
우선 이것이 파비콘 이미지이다. Chat GPT를 이용해서 내 이름 이니셜인 TR울 락스타 로고 처럼 비슷하게 뽑아달라는 식으로 말하여 생성하였다.</p>
<p>그리고 png로 생성이 되었으니 
<a href="https://www.freeconvert.com/ko/png-to-ico">https://www.freeconvert.com/ko/png-to-ico</a>
해당 사이트를 이용하여 ico 형식으로 파일 변환을 한 후 </p>
<pre><code class="language-html">&lt;Index.html 파일&gt;


&lt;!doctype html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;link rel=&quot;icon&quot; type=&quot;image/svg+xml&quot; href=&quot;/favicon.ico&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Temporary_page&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;root&quot;&gt;&lt;/div&gt;
    &lt;script type=&quot;module&quot; src=&quot;/src/main.jsx&quot;&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>이렇게 파일명이 favicon.svg가 아닌 기존 기본 파비콘을 대체할 favicon.ico로 작성한뒤 겸사겸사 
title 태그 내부를........</p>
<p>딱히 작명센스가 그리 좋지 않아서 임시 페이지라고 영어로 작성 하였다.</p>
<h2 id="2-프로필-컴포넌트">2. 프로필 컴포넌트</h2>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/58b58c41-b7a6-4abd-b074-834c90fc39a9/image.png" alt="">
(8주차 당시 사진인데 상단 부분은 실명 이슈로 사진에서 짤림)</p>
<p>8주차 당시 딱히 소개글 넣을 내용이 없어서 그냥 만든 내용을 요약해서 작성한 상태이다.</p>
<pre><code class="language-javascript">export default function ProfileCard() {
  return (
    &lt;section id=&quot;profile&quot; className=&quot;bg-white rounded-2xl p-8 md:p-12 border border-gray-200 
    shadow-sm flex flex-col md:flex-row items-center gap-8&quot;&gt; 
     {/*컴포넌트 구역 설정, 박스 둥글게, 기본적으로 세로 배치지만 창 크기에 따라 가로 배치로 전환*/}
     {/*md:~~ 는 @media (min-width: 768px) 를 의미. 반응형 디자인용으로 사용됨*/}
     {/*id는 헤더 컴포넌트에서 href자리에 들어갈 id값, 해당 태그로 자동스크롤 기능 구현 가능*/}


 {/*프로필 사진 공간*/}
      &lt;div className=&quot;w-32 h-32 rounded-full bg-gradient-to-tr from-blue-500 to-indigo-600 flex items-center justify-center text-white text-4xl font-bold shadow-md&quot;&gt;
        TR
      &lt;/div&gt;
      {/*그라데이션 태그에 to-tr 은 오른쪽 위 방향을 의미 deg를 지정하는 대신 사용하는 듯 | shadow-md은 그림자가 살짝 입체감 있게 주어지게 함*/}

      {/*작은 소속 태그*/}
      &lt;div className=&quot;space-y-3 text-center md:text-left&quot;&gt;
        &lt;div className=&quot;inline-block px-3 py-1 bg-blue-50 text-blue-700 text-xs font-semibold rounded-full&quot;&gt;
          정보통신공학과
        &lt;/div&gt;
        {/*이름, 소속*/}
        &lt;h1 className=&quot;text-3xl md:text-4xl font-extrabold text-gray-900 tracking-tight&quot;&gt;
          이멋사 &lt;span className=&quot;text-gray-400 font-normal text-xl&quot;&gt;| 대학생&lt;/span&gt;
        &lt;/h1&gt;
         {/*텍스트*/}
        &lt;p className=&quot;text-gray-600 leading-relaxed max-w-xl&quot;&gt;
          (소개글 들어갈 자리)
          넣을게 없어서 대충 지금 웹페이지 기능정리
          &lt;br/&gt;&lt;br/&gt;1. 이름 이니셜로 파비콘 이미지 변경
          &lt;br/&gt;2. 현재 컴퓨터시간 우상단에 출력(갱신은 10초단위)
          &lt;br/&gt;3. 우측 메뉴창(≡)
          &lt;br/&gt;4. 제미나이가 지멋대로 만들어준 로컬스토리지 이용하는 메모장?
          &lt;br/&gt; &lt;br/&gt;&lt;h3&gt;NEW&lt;/h3&gt;
          5. 시간대별로 변하는 창문 기능(밝기 조정하느라 3시간 날려먹음)
          &lt;br/&gt;6. 노래 플레이 리스트(제작중.... 아직 순수 ai만 사용한 상태)
        &lt;/p&gt;

      &lt;/div&gt;
    &lt;/section&gt;
  );
}</code></pre>
<p>코드 전문은 이렇다
아 그리고 이번에 <code>&lt;setion&gt;</code> 태그라는 것을 알게 되었는데</p>
<p>찾아보니 일반인 입장에서는 <code>&lt;div&gt;</code>와 큰 차이가 없는 태그지만, 검색엔진의 입장에선 섹션이라는 태그를 하나의 주제가 담긴 구역으로 인식해 검색엔진 입장에선 도움이 되고, 스크린 리더라는 시각 장애인용 음성 안내 프로그램을 사용하는 사용자 입장에서도 구역 이동을 도우는 기능이라고 한다.</p>
<p>또한 해당 페이지에서 기존에도 알고있었지만 tailwind 문법으로 바뀐 기존 css코드를 제외하고 새롭게 알게 된 기능은
<code>id=&quot;profile&quot;</code>이라는 기능이다. </p>
<p>후술 할 헤더관련에서 자세히 이야기하겠지만, href속성에서 같은페이지 내에 있는 태그의 위치를 #(id)형식으로 전달해주면 자동으로 스크롤이 해당 구역으로 내려가는 기능이다.</p>
<h2 id="3-목록-카드-컴포넌트">3. 목록 카드 컴포넌트</h2>
<pre><code class="language-javascript">export default function SkillSection() {
  const skills = [&#39;C / C#&#39;, &#39;Python&#39;, &#39;React &amp; JavaScript&#39;, &#39;Tailwind CSS&#39;];

  return (
    &lt;section id=&quot;skills&quot; className=&quot;space-y-6&quot;&gt;
      &lt;h2 className=&quot;text-2xl font-bold text-gray-900 tracking-tight&quot;&gt;기술 스택&lt;/h2&gt;
      &lt;div className=&quot;grid grid-cols-2 sm:grid-cols-4 gap-4&quot;&gt;
        {/*map함수로 skils 리스트에 있는거 차례로 배당*/}
        {skills.map((skill, idx) =&gt; (
          &lt;div key={idx} className=&quot;bg-white p-5 rounded-xl border border-gray-200 shadow-sm flex flex-col justify-between hover:border-blue-300 transition&quot;&gt;
            &lt;span className=&quot;text-sm font-medium text-gray-400&quot;&gt;스택 0{idx + 1}&lt;/span&gt;
            &lt;span className=&quot;mt-4 font-semibold text-gray-800 text-lg&quot;&gt;{skill}&lt;/span&gt;
          &lt;/div&gt;
        ))}
      &lt;/div&gt;
    &lt;/section&gt;
  );
}</code></pre>
<p>(hover:border-blue-300로 마우스 올렸을시 파란테두리로 변경 + transition로 자연스럽게까지)</p>
<p>우선 목록 카드 컴포넌트의 주요 기능에선 배열과 map함수를 이용하였다.
array에 지금것 배운 컴퓨터 언어들을 입력해주었고</p>
<p>아래의 맵함수에서</p>
<pre><code class="language-javascript">        {skills.map((skill, idx) =&gt; (
          &lt;div key={idx} className=&quot;bg-white p-5 rounded-xl border border-gray-200 shadow-sm flex flex-col justify-between hover:border-blue-300 transition&quot;&gt;
            &lt;span className=&quot;text-sm font-medium text-gray-400&quot;&gt;스택 0{idx + 1}&lt;/span&gt;
            &lt;span className=&quot;mt-4 font-semibold text-gray-800 text-lg&quot;&gt;{skill}&lt;/span&gt;</code></pre>
<p>array에 넣어진 순서대로 값 할당을 해주었다.
key값(idx)이 각 자료에 부여되고
또한, span 태그를 이용해서 순서(key값을 이용함), 각 인덱스에 있는 값을 보여주는 표를 만든다.</p>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/9ca53142-2d94-4c9d-8fbc-1b43db87c5d4/image.png" alt="">
결과물! map함수의 장점을 복습하는 겸 작성해보자면, map함수로 이렇게 작성해두면 나중에 새 언어를 배워 카드를 추가하게 되어도 skills 배열에 한 단어만 추가하면 자동으로 해결된다.</p>
<h2 id="4-로컬-스토리지를-이용한-메모장-컴포넌트">4. 로컬 스토리지를 이용한 메모장 컴포넌트</h2>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/02211af4-3b09-46e0-8915-134df224be81/image.png" alt="">
우선 어떻게 만들게 되었냐면...간단히 말해서
제미나이가 멋대로 만들어준건데 나름 잘만들어서 조금 수정 후 채택하게 되었다!</p>
<p>이번 컴포넌트는 우선 작동하는 사진들 후 기능을 소개하는 방식으로 하려한다.
<img src="https://velog.velcdn.com/images/sloth_slys/post/554f2b99-3b0d-4f28-9e0c-dbf759496085/image.png" alt="">
이렇게 제목 작성 후 코드 박스에 아무 내용 그대로 적어두면...</p>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/f455416e-9288-4f96-989f-bb38ddd38cdd/image.png" alt="">
이렇게 저장되고, 로컬스토리지에 기록이 남아서 새로고침 + 심지어 노트북을 껏다켜도 브라우저 캐시를 날리지 않는 이상 기록이 계속 존재하게 된다</p>
<pre><code class="language-javascript">import React, { useState, useEffect } from &#39;react&#39;;

export default function TilSection() {
  const [tils, setTils] = useState(() =&gt; {
    const saved = localStorage.getItem(&#39;study_tils&#39;);
    return saved ? JSON.parse(saved) : [
      { 
        id: 1, 
        title: &#39;React useState로 상태 관리하기&#39;, 
        code: &#39;const [count, setCount] = useState(0);&#39;, 
        date: &#39;2026-09-14&#39;, 
        category: &#39;React&#39; 
      },
      { 
        id: 2, 
        title: &#39;(더미)Tailwind CSS v4 flex 레이아웃&#39;, 
        code: &#39;className=&quot;flex items-center justify-between gap-4&quot;&#39;, 
        date: &#39;2026-09-13&#39;, 
        category: &#39;CSS&#39; 
      }
    ];
  });

  const [newTitle, setNewTitle] = useState(&#39;&#39;);
  const [newCode, setNewCode] = useState(&#39;&#39;);
  const [newCategory, setNewCategory] = useState(&#39;React&#39;);
  const [openCodeId, setOpenCodeId] = useState(null);

  useEffect(() =&gt; {
    localStorage.setItem(&#39;study_tils&#39;, JSON.stringify(tils));
  }, [tils]);

  const handleAddTil = (e) =&gt; {
    e.preventDefault();
    if (!newTitle.trim()) return;
    const newItem = {
      id: Date.now(),
      title: newTitle,
      code: newCode || &#39;// 작성된 코드가 없습니다.&#39;,
      date: new Date().toISOString().split(&#39;T&#39;)[0],
      category: newCategory,
    };
    setTils([newItem, ...tils]);
    setNewTitle(&#39;&#39;);
    setNewCode(&#39;&#39;);
  };

  // 특정 ID의 TIL을 삭제하는 함수
  const handleDeleteTil = (id, e) =&gt; {
    e.stopPropagation(); // 카드 펼치기/접기 이벤트와 충돌하는 것 방지
    setTils(tils.filter(item =&gt; item.id !== id));
  };

  const toggleCode = (id) =&gt; {
    setOpenCodeId(openCodeId === id ? null : id);
  };

  return (
    &lt;section id=&quot;tils&quot; className=&quot;space-y-6&quot;&gt;
      &lt;div className=&quot;flex items-center justify-between&quot;&gt;
        &lt;h2 className=&quot;text-2xl font-bold text-gray-900 tracking-tight&quot;&gt;Today I Learned (TIL)&lt;/h2&gt;
        &lt;span className=&quot;text-xs text-gray-500 bg-gray-200 px-2.5 py-1 rounded-md&quot;&gt;Code Snippet Archive&lt;/span&gt;
      &lt;/div&gt;

      {/* TIL 입력 폼 */}
      &lt;form onSubmit={handleAddTil} className=&quot;bg-white p-6 rounded-xl border border-gray-200 shadow-sm space-y-4&quot;&gt;
        &lt;div className=&quot;flex flex-col sm:flex-row gap-3&quot;&gt;
          &lt;input 
            type=&quot;text&quot; 
            placeholder=&quot;오늘 배운 내용 요약 (예: React Hook 활용법)&quot; 
            value={newTitle}
            onChange={(e) =&gt; setNewTitle(e.target.value)}
            className=&quot;flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm&quot;
          /&gt;
          &lt;select 
            value={newCategory} 
            onChange={(e) =&gt; setNewCategory(e.target.value)}
            className=&quot;px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm bg-white&quot;
          &gt;
            &lt;option value=&quot;React&quot;&gt;React&lt;/option&gt;
            &lt;option value=&quot;C/C++&quot;&gt;C/C++&lt;/option&gt;
            &lt;option value=&quot;Python&quot;&gt;Python&lt;/option&gt;
            &lt;option value=&quot;CSS&quot;&gt;CSS&lt;/option&gt;
          &lt;/select&gt;
        &lt;/div&gt;

        &lt;textarea 
          placeholder=&quot;오늘 작성한 핵심 코드 스니펫을 입력하세요...&quot; 
          value={newCode}
          onChange={(e) =&gt; setNewCode(e.target.value)}
          rows=&quot;3&quot;
          className=&quot;w-full px-4 py-2 font-mono text-xs bg-gray-900 text-gray-100 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none&quot;
        /&gt;

        &lt;div className=&quot;flex justify-end&quot;&gt;
          &lt;button 
            type=&quot;submit&quot;
            className=&quot;px-6 py-2 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition text-sm shadow-sm&quot;
          &gt;
            코드 기록 추가
          &lt;/button&gt;
        &lt;/div&gt;
      &lt;/form&gt;

      {/* TIL 목록 카드 리스트 */}
      &lt;div className=&quot;grid gap-4&quot;&gt;
        {tils.map((item) =&gt; {
          const isOpen = openCodeId === item.id;
          return (
            &lt;div key={item.id} className=&quot;bg-white p-5 rounded-xl border border-gray-200 shadow-sm transition space-y-3&quot;&gt;
              &lt;div className=&quot;flex items-center justify-between&quot;&gt;
                &lt;div className=&quot;space-y-1&quot;&gt;
                  &lt;div className=&quot;flex items-center gap-2&quot;&gt;
                    &lt;span className=&quot;px-2 py-0.5 bg-gray-100 text-gray-700 text-xs font-semibold rounded&quot;&gt;
                      {item.category}
                    &lt;/span&gt;
                    &lt;span className=&quot;text-xs text-gray-400&quot;&gt;{item.date}&lt;/span&gt;
                  &lt;/div&gt;
                  &lt;h3 className=&quot;font-medium text-gray-900&quot;&gt;{item.title}&lt;/h3&gt;
                &lt;/div&gt;

                {/* 우측 버튼 그룹 (코드 보기 + 삭제 버튼) */}
                &lt;div className=&quot;flex items-center gap-2&quot;&gt;
                  &lt;button 
                    onClick={() =&gt; toggleCode(item.id)}
                    className=&quot;px-3 py-1.5 text-xs font-medium text-blue-600 bg-blue-50 hover:bg-blue-100 rounded-lg transition&quot;
                  &gt;
                    {isOpen ? &#39;코드 숨기기 ▲&#39; : &#39;코드 보기 ▼&#39;}
                  &lt;/button&gt;
                  &lt;button 
                    onClick={(e) =&gt; handleDeleteTil(item.id, e)}
                    className=&quot;px-3 py-1.5 text-xs font-medium text-red-600 bg-red-50 hover:bg-red-100 rounded-lg transition&quot;
                  &gt;
                    삭제
                  &lt;/button&gt;
                &lt;/div&gt;
              &lt;/div&gt;

              {isOpen &amp;&amp; (
                &lt;div className=&quot;mt-3 p-4 bg-gray-900 text-gray-100 rounded-lg font-mono text-xs overflow-x-auto shadow-inner&quot;&gt;
                  &lt;pre&gt;{item.code}&lt;/pre&gt;
                &lt;/div&gt;
              )}
            &lt;/div&gt;
          );
        })}
      &lt;/div&gt;
    &lt;/section&gt;
  );
}</code></pre>
<p>여러가지 기능이 있지만 이번에 아예 새롭게 알게 된 로컬스토리지라는 기능을 중점으로 분석해보고자 한다.</p>
<pre><code>const [tils, setTils] = useState(() =&gt; {
  const saved = localStorage.getItem(&#39;study_tils&#39;);
  return saved ? JSON.parse(saved) : [ /* 값이 없을 시 기본 더미 데이터 모록*/ ];
});</code></pre><p>로컬스토리지 특징: 문자열 형태의 데이터만 저장 가능, 브라우저 캐시 삭제를 하지 않거나 삭제시간을 정해두지 않는 이상 쿠키와는 다르게 무기한 저장. 도메인당 5mb라는 적은 저장공간만 사용가능</p>
<p>localStorage.getItem(&#39;분류태그명&#39;): 로컬스토리지에서 [분류태그명]이라는 것으로 분류된 데이터들을 가져오게 한다.
JSON.parse(saved): 문자열로 저장된 saved라는 데이터를 객체 배열 형태로 복원(역직렬화라고 하기도 함)</p>
<pre><code>useEffect(() =&gt; {
  localStorage.setItem(&#39;study_tils&#39;, JSON.stringify(tils));
}, [tils]);</code></pre><p>localStorage.setItem(): 로컬 스토리지에 저장
[tils]: 참고(지금은 임의로 작성한 변수가 들어간 상태), tils의 상태가 바뀔 때 마다. 즉, 새로운 기록이나 삭제를 할때 마다 해당 코드가 실행됨
JSON.stringify(tils): parse와 반대로 저장하기 위해 객체 배열 형태의 데이터를 문자열 식으로 변환 해줌</p>
<h2 id="5-헤더푸터">5. 헤더,푸터</h2>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/c455bf91-9233-45b6-ae08-c6d1ab3fd55c/image.png" alt="">
그냥 기분삼아 만들어본 푸터. 
<strong>(<em>논 카피라이트</em>)</strong></p>
<p>간단해서 먼저 설명하자면.</p>
<pre><code>      &lt;footer className=&quot;border-t border-gray-200 bg-white mt-20 py-8 text-center text-sm text-gray-500&quot;&gt;
        &lt;p&gt;© 무단전재 및 재배포 환영&lt;/p&gt;
      &lt;/footer&gt;</code></pre><p>디자인, 글 이게 전부. 그냥 코드에서 페이지 맨 아래에 깔리도록 조정만 잘 해주면 된다.</p>
<p>그리고 상단의 헤더 컴포넌트. 주요기능을 먼저 말하자면 2갱;다. 첫번째는 </p>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/a9ecefee-0aa9-48a7-a8f6-f9b9dee0116e/image.png" alt="">
사진에 보이는 대로 오른쪽 끝에는 페이지 이름, 오른쪽엔 시계와 메뉴창 버튼</p>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/41419347-d698-4a6a-a9ca-4d99d1e75667/image.png" alt="">
그리고 2번째가 위에 보이는 대로 메뉴창 내부(여기가 만드는데 복잡 했음)</p>
<pre><code class="language-javascript">import React, { useState, useEffect } from &#39;react&#39;;
import { Link } from &#39;react-router-dom&#39;; // Link 컴포넌트 추가 임포트

export default function Header() {
  const [isOpen, setIsOpen] = useState(false); // 모바일/사이드 메뉴 열림/닫힘 상태
  const [currentTime, setCurrentTime] = useState(&#39;&#39;); // 실시간 시계 상태


  // 실시간으로 시:분 계산해서 업데이트하는 로직
  useEffect(() =&gt; {
    const updateTime = () =&gt; {
      const now = new Date(); // 현재 컴퓨터 시간 가져오기
      // 시와 분만 가져와서 2자리 형식으로 맞춤 (예: 15:04)
      const hours = String(now.getHours()).padStart(2, &#39;0&#39;);
      const minutes = String(now.getMinutes()).padStart(2, &#39;0&#39;);
      setCurrentTime(`${hours}:${minutes}`);
    };

    updateTime(); // 컴포넌트 마운트 시 처음에 바로 실행
    const timer = setInterval(updateTime, 1000 * 10); // 10초마다 시간 갱신

    return () =&gt; clearInterval(timer); // 메모리 누수 방지 (언마운트 시 타이머 해제)
  }, []);

  // 메뉴 아이템 목록 (내부 스크롤 앵커와 다른 페이지 이동 라우트를 구분)
  const menuItems = [
    { name: &#39;프로필&#39;, href: &#39;#profile&#39;, move: false },
    { name: &#39;기술 스택&#39;, href: &#39;#skills&#39;, move: false },
    { name: &#39;TIL 아카이브&#39;, href: &#39;#tils&#39;, move: false },
    { name: &#39;플레이 리스트(테스트페이지,시험 상태)&#39;, to: &#39;/test&#39;, move: true }, // 다른 페이지로 이동하는 라우트
  ];

  return (
    &lt;&gt;
      {/* 상단 고정 헤더 */}
      &lt;header className=&quot;sticky top-0 z-50 bg-white border-b-[1.9px] border-black&quot;&gt;
        &lt;div className=&quot;max-w-5xl mx-auto px-6 h-16 flex items-center justify-between&quot;&gt;

          {/* 로고 및 브랜드 영역 */}
          &lt;div className=&quot;font-bold text-lg text-gray-900 tracking-tight flex items-center gap-2&quot;&gt;
            &lt;span className=&quot;w-3 h-3 bg-blue-600 rounded-full&quot;&gt;&lt;/span&gt;
            Temporary Archive
          &lt;/div&gt;

          {/* 우측 영역: 실시간 시계 표시 + 햄버거 메뉴 버튼 */}
          &lt;div className=&quot;flex items-center gap-4&quot;&gt;
            {/* 간략한 시간 표시 (분까지만 모노 폰트로 깔끔하게) */}
            &lt;span className=&quot;text-xs font-mono text-gray-500 bg-gray-100 px-2.5 py-1 rounded-md&quot;&gt;
              {currentTime}
            &lt;/span&gt;

            {/* 햄버거 버튼 (클릭 시 사이드 메뉴 열림) */}
            &lt;button 
              onClick={() =&gt; setIsOpen(true)}
              className=&quot;p-2 text-gray-700 hover:text-blue-600 focus:outline-none transition text-xl font-bold&quot;
              aria-label=&quot;메뉴 열기&quot;
            &gt;
              ≡
            &lt;/button&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/header&gt;</code></pre>
<p>우선 첫 번째 기능을 만드는데 쓴 코드. 시계부분은 복잡해서 기초를 ai에게 맡기고 세부조정만 하는 식으로 만들게 되었다.</p>
<p>new Date(): 현재 컴퓨터의 시간을 가져옴
String(now.getHours()).padStart(2, &#39;0&#39;): 시간 값을 가져와서 글자길이는 항상 2자리, 빈자리는 0으로 채우게 하는 기능을 구현하는데 사용됨
setInterval(실행시킬 함수, 주기): 시계 변경용으로 사용함. 일정 간격마다 함수를 작동시키게 하는 코드
return () =&gt; clearInterval(timer): 페이지 화면에서 이 코드가 있는 컴포넌트가 사라진다면 timer 작동 중지. 이를 통해 메모리 누수 현상을 방지할 수 있음</p>
<h4 id="51-메뉴창-시스템-수정하기">5.1. 메뉴창 시스템 수정하기</h4>
<pre><code class="language-javascript">   {/* 사이드 메뉴가 열렸을 때 배경을 어둡게 처리하는 오버레이 */}
      {isOpen &amp;&amp; (
        &lt;div 
          onClick={() =&gt; setIsOpen(false)}
          className=&quot;fixed inset-0 bg-black/40 z-50 transition-opacity&quot;
        /&gt;
      )}

      {/* 우측에서 스르륵 튀어나오는 슬라이드 메뉴 창 */}
      &lt;div className={`fixed top-0 right-0 h-full w-72 bg-white shadow-2xl z-50 transform transition-transform duration-300 ease-in-out ${isOpen ? &#39;translate-x-0&#39; : &#39;translate-x-full&#39;}`}&gt;

        {/* 메뉴창 상단 타이틀 및 닫기 버튼 */}
        &lt;div className=&quot;p-6 flex items-center justify-between border-b border-gray-100&quot;&gt;
          &lt;span className=&quot;font-bold text-gray-900&quot;&gt;메뉴창&lt;/span&gt;
          &lt;button 
            onClick={() =&gt; setIsOpen(false)}
            className=&quot;text-gray-400 hover:text-gray-700 text-lg font-bold p-1&quot;
            aria-label=&quot;메뉴 닫기&quot;
          &gt;
            ✕
          &lt;/button&gt;
        &lt;/div&gt;

        {/* 네비게이션 링크 목록 (isAnchor 값에 따라 내부 스크롤 vs 페이지 이동 분기) */}
        &lt;nav className=&quot;p-6 flex flex-col gap-4&quot;&gt;
          {menuItems.map((item, index) =&gt; (
            item.move ? (
              // 1. 다른 페이지(라우트)로 안전하게 이동하는 React Router Link 컴포넌트
              &lt;Link 
                key={index}
                to={item.to}
                onClick={() =&gt; setIsOpen(false)}
                className=&quot;text-gray-700 hover:text-blue-600 hover:bg-blue-50 px-4 py-3 rounded-xl font-medium transition text-base&quot;
              &gt;
                {item.name}
              &lt;/Link&gt;
            ) : (
              // 2. 같은 페이지 내 특정 섹션으로 스크롤 이동하는 앵커 태그
              &lt;a 
                key={index}
                href={item.href}
                onClick={() =&gt; setIsOpen(false)}
                className=&quot;text-gray-700 hover:text-blue-600 hover:bg-blue-50 px-4 py-3 rounded-xl font-medium transition text-base&quot;
              &gt;
                {item.name}
              &lt;/a&gt;
            )
          ))}
        &lt;/nav&gt;
      &lt;/div&gt;</code></pre>
<p>마지막으로, 좀 마지막에 수정 할 떄 애를 먹은 메뉴창 기능을 분석하겠다. 아 그리고 이건 8,9주차 내용이 섞여있는데 우선 기능 자첸 8주차에 만들어져서 8주차 항목에 배치하게 되었다.</p>
<p>우선 메뉴창을 눌렀을 시
transition-transform duration-300 ease-in-out 을 통해 0.3초 동안 메뉴창이 자연스런게 나오게 된다</p>
<p>또한 ${isOpen ? &#39;translate-x-0&#39; : &#39;translate-x-full&#39;}를 통해 메뉴창의 이동을 조정한다.
(평소엔 false라 화면 밖으로 숨겨져 있음)</p>
<p>그리고 </p>
<pre><code>{isOpen &amp;&amp; (
  &lt;div 
    onClick={() =&gt; setIsOpen(false)}
    className=&quot;fixed inset-0 bg-black/40 z-50 transition-opacity&quot;
  /&gt;
)}</code></pre><p>를 통해 isOpen 값이 참이면 화면 전체를 덮는 반투명한 검은색 도형을 생성해
<img src="https://velog.velcdn.com/images/sloth_slys/post/8c6ab86a-3d74-46d0-8b5a-051abd98bb56/image.png" alt="">
이런 식으로 기존 화면이 비활성화 된 느낌을 준다</p>
<p>그리고 여기가 골치 아팠는데</p>
<pre><code class="language-javasript">        {/* 네비게이션 링크 목록 (isAnchor 값에 따라 내부 스크롤 vs 페이지 이동 분기) */}
        &lt;nav className=&quot;p-6 flex flex-col gap-4&quot;&gt;
          {menuItems.map((item, index) =&gt; (
            item.move ? (
              // 1. 다른 페이지(라우트)로 안전하게 이동하는 React Router Link 컴포넌트
              &lt;Link 
                key={index}
                to={item.to}
                onClick={() =&gt; setIsOpen(false)}
                className=&quot;text-gray-700 hover:text-blue-600 hover:bg-blue-50 px-4 py-3 rounded-xl font-medium transition text-base&quot;
              &gt;
                {item.name}
              &lt;/Link&gt;
            ) : (
              // 2. 같은 페이지 내 특정 섹션으로 스크롤 이동하는 앵커 태그
              &lt;a 
                key={index}
                href={item.href}
                onClick={() =&gt; setIsOpen(false)}
                className=&quot;text-gray-700 hover:text-blue-600 hover:bg-blue-50 px-4 py-3 rounded-xl font-medium transition text-base&quot;
              &gt;
                {item.name}
              &lt;/a&gt;
            )
          ))}</code></pre>
<p>우선 간단하게 정리하자면 삼항 연산자를 통해 move값이 true라면 다른 페이지 경로로 이동하는 버전, false 라면 같은 페이지 내에서 아까전에 언급한 태그라는 방식으로 이동하는 방식을 쓰게 하였다.</p>
<pre><code>  const menuItems = [
    { name: &#39;프로필&#39;, href: &#39;#profile&#39;, move: false },
    { name: &#39;기술 스택&#39;, href: &#39;#skills&#39;, move: false },
    { name: &#39;TIL 아카이브&#39;, href: &#39;#tils&#39;, move: false },
    { name: &#39;플레이 리스트(테스트페이지,시험 상태)&#39;, to: &#39;/test&#39;, move: true }, // 다른 페이지로 이동하는 라우트
  ];
</code></pre><p>프로필,기술스택,아카이브 같은경우는 후자의 방식으로, 플레이 리스트는 다른 페이지(정확히 말하자면 move 값이 true기 때문에)기 때문에 전자의 방식대로 작동하게 된다</p>
<hr>
<p>우선 전자의 방식의 코드를 분석해보자면
<code>&lt;link&gt;</code>태그 내에서
map함수로 키 값을 생성하고 to라는 속성으로 페이지를 이동하게 된다</p>
<ul>
<li>여기서 <code>&lt;link to = ...&gt;</code> 태그와 <code>&lt;a herf = ...&gt;</code>의 차이점을 집고 넘어가자면 
a태그 와 달리 link 태그는 페이지를 이동할 때 새로고침을 안하고 주소창만 바꾸는 방식으로 이동해 a태그 보다 매끄럽게 페이지를 이동할 수 있다.</li>
</ul>
<hr>
<p>이어서 후자의 방식은 
href={item.href}라는 속성에 아까 각 컴포넌트에 부여한 id =&#39;#profile&#39;, id = &#39;#skills&#39;, id =&#39;#tils&#39;
라는 아이디를 인식하여서 페이지가 해당 하는 아이디를 가진 컴포넌트가 있는곳으로 자동으로 스크롤해준다.</p>
<hr>
<p>그리고 별거는 아니지만 골치 아팠다고 한 이유는 8주차에는 전자의 방식이 없었기 때문에 9주차 때 삼항연산자를 넣어 2가지의 분기를 만드는 과정에서 수정에 좀 시간이 소요되었기 때문이다.</p>
<h2 id="8주차-결과물-완성">8주차 결과물 완성</h2>
<p>사진은 따로 없지만, 위에서 만든 컴포넌트를 기본 경로로 설정된 MainPage.jsx에서 조합하면 메인 페이지가 완료된다.</p>
<h2 id="19주차시간대에-따른-창문-배경-변화">1.(9주차)시간대에 따른 창문 배경 변화</h2>
<pre><code class="language-jsx">import React, { useState } from &#39;react&#39;;
import Header from &#39;../components/Header&#39;;
import ProfileCard from &#39;../components/ProfileCard&#39;;
import SkillSection from &#39;../components/SkillSection&#39;;
import TilSection from &#39;../components/TilSection&#39;;

export default function MainPage() {
  // 현재 시간에 따른 시간대별 창밖 풍경 상태 (테스트용 조작 가능)
  const [hour, setHour] = useState(new Date().getHours());

  const getTimeTheme = (h) =&gt; {
    if (h &gt;= 5 &amp;&amp; h &lt; 8) {
      return {
        name: &#39;DAWN&#39;,
        windowBg: &#39;from-slate-900 via-indigo-950 to-blue-900&#39;,
      };
    } else if (h &gt;= 0 &amp;&amp; h &lt; 12) {
      return {
        name: &#39;DAY&#39;,
        windowBg: &#39;from-sky-400 via-amber-100 to-amber-200&#39;,
      };
    } else if (h &gt;= 15 &amp;&amp; h &lt; 20) {
      return {
        name: &#39;DUSK&#39;,
        windowBg: &#39;from-rose-600 via-orange-500 to-amber-900&#39;,
      };
    } else {
      return {
        name: &#39;NIGHT&#39;,
        windowBg: &#39;from-stone-950 via-slate-900 to-black&#39;,
      };
    }
  };

  const currentTheme = getTimeTheme(hour);

  return (
    &lt;div className=&quot;min-h-screen bg-[#F2F4F7] text-gray-800 font-sans antialiased&quot;&gt;

      &lt;Header /&gt;

      &lt;main className=&quot;max-w-5xl mx-auto px-6 py-12 space-y-16&quot;&gt;

        {/* 창문 영역과 시간 조절 버튼을 감싸는 컨테이너 */}
        &lt;div className=&quot;space-y-3&quot;&gt;

          {/* 대형 창문 위젯 */}
          &lt;div className=&quot;w-full h-56 md:h-72 rounded-2xl border-4 border-gray-200 overflow-hidden relative shadow-sm group&quot;&gt;
            {/* 시간대별 그라데이션 하늘 (부드러운 전환) */}
            &lt;div className={`absolute inset-0 bg-gradient-to-b ${currentTheme.windowBg} transition-all duration-1000 ease-in-out`} /&gt;

            {/* 유리 질감 빛 번짐 효과 */}
            &lt;div className=&quot;absolute inset-0 bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-white/20 via-transparent to-black/30 pointer-events-none&quot; /&gt;

            {/* 십자 창틀 프레임 */}
            &lt;div className=&quot;absolute inset-0 flex items-center justify-center pointer-events-none&quot;&gt;
              &lt;div className=&quot;w-full h-[4px] bg-gray-900/80 shadow&quot; /&gt;
            &lt;/div&gt;
            &lt;div className=&quot;absolute inset-0 flex items-center justify-center pointer-events-none&quot;&gt;
              &lt;div className=&quot;h-full w-[4px] bg-gray-900/80 shadow&quot; /&gt;
            &lt;/div&gt;

            {/* 하단 모서리 인포 뱃지 */}
            &lt;div className=&quot;absolute bottom-3 right-3 text-[10px] font-mono text-white/80 bg-black/50 backdrop-blur px-2 py-1 rounded&quot;&gt;
              시간: {currentTheme.name}
            &lt;/div&gt;
          &lt;/div&gt;

          {/* 창문 바로 아래 왼쪽 구석에 몰아넣은 시간 조절 미니 바 */}
          &lt;div className=&quot;flex items-center gap-2 px-1&quot;&gt;
            &lt;span className=&quot;text-xs font-mono text-gray-400&quot;&gt;TIME:&lt;/span&gt;
            &lt;div className=&quot;flex items-center gap-1.5 bg-gray-100 p-1 rounded-lg border border-gray-200 text-xs&quot;&gt;
              {[6, 12, 18, 23].map((testHour) =&gt; (
                &lt;button
                  key={testHour}
                  onClick={() =&gt; setHour(testHour)}
                  className={`px-2 py-0.5 rounded font-mono transition-colors ${hour === testHour ? &#39;bg-gray-900 text-white shadow-sm&#39; : &#39;text-gray-500 hover:text-gray-900 hover:bg-gray-200&#39;}`}
                &gt;
                  {testHour}시
                &lt;/button&gt;
              ))}
            &lt;/div&gt;
          &lt;/div&gt;

        &lt;/div&gt;

        &lt;ProfileCard /&gt;
        &lt;SkillSection /&gt;
        &lt;TilSection /&gt;
      &lt;/main&gt;</code></pre>
<p>이 기능 같은 경우엔 컴포넌트 대신 메인 페이지에 같이 넣어주었다. 아까전 시계를 만들던 로직을 가져와 시간대 별로 디자인을 바꾸는 시기이다. 어....여기선 시계로직만 있으면 거의 절반 해결한거고, 솔직히 디자인이 제일 어려웠어서 설명하는말을 달기가 어렵다.</p>
<p>&lt;새벽 시간대 사진&gt;
<img src="https://velog.velcdn.com/images/sloth_slys/post/75a0ae4c-42bc-477c-92e7-c66f0b0bd8e3/image.png" alt=""></p>
<h2 id="2-플레이-리스트-페이지">2. 플레이 리스트 페이지</h2>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/22cb78b2-41ff-4253-9d35-5643a1d3665a/image.png" alt=""></p>
<p>일단 이 페이지는 내가 생각하던게 될지 ai를 통해 임시로 대충 만든 페이지이다. <del>그래서 아직 코드 분석을 못함</del></p>
<p>여튼 그래도 대략적인 기능은 인지하고 만들었으니 설명하자면
노란색의 재생 버튼을 누르면 음반이 돌아가는 애니메이션, 축음기의 저...침(?) 부분이 음반위로 올라가 진짜 축음기 느낌이 나게 하였다.</p>
<p>또한 축음기이니 유튜브 동영상 재생api를 활용해서 음악 동영상의 속성을 넣으면 음악이 재생되도록 하였다.</p>
<p>그리고 우측 하단의 입력창 같은 부분은 코드를 써놓는 곳으로 특정 코드 입력시 숨겨진 url의 음악 동영상이 재생되도록 하게 할 예정이다.(아직 제대로 구현은 안됨)</p>
<p>여튼 아마 10주차 떄 완성이 제대로 되지 않을까 싶다.
우선 그래도 만들고 싶은 기능은 </p>
<p>축음기 데코레이션, 입력창을 통한 검색또는 히든곡, </p>
<p>화면 우측에 음반처럼 돌아가면서 음악 선택하게 하는 방식. </p>
<p>좌측에는 음악이 많아질 경우를 대비해 음악을 토픽별로 분류해놓는 음반집 형태의 세부 필터 기능?(클래식,오페라 꼭 장르별로는 아님)</p>
<p><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/></p>
<h3 id="개인용-개발-관련-단어-정리">개인용 개발 관련 단어 정리</h3>
<ul>
<li><p>IDE: 통합 개발 환경. 디버깅, 개발, 빌드를 한 프로그램만으로 할 수 있게 해주는 소프트웨어 애플리케이션</p>
</li>
<li><p>백엔드: 프론트엔드와 반대로 서버관련 로직 처리, api작성, DB관리 등을 함</p>
</li>
<li><p>API: 서로 다른 프로그램이 서로 데이터를 통신하게 할수 있게하는 일련의 규칙또는 약속(이런 전송,전달 형식이 정리된게 api명세서)</p>
</li>
<li><p>Html: 웹페이지 개발 언어</p>
</li>
<li><p>CSS: html 웹페이지에 디자인을 적용하는 언어</p>
</li>
<li><p>인터프리터: 소스코드를 한줄 씩 실시간으로 변환후 곧바로 실행하는 방식(파이썬, 자바 스크립트 등이 속함)</p>
</li>
<li><p>const: 절대로 값이 바뀌지 않는 변수</p>
</li>
<li><p>let: 내용물의 값이 언제든지 바뀔수 있는 변수</p>
</li>
<li><p>객체: 속성, 메서드를 하나의 공간에 담아둔 단위. 코드의 재사용성, 구조화 면에서 이점이 존재</p>
</li>
<li><p>props: 상위 컴포넌트가 하위 컴포넌트로 데이터를 전달할 때 사용하는 객체형 변수, 자식 컴포넌트내부에선 직접 수정불가함</p>
</li>
<li><p>컴포넌트: 화면(UI)을 독립적이고 재사용 가능한 작은 조각으로 쪼개어 관리하는 단위</p>
</li>
<li><p>빌드: 배포 전 코드를 실제 서비스 가능하게끔 경량화를 위해 압축, 최적화 하는 작업을 의미</p>
</li>
<li><p>모듈: 프로그램에서 독립적인 기능을 하는 함수,클래스,파일 등을 의미</p>
</li>
</ul>
<ul>
<li><p>번들러: 프로젝트 파일에서 여러개로 분산되어 있는 파일(모듈)을 하나로 묶어서 배포할 수 있게 해주는 프로그램 (여기에 VITE가 포함됨)</p>
</li>
<li><p>프레임 워크: 라이브러리와 비슷하지만 다름, 프레임 워크는 라이브러리와 달리 호출이 불필요하며, 함수로 작동되는 것이 아닌 그냥 프레임워크에 지정된 방식으로 코딩을 하면 빌드나 테스트 시 프레임워크가 미리 지정된 방식으로 코드를 해석후 변환하여 프로그램이 작동되게 해줌(Styled css가 라이브러리와 비슷하고, TailWind css가 프레임 워크 쪽에 해당 됨)</p>
</li>
</ul>
<h3 id="이번에-만들면서-알게된-코드-정리">이번에 만들면서 알게된 코드 정리</h3>
<p>mx: margin-x, px:padding-left/right, py:padding-top/bottom, border-t: border-top
같은 반복적인건 일부 생략</p>
<ul>
<li>grid-cols-2: 한 줄에 2개의 열을 배치</li>
<li>sm:grid-cols-4: 반응형 변환, 화면이 일정 크기 이상으로 넓어졌을시 한 줄에 4개의 열을 배치</li>
</ul>
<ul>
<li>min-h-screen: 최소 높이(min-height)를 화면 전체 높이(100vh)로 설정.</li>
<li>(bg 또는 text)-{색상}-{명도/투명도}: 배경색이나 텍스트 색을 변경</li>
<li>opacity-(숫자): 이것도 투명도 조절</li>
<li>font-{폰트 명}: 폰트 적용</li>
<li>antialiased: 글자 안티앨리어싱(계단화 현상 방지)</li>
<li>flex flex-col: flex-direction: column;을 의미</li>
<li>tracking-tight: 글자간의 간격을 축소함</li>
<li>leading-relaxed: 글자 줄의 간격을 늘림</li>
<li>max-w-사이즈: 박스의 최대 넓이 제한 xs,sm,md,lg,xl,2xl~7xl 까지 순서대로 존재.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[멋사 프론트엔드 7주차(1학기 마지막 스터디) 회고록]]></title>
            <link>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-7%EC%A3%BC%EC%B0%A81%ED%95%99%EA%B8%B0-%EB%A7%88%EC%A7%80%EB%A7%89-%EC%8A%A4%ED%84%B0%EB%94%94-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-7%EC%A3%BC%EC%B0%A81%ED%95%99%EA%B8%B0-%EB%A7%88%EC%A7%80%EB%A7%89-%EC%8A%A4%ED%84%B0%EB%94%94-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Tue, 26 May 2026 04:36:47 GMT</pubDate>
            <description><![CDATA[<h1 id="1-수정사항">1. 수정사항</h1>
<p>지난 2주동안 협업 프로젝트 하느라 딱히 변경점은 없지만, 일단 좀 개판인 상태를 수습해보기 위해 노력하였다.
<img src="https://velog.velcdn.com/images/sloth_slys/post/194b109f-2514-4d05-b31c-d87c250812b0/image.png" alt="">
우선 제일 처음 페이지가 좀 많이 휑한데 이건 좀 나중으로 미루고,</p>
<p>축제 프로젝트에 들어갈 스크립트를 여기서 시험장(?) 처럼 사용해서 그것부터 원상 복구하기로 하였다.
<img src="https://velog.velcdn.com/images/sloth_slys/post/9e4d13f8-21e5-48f3-99c8-81ba638df1bc/image.png" alt="">
여긴 원래 자기소개 페이지인데 페이지 입장 애니메이션 테스트 해보느라고 아에 가려졌다.
<img src="https://velog.velcdn.com/images/sloth_slys/post/26c2dbd4-7dec-4235-ac96-adb6aa8f1b11/image.png" alt="">
여기서 Scroll 만 지워주면..
<img src="https://velog.velcdn.com/images/sloth_slys/post/4e3ea28d-ee33-4267-8618-c695015a29e3/image.png" alt="">
원래 버전으로 해결되었다.
<del>(일단 메인페이지 수정중... 스터디 전까지 될지 미지수)</del></p>
<h1 id="2-배포">2. 배포</h1>
<p>어... 일단 수정하기 전 먼저 배포를 해버려서 순서가 어긋난 감은 있지만 vercel을 통해 배포해서 딱히 문제는 없다고 판단한다.</p>
<p>우선 개인용 프라이빗 깃허브 저장소 개설 후, 협업 프로젝트 동안 수십번은 한 브랜치 개설, 브랜치 변경 후 git add .하고 커밋을 하여 만든 코드를 깃허브에 올렸다.</p>
<p>이후 vercel 웹페이지에서 깃허브 저장소를 선택하고 vercel을 해당 저장소에 설치하겠냐 묻는것에 예 버튼을 누른뒤 </p>
<p>웹페이지 생성을 했던 것으로 기억한다. 
거기서 Build Command에 CI=false npm run build를 미리 적어주었다.</p>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/e2c4146d-f297-47e1-847b-5198149c7d4a/image.png" alt="">
가동시간은 미리 배포를 해버려서 벌써 13시간이지만 결과화면은 이렇게 되었다.
<del>있는게 없어서 오류가 안 떴다</del></p>
<blockquote>
<p>배포 링크: <a href="https://mutsa-web-test.vercel.app/">https://mutsa-web-test.vercel.app/</a></p>
</blockquote>
<h1 id="3이번-1학기-스터디-동안-느낀점">3.이번 1학기 스터디 동안 느낀점</h1>
<p>음.. 아마 대학교 1학년 1학기임과 동시에 멋쟁이 사자라는 좋은 학술 동아리에 운 좋게 프론트엔드로 가입해서 이것저것 배우다가 막바지에 축제일정 2~3개(부스 운영, 아이디어 톤, 협업 프로젝트) 겹치고 일정 관리 실패해서 페를 좀 끼치게 되었는데 
그러한 점에서 참 지금도 자신에 대한 아쉬움과 도와주신 분들에게 감사함을 느끼고 있다.</p>
<p>또한, html, css(요건 좀 잘 못함ㅎㅎ), java
<del>(가끔 c언어로 짤수 있는거 같을 걸 자바로 못짜서 기분이 오묘함)</del></p>
<p>그리고 최종적으로 다 합치고 리엑트에서 쓰는 jsx를 정말 짧은 3개월도 안되는 시간동안 배우고 코딩 프로젝트도 ai 도움을 받긴 했어도 2개나 진행한 것이 아직도 실감이 안나고 뭐랄까 고등학교 때 생각하던? 1학년의 삶과 정반대...까진 좀 놀 때도 있긴해서 아니고 한 150도 차이가 나는 삶을 산 것 같다.</p>
<p>앞으로도 이제 해커톤이 2~3개 남은걸로 기억하는데 그 때까지 또 스터디가 없어도 열심히 공부해야지 사고 안날 것 같다는 위기감도 들고, 뭔가 운좋다는 생각도 들고 
느끼는 감정은 실뭉치처럼 엮여있는 것 같다. </p>
<p>이번에 협업하면서 다른 프론트 조원분들과 친분도 쌓고, 혼자 또는 같이 밤샘작업도 해보고 개발자로써 필요한 경험을 정말로 1학년이라는 이른 시기에 운 좋게 겪게 되었다고 생각한다.</p>
<p>한 학기가 이렇게 마무리 지어졌지만, 방학기간 <strong>첫번째 해커톤(<del>무박 2일</del>)</strong>도 다가오고 2학기도 남았지만 앞으로도 조원들분과 사이좋고 나머지 해커톤도 잘 끝낸 뒤 이번 년도 마지막 멋사 프론트엔드 수료를 잘 끝냈으면 좋겠다.</p>
<p>요약은 위와 같고 느낀 썰 풀거는 무진장 많긴하다. 아무래도 최근의 기억이 제일 강렬하기에 요약은 막바지 내용이 주요적이기 한데, 요 아래에선 면접 썰부터 풀어보려고 한다.</p>
<h1 id="썰풀이">썰풀이</h1>
<p><strong>경고 사항으로는 만약 멋사 동아리 회원이나 부장님이 보시기엔 다소 충격적인 내용이 있을 수도 있음을 경고합니다.</strong></p>
<ol>
<li>면접 당시 썰</li>
</ol>
<p>아마 정식입학 전 겨울 방학 시점으로 올라간다, 당시 정보대 카톡에 아마 이동로봇 특강 인가? 공지를 보고 인천대를 그렇게 거의 처음오게 되었는데 당시 버스시간 감각이 없기도 하고 지각하면 사고라는 느낌을 받아 너무 이르게. 한 1시간 정도 일찍? 
도착하였다.</p>
<p>근데 너무 일찍 와서 세팅 중이었고, 거기서 이제 4학년 선배 분들 8명쯤 정도를
먼저 뵈게 되었고(처음엔 대학원생 분들인줄 착각 함ㅎㅎ)
어쩌다보니 어느 교수님하고 잠시 대기실에 수업 시작전까지 대화 몇마디도 나누게 되었다.(근데 내가 듣는 수업이 안 겹치는지 아직도 다시 못 뵘;;)</p>
<p>여튼이제 강의 전인가 끝난 후에 지금 멋사 백엔드에 계신 분?이 멋사들어오라고 홍보를 해서 그렇게 처음 알게 되었다.</p>
<hr>
<p>이후 2월 마지막 주였나? 에타에 멋사 14기 모집공고 뜬 걸 보고 신청을 하려 했다.
당시 마음가짐은 
<strong><code>겜 개발자가 꿈이긴 한데 웹개발도 배우고, 협업 한다고? 안 할 이유가 없지</code></strong>
였다고 할 수 있다.</p>
<p>좀 더 무의식의 흐름을 자세히 말하면 
&quot;지금 취업 불경기라 개인 능력의 다양성과 대체 불가한 인력 뭐시기 뭐시기~&quot;
라는 너무 T같고 실속적인 이유가 따라 붙겠지만, 자의식 수준에서는 저런 마음가짐이었다고 할 수 있다.</p>
<p>일단 그럼 마음으로 구글폼을 작성 시작하는데, 백엔드랑 프론트엔드 고민 중 구글폼에 백엔드 지원자가 많다 고 안내가 써져있었다. 그래서 그냥 단순히, 어 그럼 떨어질 확률이 높네 프론트 해야징~ 이란 마음으로 프론트 지원서 작성을 시작했다.</p>
<hr>
<p><strong>이걸 좀 가볍게 장난식으로 보일 수 있는데 변명거리가 있다. 진짜로
이 때 당시, &quot;동아리? 고등학교 동아리랑 비슷하겠지&quot;라는 생각으로 지원하고 게다가 무지에서 비롯된 야수의 심장느낌으로 동아리 신청도 멋사 1개만 신청했다.
(동아리 1개 제한이 고등학교 때랑 같은 줄 알았음)
** 
**
게다가 학술 동아리 인것도 모르고 뭔지는 모르겠지만 전국적인 연합 동아리구나~ 라는 지식수준에서 신청을 해, 지금 와보면 자신이 봐도 뭔 깡이지 라고 생각이 들 정도
**
_</strong>여튼 지원서 작성 시작**_</p>
<p>300자 500자 였나 그런 질문 한 2개가 끝인 줄 알았는데 안끝났다. 솔직히 말하면 그 위에 볼드체로 된 당시의 생각을 가지고 있기에 좀 부적절하게 보일순 있지만;;
동아리가 뭐이리 깐깐해, 형식적인 질문인가? 꽉 안채워도 되려나? 같은 생각이 만연했다. 마지막에 포트폴리오 ppt였나? 까지 제출하라는 거 보고 속마음으로 욕은 나오긴 했지만 정성 껏 고등학교 3년간의 코딩 동아리 이력과 작품 같은걸 설명하는 내용으로 최종 제출을 하였다.</p>
<p>그리고 1차 합격 발표일 그때 발표 시간이 오후 6시였나 7시였나 그랬을 텐데 몇분이 지나도 안오길래 에타에 <code>멋사 프론트 앤드 경쟁 빡센가?</code>라는 내용이 담긴 글도 써보고 기다렸다. 아 탈락이구나 하는 심정이 든 순간 바로 1차 합격 문자가 늦게 발송되어 
김이랑 힘이 빠진 기억이 아직도 난다.</p>
<p>여튼 좀 시간이 흘러 2차 면접일, 멋사 동아리 방을 처음 오게 되었는데 앞에 사람이 하는걸 동아리 방앞에서 순서 대기타고 있다가 소리가 새서 엿들었는데 너무 웹개발에 
전문적인 경험얘기가 들려서 진짜 
<code>&quot;아 ㅈ됐다 포트폴리오에 작성한 경험이 끝인데 탈락하려나, 아닌간 초보환영이라 했으니 되려나? 아닌가? 그래도 경력직 선호겠지?&quot;</code></p>
<p>라는 만감이 교차하는 심정으로 대기실에 들어갔다. 근데 포트폴리오에 있던 내용과 달리 협업 자세랑 배우려는 의지만 물어보길래. 분위기도 거의 대학 면접 느낌 그대로였고 그래서
<code>&quot;아 탈락이네 음~&quot;</code> 
라는 생각만 면접이 끝나고 들었다. + 인천대 주변에 비둘기 대신 제비가 많네라는 생각(멘탈 털림)</p>
<p>딩시 면접 전에 찍은 제비 사진
<img src="https://velog.velcdn.com/images/sloth_slys/post/bd3ca56d-3de3-45f2-a4ef-1a0567f5bd71/image.png" alt=""></p>
<p>근데 또 1주일 뒤. 그래도 기대는 하고 있었는데 요약하자면 1차 합격 때와 같이 
기대 -&gt; 절망 -&gt; 멘붕 -&gt; 합격???
이란 똑같은 레파톨리로 멋사 프론트엔드 부원이 되었다.</p>
<hr>
<ol start="2">
<li>학술 동아리 취급 보고 놀란 썰</li>
</ol>
<p>요 썰이 이제 좀 지금의 인식 마인드로 바뀌게 되는 썰내용인데 </p>
<p>어떻게 인지를 시작했냐, 갑자기 아무래도 <strong>멋사 방문기록을 유튜브 알고리즘이 캐치</strong>를 한건지 멋사 광고가 자꾸 뜨길래, &quot;뭐여 기업 운영 동아리인가?&quot; 라는 생각으로 멋사 정보를 좀 더 찾아보았다.
<strong>여기서 이제 학술 동아리라는 것을 보고 꽤 취급이 좋았구나 정도로 생각 1차개선</strong></p>
<p>이후로는 계기가 뭔지 잘 기억이 안나는데 <strong>학술동아리 수료증이 이력서에 들어갈 수 있다고???</strong> + <strong>들어가기 빡센데 그걸 들어갔다고??? + 걍 진짜 배우고 협업 경험만 쌓으려고 들어온건데 뭐지??</strong>
라는 심정으로 지금의 생각으로 개선이 된것으로 기억한다.</p>
<hr>
<p>뭔가 썰 풀게 많다고 했는데 나머지를 막상 써보려니 타인의 입장에선 공감이 힘들
(개인적인 감정 느낌 포인트 등이 다름 등) 것 같아서 이 2개의 썰만 풀어본다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[멋사 프론트엔드 5주차 회고록]]></title>
            <link>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-5%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D%EC%9E%91%EC%84%B1%EC%A4%91</link>
            <guid>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-5%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D%EC%9E%91%EC%84%B1%EC%A4%91</guid>
            <pubDate>Fri, 08 May 2026 14:38:12 GMT</pubDate>
            <description><![CDATA[<p>이번주 과제는 문제풀이 5문제와, 저저번 4주차(어린이날이라 쉬어서 저저번주 임) 과제로 만들어간 개인 페이지 보강할점 찾아서 보강하기!</p>
<p>나같은 경우는 그..문제였던 웹페이지 주소상 이름과 디자인 쪽을 축제 프로젝트를 위해 연습할 겸, 좀 보강하면 될 것 같다.</p>
<h1 id="1-문제-풀이">1. 문제 풀이</h1>
<ol>
<li><strong>바탕 화면에 새로운 리액트 프로젝트를 생성하고, 해당 폴더로 이동해 프로젝트를 실행하는 방법을 순서대로 쓰세요. 또 이미 열려있는 서버를 끄는 방법도 설명해보세요.</strong></li>
</ol>
<pre><code class="language-jsx">1\. vsCode 열기

2\. 터미널 창 오픈 후, cd ~/Desktop으로 경로를 바탕화면으로 이동 이후 npx create-react-app (파일명) 입력
이후 cd (생성 후 복사한 파일의 경로) 입력으로 터미널창의 경로 조정

3\. npm start로 로컬 서버 열기

4\. npx kill-port 3000(해당 주소는 주소창의 로컬서버 번호에 따라 변경될 수 있음) 입력
</code></pre>
<p>이번에 좀 솔직히 말하자면, 4번 말고, 맨날 바탕화면에서 파워셸 창 띄우고 
리엑트 프로젝트 생성후 들어가서, 
2번 과정을 설명을 못해서 검색을 했는데 
검색중 바탕화면 주소를 경로 복사할 필요 없이  mac과 윈도우 환경 둘다에서 
호환이 되는 <code>cd ~/Desktop</code> 이라는 즉시 바탕화면으로 경로를 이동하는 커맨드를 발견했다.</p>
<p>그리고 4번은 해본적이 없어서 새롭게 검색을 통해 알게 되었다.</p>
<hr>
<ol start="2">
<li><strong><code>State</code>를 이용해 빈칸을 채워보세요.</strong></li>
</ol>
<pre><code class="language-jsx">
import { useState } from &quot;react&quot;;



const Counter = () =&gt; {
    const[count, count_change] = useState(0);  //초기값 없길래 그냥 0으로 설정
    return &lt;div&gt;현재 수량: {count}&lt;/div&gt;;

};
</code></pre>
<p>그냥 useState 이용 문제? 
근데 좀 최근에 멋사 과제말고 
프로그래밍 과목에서 C언어 과제들하다가 좀 리엑트 문법을 까먹어서 예전에 
했던 것들 좀 살펴보고 인터넷도 한 두 페이지 뒤져서 풀었다.</p>
<p>그러다가 참고한 좋은 벨로그 글이 있어서 여기에도 남겨본다.
<a href="https://velog.io/@hamham/%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%97%90%EC%84%9C-state%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0">[리액트] state를 사용하는 이유 (비얌)</a></p>
<hr>
<p><strong>3. 틀린 부분을 찾고 올바르게 고쳐보세요. 또 <code>export default</code>가 무슨 뜻인지 설명해보세요.</strong></p>
<pre><code class="language-jsx">
export default const HelloBtn = () =&gt; { 
    const sayHello = () =&gt; {
      alert(&quot;Hello!&quot;);
};

    return (
    &lt;button onClick={sayHello()}&gt;인사하기&lt;/button&gt; 
    );

}
</code></pre>
<pre><code class="language-jsx">// 올바르게 고친것

const HelloBtn = () =&gt; {
    const sayHello = () =&gt; {
        alert(&quot;Hello!&quot;);
    };

    return (
&lt;button onClick={ () =&gt; sayHello()}&gt;인사하기&lt;/button&gt; &lt;= 화살표 함수 형식으로 바꾸어 클릭시 동작하려는 의도에 맞게 고침
    );
}; &lt;= 여기 세미콜론 빠짐

export default HelloBtn; &lt;= 여기 추측은 되지만 명확한 이유를 모르겠는데 리엑트 파일에 문제그대로 작성시 오류줄이 뜨는것으로 보아 이렇게 고쳐야 함 </code></pre>
<p>export default의 뜻은 
우선 이게 있으면 다른 파일에서 import &#39;HelloBtn&#39;; 만 해주면 또 같은 로직을 그 파일에 따로 적을 필요 없는데, 비유하자면 </p>
<p>함수의 수출명칭(?)을 export default 뒤에 있는 명칭으로 정하고 내보낸다는 뜻. </p>
<p>그리고 마지막줄에 명확한 이유를 모르겠다고 한건 함수를 그대로 내보내면 당연히 안될걸 직감적으로 알겠는데 명확한 오류 명은 모르는 느낌적인 느낌 정도.</p>
<hr>
<ol start="4">
<li><strong><code>App</code> 컴포넌트에서 <code>MenuBox</code> 컴포넌트로 <code>price</code> 데이터를 넘겨주려고 합니다. 넘겨주는 쪽과 받는 쪽의 빈칸을 각각 채워주세요.</strong></li>
</ol>
<pre><code class="language-jsx">
// 넘겨주는 쪽 (부모)

const App = () =&gt; {

    return (
   &lt;MenuBox price = {15000}&gt;// MenuBox에 price라는 이름으로 숫자 15000을 넘기기
     );

};



// 받는 쪽 (자식)

// 부모가 넘겨준 데이터를 받아오기

const MenuBox = (menu) =&gt; { 
return &lt;div&gt;가격: { menu.price }원&lt;/div&gt;;
};
</code></pre>
<p>답 작성후 작성한 답을 제미나이에 넣어서 오류가 있는지 검증하는 과정 중
마지막 부분에</p>
<pre><code class="language-jsx">const MenuBox = ({price}) =&gt; {
return &lt;div&gt;가격: { price }원&lt;/div&gt;;
};</code></pre>
<p>{price} 를 그냥 화살표 함수에 내다 넣어버리면 
그냥 price만 입력해도 의도한 값이 뜬다고 한다. </p>
<p>개인적으로 리엑트가 생각보다 유하다고 느끼는 부분 중 하나였음.</p>
<hr>
<ol start="5">
<li><p><strong>삼항 연산자를 이용해 재고가 0개면 <code>품절</code>, 1개 이상이면 <code>주문 가능</code>이라고 띄우는 코드를 완성해보세요.</strong></p>
<pre><code class="language-jsx">const App = () =&gt; {
const stock = 0; // 재고 수량

return (
 &lt;div&gt;
   {stock &gt; 0 ? 주문 가능 : 품절}
 &lt;/div&gt;
);
};</code></pre>
<p>그냥 삼항연산자 문제였음. 
근데 너무 간단하게 끝나서 이게 정답이 맞는지 작성하는 지금도 모르겠음. 제미나이한테도 물어봤는데 문제없는 코드고, 요즘 하는 c언어 과제 난이도때문에 생기는 심리적인 이유라고 한다.</p>
</li>
</ol>
<h1 id="일정-변경으로-인해-6주차-스킵-후-7주차-게시물에서-계속">(일정 변경으로 인해 6주차 스킵 후 7주차 게시물에서 계속)</h1>
]]></description>
        </item>
        <item>
            <title><![CDATA[깃허브 기초 조작법]]></title>
            <link>https://velog.io/@sloth_slys/%EA%B9%83%ED%97%88%EB%B8%8C-%EA%B8%B0%EC%B4%88-%EC%A1%B0%EC%9E%91%EB%B2%95%EA%B0%9C%EC%9D%B8-%EB%A9%94%EB%AA%A8%EC%9A%A9</link>
            <guid>https://velog.io/@sloth_slys/%EA%B9%83%ED%97%88%EB%B8%8C-%EA%B8%B0%EC%B4%88-%EC%A1%B0%EC%9E%91%EB%B2%95%EA%B0%9C%EC%9D%B8-%EB%A9%94%EB%AA%A8%EC%9A%A9</guid>
            <pubDate>Tue, 28 Apr 2026 10:18:28 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p>깃허브 레포지터리(저장소) 연동하는 법
터미널에 git clone (저장소 링크)</p>
</li>
<li><p>커밋
폴더 경로 꼭확인!(자기가 작업한 파일이 (코드가 다 포함된 파일을 의미) 경로여야 함)
터미널에 cd &quot;(파일경로 입력, vs코드에선 끌어오기로 복사가능)&quot; 
cd ..이전 상위 경로로 이동
cd .... 으로 2단계 전 상위 경로로 이동</p>
<ul>
<li>커밋
git add . -&gt; 모든 변경사항 저장(띄어쓰기 잘 확인)
git commit -m -&gt;&quot;메세지 내용&quot; 커밋 시 내용설명 붙이기
git push origin (브랜치 명) -&gt; 깃허브에 올리기</li>
</ul>
</li>
</ul>
<pre><code>- 브랜치 관리 
 git fetch origin: 새로 만든 브랜치 확인(브랜치 목록 새로고침)
 git branch: 현재 있는 브랜치 위치 확인
 git switch (브랜치명) : 해당 브랜치로 이동
 git checkout -b (새로만들 브랜치 명): 브랜치 생성
git checkout -d (삭제할 브랜치 명): 브랜치 삭제(내쪽에서만)

- PS(풀 리퀘스트 요청 하는법): 깃허브에서 해당 브랜치명의 리퀘스트 버튼 누른뒤 설명 쓰고, create pull request버튼 클릭 이후 커밋할 브랜치경로(메인인지 다른곳인지) 확인</code></pre><ul>
<li><p>머지하는법: 충돌 잘확인후 허용 버튼 누르기?(여튼 팀장 역할 임)</p>
<ul>
<li>새롭게 변경하는 거 끌어오는 방법
git switch main 
git pull origin main()
(안전상의 이유로 다시 브랜치 변경) git switch (자기 브랜치)</li>
</ul>
</li>
<li><p>충돌 해결
리솔브 프라블럼 버튼이 깃허브에 뜨는데 
이후 셋중 하나 고르면 됨(내꺼/남의꺼/다 살릴거)</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[멋사 프론트엔드 회고록 4주차]]></title>
            <link>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%9A%8C%EA%B3%A0%EB%A1%9D-4%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%9A%8C%EA%B3%A0%EB%A1%9D-4%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 27 Apr 2026 17:28:53 GMT</pubDate>
            <description><![CDATA[<p>근 3주만에 재개하는 회고록!
원래는 조금더 이번 과제를 일찍 시작해서 퀄리티좀 빵빵하게 하고 싶었지만 
예상외로 시험 끝나고 약한 몸살과 귀차니즘이 덮쳐서</p>
<p>이번에는 뼈대만 만든느낌이긴 하지만, 중요한건 다 했으니 괜찮다.
<del>아마도</del></p>
<h2 id="이번-주차-과제">이번 주차 과제</h2>
<ol>
<li>폴더 구조 정리하기 및 라우터 세팅</li>
<li>인트로 페이지(Home.jsx) 만들기, 경로는 / 로 들어왔을 때</li>
<li>페이지 왔다 갔다 연결하기</li>
<li>{선택사항} 공통 헤더 부분 만들기</li>
</ol>
<h2 id="1-폴더-구조-정리하기-및-라우터-세팅">1. 폴더 구조 정리하기 및 라우터 세팅</h2>
<p>이번 단계는 그다지 어렵지 않다.
폴더구조를 꽤나 보편적이고 보기 쉬운 구조로 설정하고 만들면 해결되는 일이다.
src 라는 기본적으로 있느 폴더 안에 <code>components</code>, <code>pages</code>, <code>styles</code> 폴더를 생성후</p>
<p>컴포넌트 폴더에는 말그대로 구성요소. 선택 과제인 공통헤더로 보여질 파일 등이 들어가고
페이지엔 Home,Profile 등이 웹 페이지들
스타일엔 css 파일들이 들어간다.
<img src="https://velog.velcdn.com/images/sloth_slys/post/51c1831c-0096-4b4e-a141-56ee51097f60/image.png" alt=""></p>
<p>요렇게</p>
<h3 id="1-1-라우터-설치">1-1. 라우터 설치</h3>
<p>app.js에 이동한뒤
오늘도 어김없이 vscode의 터미널 창을 연 다음
npm install react-router-dom
을 입력한다.</p>
<p>그럼 맨 윗줄에
<code>import { BrowserRouter, Routes, Route } from &#39;react-router-dom&#39;;</code>
이 생긴다.</p>
<p>이러면 라우터 설치가 끝나긴 하는데 조금더 몇가지 앞서 말하자면</p>
<pre><code class="language-js">import { BrowserRouter, Routes, Route } from &#39;react-router-dom&#39;;
import Home from &#39;./pages/Home&#39;;
import Profile from &#39;./pages/Profile&#39;;
import Self from &#39;./pages/Self&#39;;
import Common_Header from &quot;./components/Header&quot;

/*
만약 공통 헤더를 넣을것이라면 
import Common_Header from &quot;./components/Header&quot;
와
&lt;Common_Header /&gt;
처럼 호출하는 이름이 같아야 함
&lt;Routes&gt; 안쪽: 주소가 바뀔 때마다 그 주소에 맞는 컴포넌트 하나만 골라서 보여주는 곳

&lt;Routes&gt; 바깥쪽: 주소가 아무리 바뀌어도 리액트가 갈아끼우지 않고 그대로 유지하는 영역
*/


function App() {
  return (

  &lt;BrowserRouter&gt;
    &lt;Common_Header /&gt; 
    &lt;h1&gt;App.js 영역&lt;/h1&gt;

      &lt;Routes&gt;
        {/* 기본 경로로 들어오면 Home 다른 함수에서 홈 호출하려면 / 만 써야 됨*/}
        &lt;Route path=&quot;/&quot; element={&lt;Home /&gt;} /&gt;

        &lt;Route path=&quot;/Profile&quot; element={&lt;Profile /&gt;} /&gt;
        &lt;Route path=&quot;/Self&quot; element={&lt;Self /&gt;} /&gt;



      &lt;/Routes&gt;
  &lt;/BrowserRouter&gt;

  );
}

export default App;</code></pre>
<p>주석 같은거 달때 이번 주차 예제 복붙하거나 ai로 팩트체크 한게있긴 한데</p>
<p>지금 살펴볼것은
import ~ from~ 이라는 제일 상단쪽 줄이다.</p>
<p>가령
<code>import Home from &#39;./pages/Home&#39;;</code>
이라는 것은</p>
<p>import 바로 뒤의 Home 이라는 건 Home이라는 다른 파일에서 <code>export default Home;</code>으로 내보낸 것을 받아오는것이다.</p>
<p>어디서?
바로 <code>&#39;./pages/Home&#39;</code> 이라는 곳에서, 개인적으로 상대경로 복습할 겸 써보자면.
같은 검색깊이에 있는 pages라는 폴더에서 Home.jsx를 찾게 하는것이다.
편하게도 jsx 까지 안써도 파일 확장자까지는 자동으로 처리해준다.</p>
<p>그다음.
아까 라우터를 받아오며 <code>BrowserRouter, Routes, Route</code> 태그를 받아왔다</p>
<pre><code class="language-jsx">&lt;BrowserRouter&gt;
    &lt;h1&gt;App.js 영역&lt;/h1&gt;

      &lt;Routes&gt;
        &lt;Route path=&quot;/&quot; element={&lt;Home /&gt;} /&gt;
        &lt;Route path=&quot;/Profile&quot; element={&lt;Profile /&gt;} /&gt;
        &lt;Route path=&quot;/Self&quot; element={&lt;Self /&gt;} /&gt;
      &lt;/Routes&gt;
  &lt;/BrowserRouter&gt;
</code></pre>
<p>브라우저 라우터 태그 안에 라우트와 공통 헤더를 넣을수있다.</p>
<p>이미지가 안그려진다면
요런 느낌</p>
<p>App.js 영역
이란 글자 밑에
<strong>내가 Home 파일</strong>에 써둔 내용이 나온다
<img src="https://velog.velcdn.com/images/sloth_slys/post/68752eec-1d5c-4139-bf49-3a2c1874774e/image.png" alt="">
(조금 글자 내용이 다른건 과거 사진이라 그렇다)</p>
<p><code>&lt;Routes&gt;</code>에는
<code>&lt;Route path=&quot;/&quot; element={&lt;Home /&gt;} /&gt;</code>
같이 넣을 구 있는데 여기서 루트 패스의 / 는 기본주소로써 
npm start를 치면 바로뜨는 그 창이다.
(<a href="http://localhost:3000/">http://localhost:3000/</a>) 여기 주소</p>
<p>그 뒤의 element는 Home이라는 파일내용(컴포넌트)을 보여주겠다~ 란 의미
<del>솔직히 나중에 Route path와 element는 기억할 것 같은데 쓰는 방식이 조금 헷갈릴 것 같긴하다</del></p>
<h2 id="2-인트로-페이지homejsx-만들기">2. 인트로 페이지(Home.jsx) 만들기</h2>
<p>만약 여기까지 라우트 관련한게 잘 이해 갔다면 이 뒤로는 일사천리기 때문에 그다지 걱정 안해도 된다. 다만! Navigate 내용이 새로 있다.</p>
<pre><code class="language-jsx">import React from &#39;react&#39;;
import { useNavigate } from &#39;react-router-dom&#39;;

function Home() {
  const navigate = useNavigate();
  return (
    &lt;div&gt;
      &lt;h2&gt;웹페이지 홈구역에 오신걸 환영합니다!&lt;/h2&gt;
        &lt;button onClick={() =&gt; navigate(&quot;/Profile&quot;)}&gt;블로그 페이지로 이동&lt;/button&gt;
        &lt;button onClick={() =&gt; navigate(&quot;/Self&quot;)}&gt;내 소개 보러 가기&lt;/button&gt;

    &lt;/div&gt;
  );
}

export default Home;</code></pre>
<p>이건 실제로 내가 쓴 이번 주차의 Home.jsx에 있는 내용인데</p>
<p>조금 분석을 해보자
음..우선
1.useNavigate 란 것을&#39;react-router-dom&#39;에서 가져왔다.</p>
<ol start="2">
<li><p>이후로 밑에 const navigate = useNavigate(); 로 설정해서 
useNavigate()를 다 칠 필요 없이 navigate라는 변수에 할당해서 사용하게 만들었다.(줄여쓰기 쯤으로 생각해도 무리없다.)</p>
</li>
<li><p>맨 끝에 export default Home;을 함으로써 Home이라는 이름으로 파일내용을 내보내 App.js 에서 <code>import Home from &#39;./pages/Home&#39;;</code>을 통해 수신할 수 있게 만들었다.</p>
</li>
</ol>
<h3 id="2-1-navigate-관련">2-1. navigate 관련</h3>
<p>지금 
<code>&lt;button onClick={() =&gt; navigate(&quot;/Profile&quot;)}&gt;블로그 페이지로 이동&lt;/button&gt;</code> 
와 같이 버튼 태그 안에 넣어서 onClick 즉,클릭할시 </p>
<p>그 안에 있는 함수인 navigate가 동작해서 Profile 이라는 주소로 이동해 아까 App.js에 쓴것
<code>&lt;Route path=&quot;/Profile&quot; element={&lt;Profile /&gt;} /&gt;</code> 
처럼 그 주소에 지정된 Profile.jsx 파일 내용(컴포넌트)을 보여주는 것이다.</p>
<p><strong>아 혹시 조금 이상한 점이 보일수도 있는데 주소명이 Profile인데 왜 블로그 페이지로 이동이 적혀있냐면 이게 복붙을 잘못해서 그렇다. 
주로 작업 시작시 잠결에 한게 문제.</strong></p>
<p>그래서 진짜 프로필은 Self.jsx라는 파일 안에 있다.</p>
<p>사진을 보여주자면 주소명과 제목이 조금 꼬여있다.
<del>제목은 진짜 어떻게하다 저렇게 수정까지 하고 꼬였는지 기억이 안남</del>
<img src="https://velog.velcdn.com/images/sloth_slys/post/b290d194-149c-4503-804a-81e52425237e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/e235eb02-7370-4b53-b5cf-1f862fce3f41/image.png" alt=""></p>
<h3 id="2-2-navigate-팁">2-2. navigate 팁</h3>
<p>만약에 만약에. 페이지 이동 기능까지 만들고 페이지를 이동후. 복귀 시 오류가 뜬다면</p>
<p>복귀하려는 컴포넌트에 있는 리턴위에
<code>const navigate = useNavigate();</code>가 안적혀있는 걸수도 있다.</p>
<p>그리고 만약에 만약에 웹페이지 이동했는데 아무것도 안뜨고 백색화면이다.
그럼 내용은 잘썼는데 <strong>그 내용을 <code>return()</code>안에 안넣었거나, 이동 주소가 잘못된 것</strong>일수도 있다.</p>
<p>이 때 추가적인 팁은 아까 공용헤더를 잠시 언급한것 처럼 이게 내용이 그냥 안뜨는건지, 아니면 모종의 사유로 모든 글자가 안뜨는 것인지 알기 위해 </p>
<p>에를 들어 App.js에</p>
<pre><code class="language-jsx">&lt;BrowserRouter&gt;
    &lt;h1&gt;App.js 영역&lt;/h1&gt;

      &lt;Routes&gt;
        &lt;Route path=&quot;/&quot; element={&lt;Home /&gt;} /&gt;
        &lt;Route path=&quot;/Profile&quot; element={&lt;Profile /&gt;} /&gt;
        &lt;Route path=&quot;/Self&quot; element={&lt;Self /&gt;} /&gt;
      &lt;/Routes&gt;
  &lt;/BrowserRouter&gt;
</code></pre>
<p>처럼 
<code>&lt;Routes&gt;</code>위에 모든 웹페이지에서 </p>
<pre><code class="language-jsx">&lt;h1&gt;App.js 영역&lt;/h1&gt;</code></pre>
<p>처럼 공통으로 보여질 내용을 간단히 써서 어디서 오류가 나는지 시각적으로 체크해보자.</p>
<h2 id="3-페이지-왔다-갔다-연결하기">3. 페이지 왔다 갔다 연결하기</h2>
<p>이건 쉽다. </p>
<pre><code class="language-jsx">import { useNavigate } from &#39;react-router-dom&#39;;</code></pre>
<p>를 먼저 모든페이지 상단에 적어준뒤</p>
<p>아까 만든 버튼 태그</p>
<pre><code class="language-jsx">&lt;button onClick={() =&gt; navigate(&quot;(이동할 path명)&quot;)}&gt;(버튼에 뜨는 텍스트 내용)&lt;/button&gt;</code></pre>
<p>이런 형식으로 버튼을 모든 페이지에 <strong>시각적으로 적절한 위치(이게 제일 중점)</strong> 에 넣어주면 된다.</p>
<p>아. <code>navigate</code>를 썼으니 나 같은 경우엔 함수 안쪽 리턴문 바깥에다가 
<code>const navigate = useNavigate();</code>를 추가적으로 적어줘야 한다.</p>
<pre><code class="language-jsx">function Home() {
  const navigate = useNavigate(); //여기 삽입함
  return (
    &lt;div&gt;
      &lt;h2&gt;웹페이지 홈구역에 오신걸 환영합니다!&lt;/h2&gt;
        &lt;button onClick={() =&gt; navigate(&quot;/Profile&quot;)}&gt;블로그 페이지로 이동&lt;/button&gt;
        &lt;button onClick={() =&gt; navigate(&quot;/Self&quot;)}&gt;내 소개 보러 가기&lt;/button&gt;

    &lt;/div&gt;
  );
}</code></pre>
<p>삽입 위치 헷갈리면 참고</p>
<h2 id="4-선택사항-공통-헤더-부분-만들기">4. {선택사항} 공통 헤더 부분 만들기</h2>
<p>이건 조금 쉬울수도 있고 헷갈릴수도 있는데.
우선 컴포넌트 파일에 Header.jsx 파일을 만들고</p>
<p>이런 내용</p>
<pre><code class="language-jsx">import React from &#39;react&#39;;

function Common_Header() {
  return (
    &lt;header style={{ padding: &#39;20px&#39;, background: &#39;#eee&#39; }}&gt;
      &lt;h2&gt;헤더 영역&lt;/h2&gt;
    &lt;/header&gt;
  );
}

export default Common_Header;</code></pre>
<p>이후 App.js에서
<code>import Common_Header from &quot;./components/Header&quot;</code>
로 불러와준다.</p>
<pre><code class="language-jsx">function App() {
  return (

  &lt;BrowserRouter&gt;
    &lt;Common_Header /&gt; {/*여기 넣음!*/}
    &lt;h1&gt;App.js 영역&lt;/h1&gt;

      &lt;Routes&gt;
        &lt;Route path=&quot;/&quot; element={&lt;Home /&gt;} /&gt;
        &lt;Route path=&quot;/Profile&quot; element={&lt;Profile /&gt;} /&gt;
        &lt;Route path=&quot;/Self&quot; element={&lt;Self /&gt;} /&gt;



      &lt;/Routes&gt;
  &lt;/BrowserRouter&gt;</code></pre>
<p>조금 김 샐수도 있지만 라우트 바깥. 브라우저 라우터 태그 안쪽에 넣으면 그냥  Header파일 내용이 뜬다.  </p>
<p><strong>태그가 왜 <Common_Header /> 냐면</strong> 그렇게 내보내기 명을 정하고 그대로 받아왔기 때문이다.(정 헷갈린다면, 만들때 파일명 = 내보내기명(export default ~) 로 일치 시킨 뒤 불러오는 걸 추천한다.)</p>
<p>추측이긴한데, 아마 파일명 = 내보내기명으로 안하면 팀플에서 욕먹을수도 있을 것 같긴하다. 지금은 개인이라. 기능 설명을 용이하게 하기위해 좀 이름을 다르게 했긴 한데.... 생각해보니 
그냥 <strong>파일명 = 내보내기명</strong> 을 하자</p>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/cafc6839-6a1c-4c81-9cb9-b02486a40026/image.png" alt=""></p>
<p>여튼 만든다면 저 헤더영역이라고 적힌 박스가 모든 페이지에서 공통적으로 뜨게 된다.</p>
<h2 id="4-1-funtion-명과-내보내기-명이-같아야-한다안-지키면-오류-발생">4-1. funtion 명과 내보내기 명이 같아야 한다.(안 지키면 오류 발생)</h2>
<p>function Common_Header() {
 (중간 코드들)
 }
export default Common_Header; 
같이</p>
<p>여긴 별 내용 없고 실수로 안적은 중요한 내용이라 이렇게 제목으로 <strong>슈퍼 강조</strong>했다.</p>
<h2 id="5-어려웠던-점">5. 어려웠던 점</h2>
<p>이번 주차가 c언어 + 타과목들 시험대비하다 온거라 2~3주차만에 다시 리엑트를 해서 조금 
처음엔 감다뒤 상태여서 복귀에 시간이 조금 걸려 힘든점이 있었다.</p>
<p>그리고 이번에 라우트 하면서 별별 오류를 다 겪은것 같은데 
본문 내용에 적힌 팁의 <strong>가정 상황</strong> 등이 직접 겪은 수난이다.</p>
<p>이외엔 아쉬운점? 빼고는 해결안된 오류는 없어서 그렇게 치명적인 어려운점은 없던 편.</p>
<p>아쉬운 점은 코드 파일 복붙 잘못해서 경로명 살짝 막장 된것? 과 디자인을 조금 넣고 싶었는데 그냥 시간 때문에 포기한 점 등이 있다.</p>
<h2 id="6-새로-배운-점">6. 새로 배운 점</h2>
<p>전반적으로 꼽자면 라우트의 모든 것이 새로 배운점이긴 한데
요약 형태로 적어보겠다.</p>
<ol>
<li>공통 컴포넌트 구역 만들기(Header.jsx 등)</li>
<li>useNavigate() 써서 페이지 이동 및 + 어떤 식으로 오류나는지</li>
<li>다른 파일 내용 받아오는 방법
<code>import Home from &#39;./pages/Home&#39;;</code> 와 <code>export default Home;</code> 같이</li>
<li>그리고 경로 및 해당 경로의 내용 요소 설정 <code>&lt;Route path=&quot;/&quot; element={&lt;Home /&gt;} /&gt;</code></li>
</ol>
<p>이번 주 벨로그 끝!</p>
<ul>
<li>미처 못보고 지나친 댓글 과제 추가
<img src="https://velog.velcdn.com/images/sloth_slys/post/6e7f8994-74ca-45d6-b915-b8875603e54a/image.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[멋사 프론트엔드 3주차 과제]]></title>
            <link>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-3%EC%A3%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9C</link>
            <guid>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-3%EC%A3%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9C</guid>
            <pubDate>Mon, 06 Apr 2026 17:24:56 GMT</pubDate>
            <description><![CDATA[<h4 id="이번주차는-시간분배-실패로-결과물과-배운점만-중점적으로-소개"><strong>이번주차는 시간분배 실패로 결과물과 배운점만 중점적으로 소개</strong></h4>
<h1 id="1요구사항-나열">1.요구사항 나열</h1>
<p><strong>1차시 때 만들었던 블로그를 리액트에서 그대로 재현하기</strong>
    1. 새 프로젝트 생성 후, <code>App.js</code> 한 파일에 모두 작성할 것
    2. 최소 3개 이상의 컴포넌트로 구조를 나눌 것
    3. <code>useState</code> 기능을 이용해 <code>좋아요</code> 버튼을 추가할 것 (클릭 시 좋아요 개수가 증가해야 함)
    4. <code>styled-components</code> 로 스타일을 재현할 것</p>
<h2 id="2-1주차-과제파일-변경">2. 1주차 과제파일 변경</h2>
<ul>
<li><p><a href="https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8-%EC%97%94%EB%93%9C1%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D">1주차게시글 보러 가기</a></p>
<pre><code class="language-jsx">&lt;h1&gt;멋사 1주차 과제 자기소개 페이지&lt;/h1&gt;

        &lt;MiniCard&gt; 
          &lt;div className=&#39;minicaed&#39;&gt;
              &lt;img src=&quot;/kiwi.webp&quot; width=&quot;250px&quot; height=&quot;250px&quot; alt=&quot;키위 이미지&quot; /&gt;


</code></pre>
</li>
</ul>
<pre><code>                &lt;h2 style = {{color: &quot;red&quot;}}&gt;{personal_info [0]} &lt;/h2&gt;
            &lt;ol&gt;
                &lt;Part&gt;&lt;li&gt;분야: {personal_info [1]}&lt;/li&gt;&lt;/Part&gt;
                &lt;li&gt;멋사 14기생 &lt;span onClick = { () =&gt; {좋아요_변경(좋아요+1)}}&gt; 👍{좋아요}&lt;/span&gt; &lt;/li&gt;


            &lt;/ol&gt;
        &lt;/div&gt;
      &lt;/MiniCard&gt;



  &lt;MainCard&gt;
    &lt;div className=&#39;maincard&#39;&gt;
        &lt;p&gt;
            &lt;li&gt;&lt;h1&gt;{personal_info[0]}&lt;/h1&gt;&lt;/li&gt;
            &lt;div className = &#39;main_track&#39;&gt;&lt;li&gt;분야: {personal_info[1]}&lt;/li&gt;&lt;/div&gt;
            &lt;li&gt;동아리: 멋진 사자들처럼[14기]&lt;/li&gt;
        &lt;/p&gt;

         &lt;p&gt;
            &lt;li&gt;&lt;h2&gt;자기 소개&lt;/h2&gt;&lt;/li&gt;
            &lt;li&gt; 자기소개임.&lt;/li&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;li&gt;&lt;h2&gt;연락처&lt;/h2&gt;&lt;/li&gt;
            &lt;ul&gt;

            &lt;li&gt;Email: &lt;a href =&quot;https://mail.google.com&quot; target=&quot;_blank&quot; title=&quot;이메일 페이지로 이동&quot;&gt;{personal_info[2]}&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;핸드폰: {personal_info[3]}&lt;/li&gt;

            &lt;/ul&gt;
        &lt;/p&gt;


        &lt;p&gt;
            &lt;li&gt;&lt;h2&gt;관심 기술&lt;/h2&gt;&lt;/li&gt;
            &lt;ul&gt;
            &lt;li&gt;c#(초보)&lt;/li&gt;
            &lt;li&gt;HTML/CSS(배우는 중)&lt;/li&gt;
            &lt;li&gt;Java Script(배울 것)&lt;/li&gt;

            &lt;/ul&gt;
        &lt;/p&gt;

        &lt;p&gt;
            &lt;li&gt;&lt;h2&gt;한 마디&lt;/h2&gt;&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;목표는 풀스택 개발자!&lt;/strong&gt;&lt;/li&gt;
        &lt;/p&gt;
    &lt;/div&gt;
  &lt;/MainCard&gt;</code></pre><pre><code>급한대로 최종본을 코드박스에 넣게되었긴하지만, 기존 html + css 형태의 파일을 jsx로 변형하는 과정에
&lt;ol&gt;
&lt;li&gt; div1,div2 태그등을 className을 이용해서 시각적,시스템적으로 구별하는 방식으로 변경&lt;br&gt;
  ㄴ 첫 주차 때는 class 같은걸 모르고 안 썻다가 의미없는 태그 여러개를 생성하는 방식으로 했었는데 지금은 보다 통용적인 방식으로 바꾸었다.&lt;/li&gt;&lt;br&gt;

&lt;li&gt; 이미지 형식 변경: 기존 상대 경로를 이용하는 방식은 똑같지만, 방식이 jsx식으로 변경되었다.&lt;/li&gt;&lt;br&gt;

  &lt;li&gt;그 외:pesonal_info 리스트로 공통되는 정보 한번에 바꾸기 쉽게 변경, style = {{color: &quot;red&quot;}} 처럼 인라인 스타일 방식도 한번 테스트로 적용&lt;/li&gt;
  &lt;/ol&gt;
</code></pre><p>let [personal_info, pesonal_info_change] = useState([&#39;아기사자&#39;, &#39;프론트엔드&#39;, &#39;email@email&#39;, &#39;010-1234-1234&#39;])</p>
<pre><code>+ 인라인 스타일에서 중괄호가 2번 씌워지는 이유는 겉 중괄호는 
이제부터 자바스크립트 코드를 쓴다라고 하는 jsx 문법의 의미이고, 
속 중괄호는 자바스크립트의 객체임을 의미


## 3. 좋아요 기능
우선 코드 파일 최상단 부분에 
```import { useState } from &#39;react&#39;;```
를 작성한뒤

어느 함수안에(그렇다고 리턴 내부 말고.)
```let [현재 상태 값, 이를 갱신하는 함수] = useState(초기값);```
이런 구조로 작성한다. 

여튼 
```let [좋아요, 좋아요_변경] = useState(0);```
이런 useState를 만든뒤 에를 들어... 내 기수 옆에 좋아요 버튼을 만든다고 치면
```jsx
&lt;MiniCard&gt; 
  {/* 컴포넌트 이름은 무조건 대문자 시작(이거 안지키면 실행되는데 오류나는 상황 발생) */}
  &lt;div className=&#39;minicaed&#39;&gt;
    &lt;img src=&quot;/kiwi.webp&quot; width=&quot;250px&quot; height=&quot;250px&quot; alt=&quot;키위 이미지&quot; /&gt;
    {/* 이미지 퍼블릭 파일에 넣고 상대경로써야 파일 안 깨짐 */}


    &lt;h2 style = {{color: &quot;red&quot;}}&gt;{personal_info [0]} &lt;/h2&gt;
    &lt;ol&gt;
      &lt;Part&gt;&lt;li&gt;분야: {personal_info [1]}&lt;/li&gt;&lt;/Part&gt;
      &lt;li&gt;멋사 14기생 &lt;span onClick = { () =&gt; {좋아요_변경(좋아요+1)}}&gt; 👍{좋아요}&lt;/span&gt; &lt;/li&gt;
      {/* onClick 함수 쓸 때 {() =&gt; {실행할 코드}} 처럼 중괄호 쓴뒤 화살표 함수 방식으로 쓰는것 유의*/}

    &lt;/ol&gt;
  &lt;/div&gt;
&lt;/MiniCard&gt;</code></pre><p>이렇게 멋사 14기생 옆에 코드가 작성된걸 볼수 있다.
이것도 기능을 풀어보자면
span 태그는 자바 스크립트 코드를 실행시키는 용도</p>
<p>onClick()은 클릭 감지 =&gt; 따라서 클릭시 코드를 실행시켜주게 하는것</p>
<p>{ () =&gt; {좋아요_변경(좋아요+1)}} 은 화살표 함수 방식으로 위에서 말했던 것처럼 갱신하는 함수의 소괄호 내부에서 좋아요 값에 1을 더하는 방식.</p>
<p>👍{좋아요}는 보이는 그대로 따봉이모티콘과 현재 좋아요 수를 표시해주는것</p>
<ul>
<li>span말고 button 태그를 사용해도 되는데 본인 생각엔 버튼 기본 ui가 조금
후져서 span을 사용했다.</li>
</ul>
<p>&lt;span 방식&gt;
<img src="https://velog.velcdn.com/images/sloth_slys/post/f889334c-8d28-4df5-90db-06e9298c8173/image.png" alt=""></p>
<p>&lt;button 방식&gt;
<img src="https://velog.velcdn.com/images/sloth_slys/post/ed7663a1-4d00-4f63-bac0-d5c77049f806/image.png" alt=""></p>
<h2 id="4-styled-components-사용">4. styled-components 사용</h2>
<p>Styled Components를 리액트 프로젝트에 설치하기 위해 터미널에
<code>npm install styled-components</code>
을 입력해준다(install 을 i로 써도 저절로 인식해서 설치한다)</p>
<p>이후 코드 파일 최상단 부위에 
<code>import styled from &quot;styled-components&quot;;</code>
을 써준뒤</p>
<pre><code>const(또는 let) 함수명 = styled.(태그, 아직 div밖에 사용 안해봄)`


css 문법



`</code></pre><p>이런 형식으로 써주면 된다.</p>
<ul>
<li>styled. 뒷부분은 태그라는데 아직 정확히는 아는바가 없으니 다음 스터디 때나, 추후 개인적 검색을 통해 4주차 스터디 회고록에<del>가능하면</del> 작성하겠다.</li>
</ul>
<p>아래는 최종적인 styled-components 부분이다.</p>
<pre><code class="language-jsx">let MiniCard = styled.div`
 display: flex;
 flex-direction: column;
 width: 50%;
 height: 35%;
 border-radius: 10px;
 border: 3px solid gray;
`
const MainCard = styled.div`
margin-top: 40px;
 display: flex;
 flex-direction: column;
 width: 100%;
 height: 70%;
 border-radius: 10px;
 border: 3px solid gray;
`
const Part = styled.p`
  color: blue;
`</code></pre>
<h3 id="5-아쉬운-점">5. 아쉬운 점</h3>
<p>이번 주는 꽤나 아쉬운 점이 많았는데</p>
<ol>
<li>오류를 검사하는 시간 부족: 이게 뭔말이냐면 평소엔 오류를 직접 한 10<del>30분정도 찾다가 못찾으면 그제서야 ai를 돌렸는데 이번주는 5</del>10분 만에 못찾으면 ai를 사용했다.</li>
<li>보고 따라하기: 이건 좀 애매한데..코드를 작성하는 방식이 좀 헷갈려서 강의를 보면서 작성했던걸 다시 펼쳐보는 일이 좀 많았다.</li>
<li>벨로그 작성 대충: 개인적으로 1,2주차 글보다 이번글의 내용이 혼잡하고 대충인것 같다. 간단히 말하자면 과정이 생략되고 결과본만 작성된 느낌</li>
</ol>
<p>대충 크게 느껴지는 부족한 점은 이 3가지 였다.</p>
<h2 id="6-새롭게-알게-된-점--배우게-된-유의점들">6. 새롭게 알게 된 점 &amp;&amp; 배우게 된 유의점들</h2>
<h3 id="새롭게-알게-된점">새롭게 알게 된점</h3>
<ul>
<li><p>useState 문법 : 자료 잠깐 저장할때 도 씀, 변수와의 차이점은 새 데이터를 자동으로 변경(state 쓰던 html은 자동으로 재랜더링 됨)</p>
</li>
<li><p>destructuring 문법
let num = [1,2];
let [a, b] = [1, 2];
이러면 
let a = num [0];
let b = num [1];
과 동일</p>
</li>
<li><p>컴포넌트 만드는 법:</p>
<pre><code>funtion()만들기
return() 안에 html 담기
&lt;함수명&gt;&lt;/함수명&gt; 짜기</code></pre><pre><code class="language-jsx">funtion Blahblah()
return(
&lt;함수명&gt;함수 내용&lt;/함수명&gt;
)</code></pre>
<p>or</p>
<pre><code class="language-jsx">const(또는 let) 함수명 () =&gt; {
    (코드들)
}</code></pre>
</li>
<li><p>컴포넌트 쓰기 좋은 때</p>
<pre><code> - 반복적인 html을 축약
 - 큰 페이지 하나
 - 자주 변경되는 것들(ui요소들)
 ( 항상 그런 건 아니지만 대부분 이럴 때)</code></pre></li>
<li><p>단점: 다른 함수에 있던 변수(스테이트 등)을 맘대로 못가져가 씀</p>
</li>
</ul>
<h3 id="배운-유의점">배운 유의점</h3>
<ul>
<li><p>useState는 함수 안에 넣어야 오류 안뜸     </p>
</li>
<li><p>스테이트로 리스트를 변경할땐 혹시를 대비해 카피본을 만들고
변경된 카피본을 보여주게 하는것이 좋음</p>
<ul>
<li><p>기존 스테이트 와 신규스테이트가 같으면 변경안 해줌
(아래는 개인 추측)</p>
<pre><code class="language-jsx">let [글제목, set_post_title] = useState([&#39;한글&#39;, &#39;영어&#39;, &#39;외계어&#39;]); 이런 예시

    let copy = [...글제목]; 
// 그냥 글제목을 써버리면 원본 리스트의 주소를 그대로 가르켜서 수정사항이 안보여짐(내가 이해한바로는 이럼)
//[...글제목]이건 새로운 주소값 생성, 아마도 전체적으로 포인터랑 비슷한 주소개념을 가지고 있는듯</code></pre>
<h2 id="핵심-유의점이번에-많이-헷갈린점">핵심 유의점(이번에 많이 헷갈린점)</h2>
</li>
</ul>
</li>
<li><p>컴포넌트 이름은 무조건 대문자 시작(이거 안지키면 실행되는데 오류나는 상황 발생)</p>
</li>
<li><p>이미지 퍼블릭 파일에 넣고 상대경로써야 파일 안 깨짐</p>
</li>
<li><p>onClick 함수 쓸 때 &quot;onClick = {() =&gt; {실행할 코드}}&quot; 처럼 중괄호 쓴뒤 화살표 함수 방식으로 쓰는것 유의</p>
</li>
</ul>
<h1 id="스터디원-댓글-과제">+스터디원 댓글 과제</h1>
<p> 댓글 단 곳: <a href="https://velog.io/@kny337/3%EC%A3%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9C">https://velog.io/@kny337/3%EC%A3%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9C</a></p>
<p> <img src="https://velog.velcdn.com/images/sloth_slys/post/c8cb8f85-f468-4938-9e87-e4e2e19a1943/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[멋사 프론트엔드 2주차 회고록]]></title>
            <link>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-2%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-2%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Sun, 29 Mar 2026 04:36:19 GMT</pubDate>
            <description><![CDATA[<h2 id="리엑트를-쓰는-이유">리엑트를 쓰는 이유</h2>
<p>   html에서 다른 프레임워크(라이브러리들 집합)중에 리엑트를 쓰는 이유는 간단히, 사용자 수 1위라서
  ㄴ 유추 가능한 점이 있는데 많은 사용자 수라는건 이제 쓰는 기업들이 많다는 걸(유니티 나 언리얼 같이) 의미하기도 하고,
  <br>코딩 플랫폼에서 중요한 점이 <strong>협업에서의 용이성,유지 보수성, 호환성 등</strong>
인데 이용자 수가 많으면 용이성이나 유지보수성이 자연스레 좋은 플랫폼이 됨(서브시장이나, 개발자간에 여러 코드 공유 등?)<br></p>
<ul>
<li>코딩 언어중 가독성이 안좋은 예시로는 
(거의 다 개발 비화가 개그성이긴 하지만) 
엄랭이나 랭슝좍 등이 존재 (이를 난해한 프로그래밍 언어 라고 함)</li>
</ul>
<h1 id="문제-풀이">문제 풀이</h1>
<h3 id="문제-1-화살표-함수-연습"><strong>문제 1. 화살표 함수 연습</strong></h3>
<p>아기사자를 환영하는 함수입니다. <code>const</code> 와 <code>화살표 함수</code> 를 사용하는 요즘 스타일로 바꿔주세요.</p>
<h2 id="답">답</h2>
<pre><code>const welcomeLion = (name) =&gt;
{
return &quot;환영합니다, &quot; + name + &quot; 사자님!&quot;;
}</code></pre><h3 id="문제-2-삼항-연산자-연습"><strong>문제 2. 삼항 연산자 연습</strong></h3>
<p>동아리 회비를 냈는지 확인하는 <code>if-else</code> 문을 삼항 연산자를 써서 딱 한 줄로 줄여주세요.</p>
<h2 id="답-1">답</h2>
<pre><code>let isPaid = true;
const status = isPaid ?  &quot;납부 완료&quot; :  &quot;미납&quot;;</code></pre><p>아래는 실수로 기존에 썼던 답</p>
<pre><code>let isPaid = true;
let status = &quot;&quot;;

isPaid ? status = &quot;납부 완료&quot; : status = &quot;미납&quot;; </code></pre><h3 id="문제-3-구조-분해-할당-연습"><strong>문제 3. 구조 분해 할당 연습</strong></h3>
<p>14기 멤버의 정보가 담긴 객체입니다. <code>member.name</code> , <code>member.track</code> 이라고 매번 쓰기 귀찮으니, 구조 분해 할당으로 <code>name</code> 과 <code>track</code>만 쏙 뽑아내는 코드를 작성해 주세요.</p>
<p><em>(주의: 객체 안에 있는 이름 그대로 꺼내야 합니다!)</em></p>
<h2 id="답-2">답</h2>
<pre><code>const member = { name: &quot;상현&quot;, age: 20, track: &quot;프론트엔드&quot;, role: &quot;아기사자&quot; };

const { name, age, track, role} = member; 

console.log(name); 
console.log(track); </code></pre><h3 id="문제-4-map-함수-연습"><strong>문제 4. <code>map</code> 함수 연습</strong></h3>
<p>스터디 출석부에 이름을 띄워야 합니다. <code>map</code> 을 활용해서 <code>attendance</code> 배열의 이름들에 <code>&lt;li&gt;</code> 태그를 씌워주세요.</p>
<p><em>참고: JS 안에서 태그를 쓸 때, 변수도 넣고 싶다면 중괄호<code>{}</code> 로 꼭 감싸주셔야 합니다.</em></p>
<h2 id="답-3">답</h2>
<pre><code>const attendance = [&quot;상현&quot;, &quot;지인&quot;, &quot;태민&quot;];
const list = attendance.map((name) =&gt;
{
return &lt;li&gt;{name}&lt;/li&gt;
});
//소괄호 위치 주의해야 함
</code></pre><h3 id="문제-5-리액트-컴포넌트-맛보기"><strong>문제 5. 리액트 컴포넌트 맛보기</strong></h3>
<p>다음 주에 부모가 자식에게 데이터를 넘겨줄 때 쓸 진짜 실전 방식입니다. 매개변수 자리 <code>( )</code>  안에서 바로 구조 분해 할당을 해보세요.</p>
<pre><code>// [바꾸기 전]
const ProfileCard = (props) =&gt; {
  console.log(&quot;이름: &quot; + props.name);
  console.log(&quot;파트: &quot; + props.track);
}</code></pre><h2 id="답-4">답</h2>
<pre><code>const ProfileCard = ({name, track}) =&gt; {
  console.log(&quot;이름: &quot; + name);
  console.log(&quot;파트: &quot; + track);
}
디버그 확인용: ProfileCard({ name: &quot;ms&quot;, track: &quot;프엔&quot; });
</code></pre><h3 id="문제-6-실제-리액트-구조-눈에-익히기"><strong>문제 6. 실제 리액트 구조 눈에 익히기</strong></h3>
<p>실제 백엔드 서버에서 데이터를 받아오면 이런 복잡한 배열 형태가 됩니다. 2차시 때 배운 문법을 총동원해서 명부를 완성해 보세요.</p>
<ol>
<li><code>map</code>을 써서 배열을 순회하세요.</li>
<li>매개변수 자리에서 구조 분해 할당으로 <code>name</code>, <code>track</code>, <code>isMaster</code>를 바로 뽑아내세요.</li>
<li>삼항 연산자를 써서 <code>isMaster</code>가 <code>true</code>면 &quot;운영진&quot;, <code>false</code>면 &quot;아기사자&quot;를 출력하세요.</li>
</ol>
<p><em>참고: JS 안에서 태그를 쓸 때, 변수도 넣고 싶다면 중괄호<code>{}</code> 로 꼭 감싸주셔야 합니다.</em></p>
<pre><code>const lions = [
  { id: 1, name: &quot;임상현&quot;, track: &quot;프론트엔드&quot;, isMaster: true },
  { id: 2, name: &quot;새내기&quot;, track: &quot;프론트엔드&quot;, isMaster: false }
];

// [정답을 각자 벨로그에 적어주세요]</code></pre><h2 id="답-5">답</h2>
<pre><code>const lionList = lions.map(({name, track, isMaster}) =&gt; {
  return (
    &lt;div&gt;
      &lt;h2&gt;이름: {name}&lt;/h2&gt;
      &lt;p&gt;파트: {track}&lt;/p&gt;
      &lt;p&gt;직책: {isMaster ? &quot;운영진&quot; : &quot;아기사자&quot;}&lt;/p&gt;
    &lt;/div&gt;
  );
});</code></pre><p>AI사용 내역: 답 확인을 하려 코드를 테스트해보려한는데 코드를 어떻게 돌리는지 방식을 잘 몰라서 ai사용 함(). <strong>직책관련 부분에서도 삼항연산자를 위에 처럼 넣어야한다는 걸 아는 과정에서도 ai사용</strong> 
원래는</p>
<pre><code>isMaster ? tier = &quot;운영진&quot; : tier = &quot;아기사자&quot;
&lt;p&gt;직책:{tier}&lt;/p&gt;</code></pre><p>이렇게 하려고 함</p>
<h3 id="문제-7-디버깅-연습"><strong>문제 7. 디버깅 연습</strong></h3>
<p>아래 코드는 리액트에서 작성하면 화면에 아무것도 안 뜨는 에러 코드입니다. 틀린 이유와 올바른 정답을 찾아보세요.</p>
<pre><code>const numbers = [1, 2, 3];

// 화면에 숫자가 2배로 나와야 하는데 아무것도 안 나옴!
const doubleNumbers = numbers.map((num) =&gt; {
  num * 2;
});</code></pre><ul>
<li>20분 이상 고민했는데 도저히 모르겠다면, AI의 도움을 받아도 좋습니다.</li>
</ul>
<h2 id="답-6">답</h2>
<pre><code>const numbers = [1, 2, 3];


const doubleNumbers = numbers.map((num) =&gt; {
return &lt;p&gt;{num *2 }&lt;/p&gt;;
});</code></pre><p><strong>문제점 및 AI사용 내역</strong>: 답을 맞게 썼는지 미리보기 웹페이지에 뭘해도 안떠서 일단 이게 답이 맞다고 AI 질문을 통해 듣긴 들음.
근데 눈으로 확인을 못해봄</p>
<p><strong>이유</strong>: 우선 문제가 된 이유를 가능한 분석하자면, <strong>return을 안써서</strong> 값 반환이 안되고 딱 연산 만 진행되었던게 문제 같음</p>
<h2 id="새로-알게-된-점">새로 알게 된 점</h2>
<ol>
<li><p>div className=&quot;App&quot; 같이 옆에 class나 className 같은걸 쓰는 이유를 몰랐는데
이는 일종의 주석으로 작용하기도 하고, css나 자바스크립트 파일을 html과 연결할 수 있는 
식별 코드 느낌(몇가지 기능이 있는 전자식 코드 주석 느낌?)</p>
</li>
<li><p>리액트 구조의 return 내부에서 삼항연산자를 어떻게 이용하는지 알게 됨</p>
</li>
<li><p>강의를 통한 jsx관련 내용(하단)</p>
</li>
</ol>
<h3 id="jsx-문법">jsx 문법</h3>
<ol>
<li>class 대신 className 사용, 이유는 class는 javascript에서 키워드 기 때문에 div 같은거 옆에는 className 쓰고 css파일에서는 그거 옆에 쓰인 제목을 가져옴</li>
</ol>
<pre><code class="language-jsx">&lt;div className = &quot;black-nav&quot;&gt;
        &lt;h4&gt;블로그임!&lt;/h4&gt;
      &lt;/div&gt;

//이경우엔 .black-nav 라고 css에서 불러와주면 됨</code></pre>
<ol start="2">
<li><p>변수 넣을 땐 중괄호(데이터 바인딩)</p>
<pre><code class="language-jsx">function App() {

let post = &quot;(서버에서 가져온 데이터)&quot;;
//document.querySelector(&#39;h4&#39;).innerHTML = post;
//원래 자바스크립트에서 서버데이터 적용하는 법

return (
 &lt;div className=&quot;App&quot;&gt;

   &lt;div className = &quot;black-nav&quot;&gt;
     &lt;h4&gt;블로그임!&lt;/h4&gt;

   &lt;/div&gt;
   &lt;h4&gt;{ post }&lt;/h4&gt;

   &lt;/div&gt;
);
}
</code></pre>
</li>
</ol>
<pre><code>이렇게 let으로 지정한 변수를 중괄호로 덮어씌워 jsx 내부로 이송 가능

3. 스타일 지정하는 법
이것도 마찬가지로 중괄호 내부에 씀(중괄호 2개)
```jsx
function App() {

  let post = &quot;(서버에서 가져온 데이터)&quot;;
  let tag_post = &quot;h4에 붙도록 한 아이디&quot;
  //document.querySelector(&#39;h4&#39;).innerHTML = post;
  //원래 자바스크립트에서 서버데이터 적용하는 법

  return (
    &lt;div className=&quot;App&quot;&gt;

      &lt;div className = &quot;black-nav&quot;&gt;
        &lt;h4 id = {tag_post} style ={ {color : &#39;red&#39;, fontSize : &#39;15px&#39; }} &gt;블로그임!&lt;/h4&gt;
// 그래도 css랑 차이점이 있는데 본래 font-size는 fontSize로 써야 작동함
      &lt;/div&gt;
      &lt;h4&gt;{ post }&lt;/h4&gt;

    &lt;/div&gt;
  );
}</code></pre><p>tip: 서로 다른 계열의 여러 속성을 붙이게될 경우엔 뛰어쓰기만 해주면 한 번에 들어감
, 에러메세지는 보통 바로 터미널이나 브라우저 등에 뜨는데 <strong>안 뜰 경우엔 웹페이지의 개발자 도구의 검사에서 콘솔 버튼 누르면 뜸</strong></p>
<h1 id="어려웠던-점">어려웠던 점</h1>
<p>우선 return 내부에서 삼항 연산자를 쓸 때의 방식이 헷갈렸고
제일 기억에도 남고, 해결도 못한 어려운 점은  문제 7번에서의
상수로 나와야하는 답이 화면에 출력되지 않는 것 이었다.</p>
<h1 id="댓글-과제">댓글 과제</h1>
<p>댓글 단 포스트:
<a href="https://velog.io/@goyo88/%EA%B8%B0%EC%B4%88%EC%9D%B4%EB%A1%A0">https://velog.io/@goyo88/%EA%B8%B0%EC%B4%88%EC%9D%B4%EB%A1%A0</a></p>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/d58d1f9b-b38a-4f45-a936-a98bc413481b/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[멋사 프론트 엔드
1주차 회고록]]></title>
            <link>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8-%EC%97%94%EB%93%9C1%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@sloth_slys/%EB%A9%8B%EC%82%AC-%ED%94%84%EB%A1%A0%ED%8A%B8-%EC%97%94%EB%93%9C1%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Sat, 21 Mar 2026 15:58:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sloth_slys/post/c32b7e67-eaef-4bf3-9e4b-951533df4334/image.png" alt=""></p>
<h4 id="1-1주차-학습-내용-요약">1. 1주차 학습 내용 요약:</h4>
<ol>

<li>CSS은 html을 꾸며주는 역할</li><br>

<li>css를 html에 적용시키는 방법은 총3가지 존재<br>
  ㄴ 배운건 css파일을 따로 만들고 html 파일의 head 부분에<br>
link rel ="stylesheet" href ="style.css"을 작성해 파일끼리 연동시키기</li>
<br>
 <li>css파일내에서 html 디자인을 적용시키려면 상위태그를 지정하고 적용하면 됨 </li>
예를 들어 "가나다라"라는 li가 있고, body태그안에 존재하고
이 글자에 색상을 적용시키려고 한다면.

<pre><code class="language-html">
body
{
  color: (색상);
}
</code></pre>
<p>  이런식으로 하면 된다</p>
<p><br><br></p>
<li>css의UI(?)인 레이아웃을 자유롭게 배치하기 위해<br> **display: flex;** 라는 것을 거의 필수적으로 사용</li>
 <br>
<li> flexbox froggy</li>
여러 css문법 배움및 활용
</ol>

<p><strong>justify-content:flex-start: 요소들을 왼쪽 정렬</strong></p>
<p><strong>justify-content:flex-end: 오른쪽 정렬</strong></p>
<p><strong>justify-content:center: 가운데 정렬</strong></p>
<p><strong>justify-content:space-between: 요소들 사이에 동일한 간격 생성</strong></p>
<p><strong>space-around: 요소들 주위에 동일한 간격을 줌</strong>
<em>(배울땐 이렇게 써져 있었는데 비트윈 하고 큰 차이를 아직은 모르겠음, 
추측하건데 between은 박스내부 요소들 개수만큼 나눠서 동일한 간격 생성하는것 같고, 
space-around는 박스내부 요소들 개수만큼 나눈뒤 거대한 네모박스를 생성해 요소 하나하나를 그 안에 집어넣는 느낌?)</em>
<br></p>
<p><strong>align-items: flex-start: 요소들을 꼭대기로 정렬
align-items:flex-end: 요소들을 바닥으로 정렬
align-items:center: 요소들을 컨테이너의 세로선 상의 가운데로 정렬</strong>
ㄴ 전체적으로 세로를 건드리는 느낌</p>
<p><strong>flex-direction: column: 요소들을 위에서 아래로 정렬
flex-direction: column-reverse: 요소들을 아래에서 위로 정렬</strong>
ㄴ 이 외에 다른 것들도 있는데 아직 안 사용해봐서 정리까진 안 함</p>
<h1 id="과제-시작">과제 시작</h1>
<p>1.문제(요구사항) 분석
2.html 선제작
3.css로 디자인 시작
4.완성된 디자인을 보고 오류 개선(글자겹침,가독성 등)</p>
<ul>
<li>추가 도전 과제: 미니카드에 마우스 올릴시 카드가 6px만큼 상승하게 만들기
아마 나누자면 이런 과정일 것이다</li>
</ul>
<h3 id="1문제요구사항-분석">1.문제(요구사항) 분석</h3>
<p><em>(저작권 문제 있을까봐 멋사대학의 예시는 못 올림)</em></p>
<p>일단 분석한 디자인에 따르자면</p>
<ol>
<li>미니 자기소개카드(프로필 사진, 이름, 분야, 자기소개 요약 글)</li>
<li>메인 자기소개카드(미니 칸에있던 내용들,자기소개,연락처관심기수르 한마디)</li>
</ol>
<p>이렇게 2가지 구역으로 나눠져있고 여러가지 정보를 단순히 쓰면 된다
또한 <strong>배경색이 뭔가 연하고</strong>, <strong>구역을 나누는 박스에 외곽선이 있고 끝이 둥그랬다</strong></p>
<p><strong><del>(벨로그에 올리려고 다 만든 후 기껏 쓴 정보같은거 
검열하는게 더 고생이었던건 비밀이다)</del></strong></p>
<h3 id="2-html파일-제작">2. HTML파일 제작</h3>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;

    &lt;head&gt;
        &lt;meta charset=&quot;UTF-8&quot;&gt;
        &lt;title&gt;자기소개 페이지&lt;/title&gt;
        &lt;link rel =&quot;stylesheet&quot; href =&quot;자기소개_페이지_디자인.css&quot; &gt;
    &lt;/head&gt;</code></pre>
<p>우선 기본적인 베이스를 짠다
파일 형식(DOCTYPE)을 html-5 (최신)형식으로 인지시키게 만들고
 웹페이지 언어 형식은 UTF-8로
 웹페이지 제목도 쓰고</p>
<p> 마지막으로 css파일과 연동시켜준다. </p>
<p>rel =&quot;stylesheet&quot; 속성이 아직 뭐하는지는 완벽히 모르지만 
들은 바와, 안넣을 때 html파일이 css파일 디자인을 
적용 안 하는 현상에 보건데</p>
<p>html이 이 파일은 스타일시트다! 라고 인지 시켜줘서 스스로 적용하게 하는 태그 인것으로 보인다</p>
<ul>
<li>이거만들다가 vs코드의 새로운 기능을 알게되었는데
컨트롤+i키를 누르면 ai가 기초를 짜게 만들수 있었다
<br><br><br></li>
</ul>
<pre><code class="language-html"> &lt;body&gt;

        &lt;h1&gt;멋사 1주차 과제 자기소개 페이지&lt;/h1&gt;
            &lt;div1&gt;
                &lt;img &gt;


                    &lt;mini_name&gt;&lt;h2&gt;이름칸&lt;/h2&gt;&lt;/mini_name&gt;
                &lt;ol&gt;
                    &lt;mini_track&gt;&lt;li&gt;분야: Front-end&lt;/li&gt;&lt;/mini_track&gt;
                    &lt;li&gt;자기소개 요약글&lt;/li&gt;

                &lt;/ol&gt;
            &lt;/div1&gt;

        &lt;div2&gt;

            &lt;p&gt;
                &lt;li&gt;&lt;h1&gt;이름칸&lt;/h1&gt;&lt;/li&gt;
                &lt;main_track&gt;&lt;li&gt;분야: Front-end&lt;/li&gt;&lt;/main_track&gt;
                &lt;li&gt;동아리: &lt;/li&gt;
            &lt;/p&gt;

             &lt;p&gt;
                &lt;li&gt;&lt;h2&gt;자기 소개&lt;/h2&gt;&lt;/li&gt;

            &lt;/p&gt;

            &lt;p&gt;
                &lt;li&gt;&lt;h2&gt;연락처&lt;/h2&gt;&lt;/li&gt;
                &lt;ul&gt;


                &lt;/ul&gt;
            &lt;/p&gt;


            &lt;p&gt;
                &lt;li&gt;&lt;h2&gt;관심 기술&lt;/h2&gt;&lt;/li&gt;
                &lt;ul&gt;

                &lt;/ul&gt;
            &lt;/p&gt;

            &lt;p&gt;
                &lt;li&gt;&lt;h2&gt;한 마디&lt;/h2&gt;&lt;/li&gt;

            &lt;/p&gt;

        &lt;/div2&gt;
    &lt;/body&gt;

&lt;/html&gt;</code></pre>
<ul>
<li>요약 하자면 앞서 말했듯 크게 두 박스로 나눠져있기에 div1,2로 구별해주고 
메인 항목들엔 h2 크기를 적용시켜 일반 텍스트와 구별되게 하였다.</li>
</ul>
<h3 id="2-1-이미지-삽입">2-1. 이미지 삽입</h3>
<p>자, 우선 바탕하면 <strong>&quot;WEB&quot;이라는 폴더 내부</strong>에 <strong>&quot;image&quot;라는 파일을 만들고
그 폴더 내부에 프로필 사진을 넣는다.</strong></p>
<p>굳이 경로를 강조한 이유는 image파일의 <strong>상대 경로</strong>를 이용할 것이기 때문이다. 파일의 깊이(?)에 따라</p>
<p>예시로
./이미지명.png
./../이미지명.png
./../../이미지명.png
.
.
이런 식으로 .. 개수를 늘려줘야 한다.
지금은 큰 폴더 내부의
이미지라는 폴더에서 정보를 가져오는 것이니 ./../ 을 쓰면 된다.
이미지 파일 명은 kiwi.webp이다. 
<del>프로필 사진이랄만한게 없어서 키위새 사진을 퍼왔다</del></p>
<p>여튼 이걸</p>
<pre><code class="language-html">&lt;img src =&quot;./../image/kiwi.webp&quot; width=&quot;250px&quot; height=&quot;250px&quot; &gt;</code></pre>
<p>이렇게 써서 알맞은 자리에 적절한 크기로 조절해서 만들어주면..
<img src="https://velog.velcdn.com/images/sloth_slys/post/952650cf-35ad-4f62-836b-a1d7f6a8e5df/image.png" alt="">
이리 귀여운 키위새가 나온다!
(글씨 색, 외곽선과 배경색은 밑에서 설명)</p>
<h3 id="2-2-메인-자기소개-카드">2-2. 메인 자기소개 카드</h3>
<ul>
<li>딱히 특별할 것 없이 똑같이 글씨를 써주고 하면된다
아. 다만 편의성으로 이메일을 클릭하면 이메일 웹페이지로 이동하게 링크를 넣어주는 작업을 하였다.<pre><code class="language-html">&lt;li&gt;Email: &lt;a href =&quot;https://mail.google.com&quot; target=&quot;_blank&quot; title=&quot;이메일 페이지로 이동&quot;&gt;이메일&lt;/a&gt;&lt;/li&gt;</code></pre>
요로코롬, 링크를 웹링크를 연결하고 새페이지로 열게끔 했다. 추가로 텍스트 설명도 붙이고</li>
</ul>
<p><del><em>href를 src로 헷갈려 써놓고 왜 안되냐며 궁시렁거리며 고치는 찐빠가 중간에 있었긴 했다</em></del></p>
<h3 id="3css">3.CSS</h3>
<p>우선 link에 썼던 것처럼 자기소개_패이지_디자인.css 파일을 만든다.
그리고 아까 미리 만든 div1, div2를 C언어의 클래스처럼(제미나이 피셜 공식명칭은 스타일 규칙이라 한다) 나눠준다</p>
<p>아래는 최종 결과물.</p>
<pre><code class="language-css">div1
{
 display: flex;
 flex-direction: column;
 width: 50%;
 height: 35%;
 border-radius: 10px;
 border: 3px solid gray;

}
div1:hover{
 transform: scale(1.1) translateY(-6px);


}

mini_name
{
    display: flex;
    justify-content: start;
}
/* 900 픽셀 정도로 */
div2{
 display: flex;
 flex-direction: column;
 width: 100%;
 height: 70%;
 border-radius: 10px;
 border: 3px solid gray;
}</code></pre>
<h3 id="3-1-박스-생성">3-1. 박스 생성</h3>
<p>위의 있는 코드박스에 적힌 것처럼 네모난 박스를 시각적으로 만들고 모서리를 둥글게 그러니까 즉 곡률을 주기 위해  border-radius: 10px; 를 적용시켰다</p>
<p>이는 수업에서 안 배웠기에 이제 처음으로 이번 과제를 하면서 인터넷 검색을 쓴 부분이기도 하다.</p>
<pre><code class="language-css">border: 3px solid gray; 는 3픽셀만큼의 회색 외곽선
(테스트해보니 solid도 작성해야 한다)
border-radius: 10px; 는 10만큼의 모서리 곡률

 width: 50%;
 height: 35%; 
 는 박스가 차지하는 웹페이지 상의 크기,
 픽셀로 하면 웹페이지 축소 때 
 글자 줄바꿈이 난리나는 등의 문제가 있어 비율로 해주었다.</code></pre>
<p>div2도 동일하게 해준다</p>
<p><del>px사이즈 맞추느라 고생해놓고 마지막에 그냥 비율로 사이즈를 맞춘 슬픈전설</del></p>
<h3 id="3-2-배경색폰트">3-2. 배경색,폰트</h3>
<p>이제 페이지 배경색을 맞출 차례이다. 
그동안 솔직히 배경색이 너무 하얘서 오래 보면 눈이 쨍해지는 느낌 때문에 불편했다.</p>
<p>참고로 이것또한 자습으로 알게 되었다.</p>
<p>우선 코드는</p>
<pre><code class="language-css"> background-color: rgba(128, 128, 128, 0.264);</code></pre>
<p>이렇다. 매우 간단하다.
뒤에는 rgb의 색. 0~256까지 있는 그거 맞다.
그리고 맨 뒤에 0.264는 이번에 색 찾다 보니 처음 알게 되었는데 투명도란다.</p>
<p>여튼 색을 일일히 다 치진 않고 vs스튜디오 코드 에만 있는지 모르겠는데
red같은 임의 색을 치면 옆에 박스가 떠서 색을 드래그로 조정할수 있었다.</p>
<p>그 외에도 뭔가 폰트가 좀 구린거 같아서 </p>
<pre><code class="language-css">body
{
    font-family: &#39;Lucida Sans&#39;, &#39;Lucida Sans Regular&#39;, &#39;Lucida Grande&#39;, &#39;Lucida Sans Unicode&#39;, Geneva, Verdana, sans-serif;
    background-color: rgba(128, 128, 128, 0.264);
    font-size: 24px;
}</code></pre>
<p>이렇게 루산다 산스? 체로 바꿔주고 
사이즈는 24픽셀로 하였다.</p>
<p>폰트또한 일일히 안치고 font-familly까지 입력하면 폰트 고르는 창이 뜬다.
그리고, 써보진 않았지만 외부에서 다운받고 파일을 연결해서 
기본적으론 없는 폰트도 적용시킬수 있는 듯 보인다.</p>
<h3 id="3-3-욕심">3-3. 욕심</h3>
<p>아까전에 한 마디라는 항목에 
목표는 풀스택 개발자 라고 적었다. 다만 심심한 느낌이 좀 들었는데
순간 머릿속을 지나쳐가는 광경이 하나 있어서 적용 시키기로 했다.</p>
<p>음..설명하자면 인터넷 게시글에 가끔 보이는 글자가 무지개색으로 되어있고 
폰트 사이즈는 들쭉날쭉인 그런 문장.</p>
<p>솔직히 말하자면 <strong>현 상태론</strong> 단순 반목 작업이다.
제미나이 한테 외주 작업 맡기다가 알게 된것인데 자바스크립트 배우면 뭐 반복문으로 
처리할 수 있다고는 한 것 같다.</p>
<p>요구사항은 아래와 같다. 폰트는 18부터 2씩 증가, 각글자의 색은 아래와 같이.</p>
<pre><code>&lt;!-- 빨 노 파 초 분 주 연 파 분 삘긴 !(폰트 2씩 증가)--&gt;</code></pre><pre><code class="language-html">&lt;li&gt;&lt;h2&gt;한 마디&lt;/h2&gt;&lt;/li&gt;
                &lt;li&gt;&lt;strong&gt;
                    &lt;dest_1&gt;목&lt;/dest_1&gt;
                    &lt;dest_2&gt;표&lt;/dest_2&gt;
                    &lt;dest_3&gt;는 &lt;/dest_3&gt;
                    &lt;dest_4&gt;풀&lt;/dest_4&gt;
                    &lt;dest_5&gt;스&lt;/dest_5&gt;
                    &lt;dest_6&gt;택 &lt;/dest_6&gt;
                    &lt;dest_7&gt;개&lt;/dest_7&gt;
                    &lt;dest_8&gt;발&lt;/dest_8&gt;
                    &lt;dest_9&gt;자&lt;/dest_9&gt;
                    &lt;dest_10&gt;!&lt;/dest_10&gt;&lt;/strong&gt;&lt;/li&gt;</code></pre>
<p>우선 html 한글자 한글자를 이리 나눠 준다.</p>
<p>그리고 제미나이한테 하청을 맡기기 위해</p>
<pre><code class="language-css">dest_1{

  color: red;
  font-size: 16px;

}</code></pre>
<p>이와 같이 기본판을 만들고 조건을 제시하면
10초안에 </p>
<pre><code>/* 반복 작업이라 제미나이 사용 */
dest_1{

  color: red;
  font-size: 16px;

}
/* 2. 표 (노랑) */
dest_2 { color: yellow; font-size: 18px; }

/* 3. 는 (파랑) */
dest_3 { color: blue; font-size: 20px; }

/* 4. 풀 (초록) */
dest_4 { color: green; font-size: 22px; }

/* 5. 스 (분홍/보라) */
dest_5 { color: pink; font-size: 24px; }

/* 6. 택 (주황) */
dest_6 { color: orange; font-size: 26px; }

/* 7. 개 (연두) */
dest_7 { color: lightgreen; font-size: 28px; }

/* 8. 발 (진파랑) */
dest_8 { color: darkblue; font-size: 30px; }

/* 9. 자 (분홍) */
dest_9 { color: hotpink; font-size: 32px; }

/* 10. ! (빨강) */
dest_10 { color: red; font-size: 34px; }</code></pre><p>이리 써준다. 
결과물은....<br><br><br><br><br></p>
<p><img src="https://velog.velcdn.com/images/sloth_slys/post/d7a9666a-c5f7-4619-8a07-04b1be93639d/image.png" alt="">
맘에 든다.</p>
<h3 id="4-박스-상승">4. 박스 상승</h3>
<p>이제 마지막으로 아까 추가 도전 과제 였던 6px 상승을 만들 차례이다.
처음에 기능만 따지고  보면 자바스크립트 인것 같아서 이게 추가 도전 과제라고? 라면서 당황 하긴 했다.</p>
<p>일단 검색한다.
그리고 결과물을 1페이지 만에 찾는다. 
<br></p>
<p>_솔직히 요즘에 구글에 사용자 입력에 따라 제일 상단에 ai답변이 나와서 검색 시간이 대폭 감소하긴 했다. </p>
<p>그래서 이걸 찾았다고 해야하는지 ai한테 물어봤다 해야하는지 
헷갈리기도 한다.</p>
<p>가끔은 제대로 안나와서 좀 더 찾기도 하지만._
<br><br>
여튼 코드는</p>
<pre><code class="language-css">div1:hover{
 transform: scale(1.1) translateY(-6px);

}</code></pre>
<p>이렇다.
트랜스 폼을 써주고 translateY(-6px)가 6픽셀 상승 기능을 한다.
스케일은 답변에 같이 나와서 이게 뭐지 하고 봤더니 말 그대로 1.1배로
사이즈를 확장하는 기능이다.</p>
<p>그리고 어려웠던 점이 몇가지 있었는데</p>
<p>첫 번째론, y축이 위에 쓰인것처럼 상승인데 마이너스로 쓰인 점이다.
이게 보니까 웹페이지 에선 통상적인(?) y축 방향이 반대 인것 
같았다.</p>
<p>두 번째가 까다로웠는데 <strong>:hover</strong> 이거다.
<strong>이걸 안써주면 박스가 웹페이지 열자마자 상승하면서 커진다.</strong>
그러니까 말하자면 일종의 마우스를 감지하는 <strong>트리거 역할</strong>이다.</p>
<p>솔직히, 이건 버그났을 때 작동도 잘되는데 그냥 바로 상승하고,커져서
&quot;뭐지 이거 원인이 뭐지.&quot; 이러면서 원인도 모르다가 
제미나이와의 대화로 알게 된 코드이다.</p>
<h1 id="어려웠던-점">어려웠던 점</h1>
<p>웬만하면 오타 같은 셀프트롤이어서 금방 찾고 고쳤지만,</p>
<p><strong>폰트 사이즈 맞추고, 배경색 고르는게 제일 고난</strong>이었던 것 같다.
둘다 뭐랄까.. 디자인적 경험치에 기반한 <strong>직감</strong> 같은 
것이기 때문에 시간이 지나면서
해결 될 문제임과 동시에 지금은 어쩔수 없는 문제로 보인다.</p>
<h1 id="새로-배우게-된-점-요약">새로 배우게 된 점 요약</h1>
<pre><code>font-family:  &gt; 폰트 지정,바디에 속해야 함
background-color:  &gt; 배경색 지정, 바디에 속해야 함
:hover  &gt; 마우스 감지 트리거
transform: scale, translateY  &gt; 각각 스케일 변경 및 y축 위치 변경(상승은 -부호!)

font-size: &gt; 폰트 사이즈 지정
border-radius: (곡률,px 단위); &gt; 박스 모서리의 곡률 지정
border: (외곽 두께) solid (색상);  &gt; 웹페이지 상에서 시각적으로 보이는 박스 생성</code></pre><p>대체적으로 body 태그(웹페이지 전체 대상) 내부를 건드리는 css코드나 
박스를 생성하는 기능을 배웠다고 할수 있는 것 같다.</p>
]]></description>
        </item>
    </channel>
</rss>