<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>jennet1 님의 블로그</title>
    <link>https://jennet1.tistory.com/</link>
    <description>jennet1 님의 블로그 입니다.</description>
    <language>ko</language>
    <pubDate>Sat, 15 Aug 2026 23:18:15 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>jennet1</managingEditor>
    <item>
      <title>React [ 셋팅 ]</title>
      <link>https://jennet1.tistory.com/31</link>
      <description>&lt;h2 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;1. 프로젝트 기본 스타일 정리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;✅ &lt;/span&gt;&lt;span&gt;App.css&lt;/span&gt;&lt;span&gt; 및 &lt;/span&gt;&lt;span&gt;index.css&lt;/span&gt;&lt;span&gt; &amp;rarr; &lt;/span&gt;&lt;span&gt;&lt;b&gt;기본 스타일 포함, 필요에 따라 수정 또는 삭제&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt; ✅ &lt;/span&gt;&lt;span&gt;&lt;b&gt;로고 필요 없으면 삭제&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;258&quot; data-origin-height=&quot;63&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8jy8P/btsM6BTdjkS/K3tBf9mx1mRog8xvnK54bK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8jy8P/btsM6BTdjkS/K3tBf9mx1mRog8xvnK54bK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8jy8P/btsM6BTdjkS/K3tBf9mx1mRog8xvnK54bK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8jy8P%2FbtsM6BTdjkS%2FK3tBf9mx1mRog8xvnK54bK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;258&quot; height=&quot;63&quot; data-origin-width=&quot;258&quot; data-origin-height=&quot;63&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;258&quot; data-origin-height=&quot;339&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJuIib/btsM8ueowQv/YtPw2cKk3uvxQfmclIe3D0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJuIib/btsM8ueowQv/YtPw2cKk3uvxQfmclIe3D0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJuIib/btsM8ueowQv/YtPw2cKk3uvxQfmclIe3D0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJuIib%2FbtsM8ueowQv%2FYtPw2cKk3uvxQfmclIe3D0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;258&quot; height=&quot;339&quot; data-origin-width=&quot;258&quot; data-origin-height=&quot;339&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;2. Tailwind CSS 설치&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;아래 명령어를 실행하여 Tailwind CSS 및 관련 패키지 설치&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743661587308&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install -D tailwindcss@3.4.17 postcss@8.4.31 autoprefixer@10.4.14&lt;/code&gt;&lt;/pre&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;설정 파일 생성 (Tailwind 및 PostCSS 초기화)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;&amp;nbsp;- &lt;/b&gt;&lt;/span&gt;&lt;span&gt;tailwind.config.js&lt;/span&gt;&lt;span&gt;와 &lt;/span&gt;&lt;span&gt;postcss.config.js&lt;/span&gt;&lt;span&gt; 파일이 생성&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1743661677088&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npx tailwindcss init -p&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;⚙️ &lt;/span&gt;&lt;span&gt;&lt;b&gt;3. Tailwind 설정 파일 수정&lt;/b&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;tailwind.config.js&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/h2&gt;
&lt;p data-pm-slice=&quot;1 3 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;주요 설정:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;content&lt;/span&gt;&lt;span&gt; 경로 수정하여 &lt;/span&gt;&lt;span&gt;&lt;b&gt;Tailwind가 적용될 파일&lt;/b&gt;&lt;/span&gt;&lt;span&gt; 지정&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;theme.extend&lt;/span&gt;&lt;span&gt;를 활용하여 &lt;/span&gt;&lt;span&gt;&lt;b&gt;추가적인 스타일 확장 가능&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1743661718628&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/** @type {import('tailwindcss').Config} */
export default {
  content: [
    &quot;./index.html&quot;,
    &quot;./src/**/*.{js,ts,jsx,tsx}&quot;,
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;4. 기본 스타일 적용&lt;/b&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;index.css&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/h2&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;Tailwind CSS의 기본 스타일을 불러오기 위해 아래 코드 추가&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1743661839692&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@tailwind base;
@tailwind components;
@tailwind utilities;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;Tailwind가 정상적으로 적용되었는지 확인하기 위해, &lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt;App.tsx&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt;에서 테스트 코드 추가&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1743663552759&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function App() {
  return (
    &amp;lt;div className=&quot;min-h-screen bg-gray-100 flex items-center justify-center&quot;&amp;gt;
      &amp;lt;div className=&quot;bg-white p-8 rounded-lg shadow-md&quot;&amp;gt;
        &amp;lt;h1 className=&quot;text-2xl font-bold text-gray-800&quot;&amp;gt;Hello Tailwind!&amp;lt;/h1&amp;gt;
        &amp;lt;p className=&quot;mt-2 text-gray-600&quot;&amp;gt;Welcome to your new React + Tailwind project&amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default App&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;5. TypeScript 설정&lt;/b&gt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;tsconfig.json&lt;/span&gt;&lt;span&gt; 수정)&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1743661955506&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    // TypeScript 컴파일러 옵션들
    &quot;target&quot;: &quot;ES2020&quot;,        // JavaScript 버전을 ES2020으로 지정
    &quot;lib&quot;: [&quot;ES2020&quot;, &quot;DOM&quot;, &quot;DOM.Iterable&quot;],  // 사용할 라이브러리 정의
    &quot;module&quot;: &quot;ESNext&quot;,        // 모듈 시스템을 ESNext로 지정
    &quot;jsx&quot;: &quot;react-jsx&quot;,        // React JSX 문법 지원
    &quot;strict&quot;: true,            // 엄격한 타입 체크 활성화
    &quot;baseUrl&quot;: &quot;.&quot;,            // 절대 경로 임포트의 기준점
    &quot;paths&quot;: {                 // 경로 별칭 설정
      &quot;@/*&quot;: [&quot;src/*&quot;]        // @/로 시작하는 임포트는 src/ 디렉토리에서 찾음
    }
  },
  &quot;include&quot;: [&quot;src&quot;],         // TypeScript가 처리할 파일들
  &quot;references&quot;: [{ &quot;path&quot;: &quot;./tsconfig.node.json&quot; }]  // tsconfig.node.json 참조
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;Node 환경 설정을 위한 &lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt;tsconfig.node.json&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt; 추가&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1743661972428&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;composite&quot;: true,         // 프로젝트 참조를 위한 설정
    &quot;module&quot;: &quot;ESNext&quot;,        // Node.js용 모듈 시스템
    &quot;moduleResolution&quot;: &quot;bundler&quot;,  // Vite와 같은 번들러 사용을 위한 설정
    &quot;allowSyntheticDefaultImports&quot;: true  // default export가 없는 모듈도 import 가능
  },
  &quot;include&quot;: [&quot;vite.config.ts&quot;]  // Vite 설정 파일만 포함
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;6. 서버&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt; 재시작 및 적용 확인&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1743663629313&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm run dev&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;353&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/da7iKC/btsM66Fqji9/TKj2zhlrKrhxKMBSBotwxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/da7iKC/btsM66Fqji9/TKj2zhlrKrhxKMBSBotwxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/da7iKC/btsM66Fqji9/TKj2zhlrKrhxKMBSBotwxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fda7iKC%2FbtsM66Fqji9%2FTKj2zhlrKrhxKMBSBotwxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;353&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;353&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>라이브러리/React</category>
      <author>jennet1</author>
      <guid isPermaLink="true">https://jennet1.tistory.com/31</guid>
      <comments>https://jennet1.tistory.com/31#entry31comment</comments>
      <pubDate>Thu, 3 Apr 2025 16:01:37 +0900</pubDate>
    </item>
    <item>
      <title>브랜치 작업하기</title>
      <link>https://jennet1.tistory.com/30</link>
      <description>&lt;h3 data-end=&quot;89&quot; data-start=&quot;67&quot; data-ke-size=&quot;size23&quot;&gt;1. &lt;b&gt;브랜치 생성 및 이동&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;130&quot; data-start=&quot;91&quot; data-ke-size=&quot;size16&quot;&gt;먼저 메인 브랜치에서 새로운 브랜치를 생성하고 그 브랜치로 이동합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;bash&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span data-state=&quot;closed&quot;&gt;복사&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;git checkout main &lt;span&gt;# 메인 브랜치로 이동 (현재 작업중인 브랜치가 메인이어야 합니다)&lt;/span&gt; git pull origin main &lt;span&gt;# 메인 브랜치를 최신 상태로 업데이트&lt;/span&gt; git checkout -b scroll-menu &lt;span&gt;# 새로운 브랜치 생성 후 이동&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;340&quot; data-start=&quot;316&quot; data-ke-size=&quot;size23&quot;&gt;2. &lt;b&gt;브랜치에서 개발 후 커밋&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;379&quot; data-start=&quot;342&quot; data-ke-size=&quot;size16&quot;&gt;새로 생성한 브랜치에서 개발 작업을 하고, 변경 사항을 커밋합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;bash&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span data-state=&quot;closed&quot;&gt;복사&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;# 변경된 파일을 스테이징&lt;/span&gt; git add . &lt;span&gt;# 모든 파일을 추가&lt;/span&gt; &lt;span&gt;# 또는 특정 파일만 추가&lt;/span&gt; &lt;span&gt;# git add &amp;lt;file-name&amp;gt;&lt;/span&gt; &lt;span&gt;# 커밋을 작성&lt;/span&gt; git commit -m &lt;span&gt;&quot;Add scroll menu feature&quot;&lt;/span&gt; &lt;span&gt;# 커밋 메시지 작성&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;569&quot; data-start=&quot;549&quot; data-ke-size=&quot;size23&quot;&gt;3. &lt;b&gt;로컬 브랜치 푸시&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;598&quot; data-start=&quot;571&quot; data-ke-size=&quot;size16&quot;&gt;로컬에서 작업한 내용을 원격 저장소에 푸시합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;bash&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span data-state=&quot;closed&quot;&gt;복사&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;git push origin scroll-menu &lt;span&gt;# scroll-menu 브랜치를 원격 저장소에 푸시&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;699&quot; data-start=&quot;673&quot; data-ke-size=&quot;size23&quot;&gt;4. &lt;b&gt;메인 브랜치로 이동 후 머지&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;743&quot; data-start=&quot;701&quot; data-ke-size=&quot;size16&quot;&gt;브랜치에서 작업이 완료되면 메인 브랜치로 돌아가서 해당 브랜치를 머지합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;bash&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span data-state=&quot;closed&quot;&gt;복사&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;git checkout main &lt;span&gt;# 메인 브랜치로 이동&lt;/span&gt; git pull origin main &lt;span&gt;# 메인 브랜치를 최신 상태로 업데이트&lt;/span&gt; git merge scroll-menu &lt;span&gt;# scroll-menu 브랜치를 메인 브랜치에 머지&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;941&quot; data-start=&quot;916&quot; data-ke-size=&quot;size23&quot;&gt;5. &lt;b&gt;머지 후 메인 브랜치 푸시&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;979&quot; data-start=&quot;943&quot; data-ke-size=&quot;size16&quot;&gt;메인 브랜치에서 머지 후, 변경 사항을 원격 저장소에 푸시합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;bash&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span data-state=&quot;closed&quot;&gt;복사&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;git push origin main &lt;span&gt;# 메인 브랜치에 푸시&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;1064&quot; data-start=&quot;1038&quot; data-ke-size=&quot;size23&quot;&gt;6. &lt;b&gt;브랜치 삭제 (로컬과 원격)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1100&quot; data-start=&quot;1066&quot; data-ke-size=&quot;size16&quot;&gt;작업이 끝난 후, 더 이상 필요하지 않은 브랜치를 삭제합니다.&lt;/p&gt;
&lt;h4 data-end=&quot;1117&quot; data-start=&quot;1102&quot; data-ke-size=&quot;size20&quot;&gt;로컬 브랜치 삭제:&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;bash&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span data-state=&quot;closed&quot;&gt;복사&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;git branch -d scroll-menu &lt;span&gt;# 로컬 브랜치 삭제 (병합된 브랜치만 삭제 가능)&lt;/span&gt; &lt;span&gt;# 병합되지 않은 브랜치를 강제로 삭제하려면 아래 명령어 사용&lt;/span&gt; &lt;span&gt;# git branch -D scroll-menu&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-end=&quot;1269&quot; data-start=&quot;1254&quot; data-ke-size=&quot;size20&quot;&gt;원격 브랜치 삭제:&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;bash&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span data-state=&quot;closed&quot;&gt;복사&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;git push origin --delete scroll-menu &lt;span&gt;# 원격 저장소에서 브랜치 삭제&lt;/span&gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1342&quot; data-start=&quot;1339&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1357&quot; data-start=&quot;1344&quot; data-ke-size=&quot;size23&quot;&gt;전체 흐름 요약:&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1749&quot; data-start=&quot;1359&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1383&quot; data-start=&quot;1359&quot;&gt;git checkout main&lt;/li&gt;
&lt;li data-end=&quot;1411&quot; data-start=&quot;1384&quot;&gt;git pull origin main&lt;/li&gt;
&lt;li data-end=&quot;1446&quot; data-start=&quot;1412&quot;&gt;git checkout -b scroll-menu&lt;/li&gt;
&lt;li data-end=&quot;1471&quot; data-start=&quot;1447&quot;&gt;개발 작업 후 git add .&lt;/li&gt;
&lt;li data-end=&quot;1510&quot; data-start=&quot;1472&quot;&gt;git commit -m &quot;Add scroll menu&quot;&lt;/li&gt;
&lt;li data-end=&quot;1545&quot; data-start=&quot;1511&quot;&gt;git push origin scroll-menu&lt;/li&gt;
&lt;li data-end=&quot;1570&quot; data-start=&quot;1546&quot;&gt;git checkout main&lt;/li&gt;
&lt;li data-end=&quot;1598&quot; data-start=&quot;1571&quot;&gt;git pull origin main&lt;/li&gt;
&lt;li data-end=&quot;1627&quot; data-start=&quot;1599&quot;&gt;git merge scroll-menu&lt;/li&gt;
&lt;li data-end=&quot;1656&quot; data-start=&quot;1628&quot;&gt;git push origin main&lt;/li&gt;
&lt;li data-end=&quot;1698&quot; data-start=&quot;1657&quot;&gt;git branch -d scroll-menu (로컬 삭제)&lt;/li&gt;
&lt;li data-end=&quot;1749&quot; data-start=&quot;1699&quot;&gt;git push origin --delete scroll-menu (원격 삭제)&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>GIT</category>
      <author>jennet1</author>
      <guid isPermaLink="true">https://jennet1.tistory.com/30</guid>
      <comments>https://jennet1.tistory.com/30#entry30comment</comments>
      <pubDate>Wed, 5 Mar 2025 22:36:59 +0900</pubDate>
    </item>
    <item>
      <title>React [ Vite]</title>
      <link>https://jennet1.tistory.com/29</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;React (CRA) vs. Vite 비교&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React를 개발할 때 일반적으로 create-react-app (CRA)과 Vite 두 가지 방식이 많이 사용됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 방법 모두 React 앱을 설정하지만 차이점이 존재&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 기본 개념&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 160px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.2093%; height: 20px;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%; height: 20px; text-align: center;&quot;&gt;Create React App (CRA)&lt;/td&gt;
&lt;td style=&quot;width: 40.1163%; height: 20px; text-align: center;&quot;&gt;Vite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.2093%; height: 20px;&quot;&gt;&lt;b&gt;개발 서버&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%; height: 20px;&quot;&gt;Webpack 기반의 개발 서버 사용&lt;/td&gt;
&lt;td style=&quot;width: 40.1163%; height: 20px;&quot;&gt;ES 모듈을 활용한 빠른 개발 서버&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.2093%; height: 20px;&quot;&gt;&lt;b&gt;번들러&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%; height: 20px;&quot;&gt;Webpack 사용&lt;/td&gt;
&lt;td style=&quot;width: 40.1163%; height: 20px;&quot;&gt;ESBuild (Go로 작성된 초고속 번들러) 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.2093%; height: 20px;&quot;&gt;&lt;b&gt;핫 리로딩 (HMR)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%; height: 20px;&quot;&gt;느림&lt;/td&gt;
&lt;td style=&quot;width: 40.1163%; height: 20px;&quot;&gt;매우 빠름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.2093%; height: 20px;&quot;&gt;&lt;b&gt;빌드 속도&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%; height: 20px;&quot;&gt;느림&lt;/td&gt;
&lt;td style=&quot;width: 40.1163%; height: 20px;&quot;&gt;빠름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.2093%; height: 20px;&quot;&gt;&lt;b&gt;환경설정&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%; height: 20px;&quot;&gt;자동 설정 (Webpack)&lt;/td&gt;
&lt;td style=&quot;width: 40.1163%; height: 20px;&quot;&gt;간단한 설정 (vite.config.js)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.2093%; height: 20px;&quot;&gt;&lt;b&gt;SSR 지원&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%; height: 20px;&quot;&gt;직접 설정 필요&lt;/td&gt;
&lt;td style=&quot;width: 40.1163%; height: 20px;&quot;&gt;기본적으로 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.2093%; height: 20px;&quot;&gt;&lt;b&gt;추천 상황&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 40.2326%; height: 20px;&quot;&gt;기존 CRA 프로젝트 유지, 익숙한 방식 선호&lt;/td&gt;
&lt;td style=&quot;width: 40.1163%; height: 20px;&quot;&gt;최신 React 개발, 빠른 빌드 속도 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 설치방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; (1) CRA로 설치 &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1738818967823&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;npx create-react-app my-app
cd my-app
npm start&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; (2) Vite로 설치 &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1738819029291&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm create vite@latest my-app --template react
cd my-app
npm install
npm run dev&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 어떤 방식을 선택할까?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;CRA를 선택할 경우&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 프로젝트가 CRA로 되어 있다면 유지하는 것이 좋음.&lt;/li&gt;
&lt;li&gt;Webpack 설정을 커스텀할 필요가 있을 경우.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;Vite를 선택할 경우&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;빠른 개발 속도와 빌드 속도를 원한다면 Vite를 선택하는 것이 유리.&lt;/li&gt;
&lt;li&gt;최신 React 프로젝트를 시작한다면 Vite가 훨씬 빠르고 효율적.&lt;/li&gt;
&lt;li&gt;서버 사이드 렌더링(SSR) 및 코드 분할을 고려한다면 Vite가 더 유리.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>라이브러리/React</category>
      <author>jennet1</author>
      <guid isPermaLink="true">https://jennet1.tistory.com/29</guid>
      <comments>https://jennet1.tistory.com/29#entry29comment</comments>
      <pubDate>Thu, 6 Feb 2025 14:17:53 +0900</pubDate>
    </item>
    <item>
      <title>React [ 컴포넌트 ]</title>
      <link>https://jennet1.tistory.com/27</link>
      <description>&lt;h1 data-pm-slice=&quot;1 1 []&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;리액트&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 컴포넌트란?&lt;/span&gt;&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;리액트(React)는 사용자 인터페이스(UI)를 구성하기 위해 컴포넌트(Component) 라는 개념을 사용합니다. 컴포넌트는 재사용 가능한 코드 조각으로 UI를 독립적이고 작은 단위로 나누어 관리할 수 있게 합니다. 이로 인해 유지보수성과 가독성이 높아지며 코드 재사용이 용이해집니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-pm-slice=&quot;1 3 []&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;컴포넌트의 기본 개념&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;독립성: 컴포넌트는 서로 독립적으로 동작하며 다른 컴포넌트와 결합하여 UI를 구성한다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;재사용성: 한 번 작성한 컴포넌트를 다양한 곳에서 재사용할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;구조화: UI를 계층적으로 구조화하여 개발 및 유지보수를 용이하게 한다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-pm-slice=&quot;3 3 []&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;함수형 컴포넌트(Function Component)&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클래스형 컴포넌트(Class Component)&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 data-pm-slice=&quot;1 1 []&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;리액트 파일 구조&lt;/span&gt;&lt;/b&gt;&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-pm-slice=&quot;3 3 []&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;/components: 컴포넌트 파일들을 모아 두는 폴더입니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;App.js: 애플리케이션의 루트 컴포넌트입니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;index.js: 리액트 애플리케이션의 진입점(entry point)으로 App 컴포넌트를 브라우저에 렌더링합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1736096198365&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/src
  |-- /components
  |     |-- Header.js
  |     |-- Footer.js
  |     |-- World.js
  |
  |-- App.js
  |-- index.js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-pm-slice=&quot;1 1 []&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;함수형 컴포넌트 [ 자주씀 ]&lt;/span&gt;&lt;/b&gt;&lt;/h1&gt;
&lt;p data-pm-slice=&quot;1 1 [&amp;quot;list&amp;quot;,{&amp;quot;spread&amp;quot;:false,&amp;quot;start&amp;quot;:865,&amp;quot;end&amp;quot;:957},&amp;quot;regular_list_item&amp;quot;,{&amp;quot;start&amp;quot;:889,&amp;quot;end&amp;quot;:957}]&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;더 간결하며 React Hooks를 사용하여 상태(state)와 생명주기(lifecycle)를 관리할 수 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 [&amp;quot;list&amp;quot;,{&amp;quot;spread&amp;quot;:false,&amp;quot;start&amp;quot;:865,&amp;quot;end&amp;quot;:957},&amp;quot;regular_list_item&amp;quot;,{&amp;quot;start&amp;quot;:889,&amp;quot;end&amp;quot;:957}]&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;단축 : rfc&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1736096283970&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';

function Header() {
  return (
    &amp;lt;header&amp;gt;
      &amp;lt;h1&amp;gt;Welcome to My Website&amp;lt;/h1&amp;gt;
    &amp;lt;/header&amp;gt;
  );
}

export default Header;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-pm-slice=&quot;3 3 []&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;function 키워드로 컴포넌트를 정의합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;return문 안에서 JSX(JavaScript XML)를 사용하여 UI를 정의합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;export default를 통해 다른 파일에서 이 컴포넌트를 사용할 수 있습니다&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 data-pm-slice=&quot;1 1 []&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클래스형 컴포넌트&lt;/span&gt;&lt;/b&gt;&lt;/h1&gt;
&lt;p data-pm-slice=&quot;1 1 [&amp;quot;list&amp;quot;,{&amp;quot;spread&amp;quot;:false,&amp;quot;start&amp;quot;:1314,&amp;quot;end&amp;quot;:1416},&amp;quot;regular_list_item&amp;quot;,{&amp;quot;start&amp;quot;:1362,&amp;quot;end&amp;quot;:1416}]&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;상태(state)와 생명주기 메서드(lifecycle methods)를 기본적으로 포함합니다&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 [&amp;quot;list&amp;quot;,{&amp;quot;spread&amp;quot;:false,&amp;quot;start&amp;quot;:1314,&amp;quot;end&amp;quot;:1416},&amp;quot;regular_list_item&amp;quot;,{&amp;quot;start&amp;quot;:1362,&amp;quot;end&amp;quot;:1416}]&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;단축&amp;nbsp; : rcc&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1736096379594&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { Component } from 'react';

class Footer extends Component {
  render() {
    return (
      &amp;lt;footer&amp;gt;
        &amp;lt;p&amp;gt;Copyright 2025, All Rights Reserved&amp;lt;/p&amp;gt;
      &amp;lt;/footer&amp;gt;
    );
  }
}

export default Footer;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-pm-slice=&quot;1 3 []&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;주요 포인트&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Component 클래스를 상속받아 정의합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;render() 메서드 안에서 JSX를 반환합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;컴포넌트 만들기&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;폴더 구조&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1736096591565&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/src
  |-- /components
  |     |-- Header.js
  |     |-- Welcome.js
  |     |-- World.js
  |
  |-- App.js
  |-- index.js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;App.js&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1736095669252&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import './App.css';
import Hello from './component/Hello';
import Welcome from './component/Welcome';

function App() {
  return (
    &amp;lt;div className=&quot;App&quot;&amp;gt;
      &amp;lt;Hello /&amp;gt;
      &amp;lt;Welcome /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;component/World&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1736095679204&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export default function world() {
  return &amp;lt;h3&amp;gt;World&amp;lt;/h3&amp;gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; component/Welcome&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1736095686200&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export default function Welcome() {
    return &amp;lt;p&amp;gt;Welcome&amp;lt;/p&amp;gt;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; component/Hello&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1736095692740&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// const Hello = () =&amp;gt; {
//     &amp;lt;p&amp;gt;Hello&amp;lt;/p&amp;gt;
// };
import World from './World';

export default function Hello() {
   return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;hello&amp;lt;/h1&amp;gt;
      &amp;lt;World/&amp;gt;
    &amp;lt;/div&amp;gt;

   );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/opfD0/btsLEMBqooc/7JkkxlWdcBjDmpwigN5Hr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/opfD0/btsLEMBqooc/7JkkxlWdcBjDmpwigN5Hr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/opfD0/btsLEMBqooc/7JkkxlWdcBjDmpwigN5Hr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FopfD0%2FbtsLEMBqooc%2F7JkkxlWdcBjDmpwigN5Hr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;727&quot; height=&quot;234&quot; data-origin-width=&quot;727&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;862&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rBOgM/btsLEhVYth0/i0Vma4AhDgBwyaQpBji6S1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rBOgM/btsLEhVYth0/i0Vma4AhDgBwyaQpBji6S1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rBOgM/btsLEhVYth0/i0Vma4AhDgBwyaQpBji6S1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrBOgM%2FbtsLEhVYth0%2Fi0Vma4AhDgBwyaQpBji6S1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;862&quot; height=&quot;567&quot; data-origin-width=&quot;862&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>라이브러리/React</category>
      <author>jennet1</author>
      <guid isPermaLink="true">https://jennet1.tistory.com/27</guid>
      <comments>https://jennet1.tistory.com/27#entry27comment</comments>
      <pubDate>Mon, 6 Jan 2025 02:16:18 +0900</pubDate>
    </item>
    <item>
      <title>문자열 다루기</title>
      <link>https://jennet1.tistory.com/26</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 1. 문자열 길이 구하기 &lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735610601126&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package Pool;

public class ch01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		// 문자열 길이 
		String str = &quot;Hello world&quot;;
		System.out.println(str.length());
		
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735610614842&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;11&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 문자열 비교 (같은지 다른지)&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;equals() : 두 문자열이 정확히 동일한지 비교&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;equalsIgnoreCase() : 대소문자 구분 없이 비교&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1735610790705&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package Pool;

public class ch01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str1 = &quot;Hello&quot;;
		String str2 = &quot;hello&quot;;
		
		System.out.println(str1.equals(str2)); // 두 문자가 정확히 동일한지 
		System.out.println(str1.equalsIgnoreCase(str2)); // 대소문자 없이 비교
		
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735610802300&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;false
true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3. 부분 문자열 추출 (Substring) &lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735611195617&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package Pool;

public class ch01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 문자열 추출하기
		String str = &quot;Hello World&quot;;
		String subStr = str.substring(7); // 7번째 부터 끝까지
		System.out.println(subStr);
		
		String subStr2 = str.substring(0,5); // 0 부터 5까지
		System.out.println(subStr2);	
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735611242049&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;orld
Hello&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;4. 문자열 검색 (찾기)&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735611419949&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package Pool;

public class ch01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str = &quot;Hello World&quot;;
		
        System.out.println(str.indexOf(&quot;o&quot;));      // 4 (첫 번째 o의 위치)
        System.out.println(str.lastIndexOf(&quot;o&quot;));  // 8 (마지막 o의 위치)
        System.out.println(str.contains(&quot;World&quot;)); // true (포함됨)
        System.out.println(str.contains(&quot;level&quot;));   // false
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735611451779&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;4
7
true
false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;5. 모든 문자열 대소문자로 변환&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735611518305&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package Pool;

public class ch01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str = &quot;Hello World&quot;;
		
        System.out.println(str.toLowerCase());  // hello, world!
        System.out.println(str.toUpperCase());  // HELLO, WORLD!
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735611573249&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;hello world
HELLO WORLD&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;6. 문자열 빈값 확인&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735871851151&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package pratic01;

public class Main5 {
	
	public static void main(String[] args) {
		String str = &quot;&quot;;
		System.out.println(str.isEmpty());
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735871949766&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;true&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;6. 특정 인덱스 문자 반환&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735871929037&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package pratic01;

public class Main5 {
	
	public static void main(String[] args) {
		String str = &quot;Hello&quot;;
		System.out.println(str.charAt(2));
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735871995937&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;l&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;7. 문자열 바꾸기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735872124621&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package pratic01;

public class Main5 {
	
	public static void main(String[] args) {
		String str = &quot;Hello, World!&quot;;
		System.out.println(str.replace('o', 'a'));  // 출력: &quot;Hella, Warld!&quot;
		System.out.println(str.replace(&quot;World&quot;, &quot;Java&quot;)); // 출력: &quot;Hello, Java!&quot;
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735872142381&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Hella, Warld!
Hello, Java!&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;7. 문자열 분리&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735874429920&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package pratic01;

public class Main5 {
	
	public static void main(String[] args) {
		String str = &quot;Apple,Banana,Cherry&quot;;
		String[] fruits = str.split(&quot;,&quot;);
		for (String fruit : fruits) {
		    System.out.println(fruit);
		}
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735874476923&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Apple
Banana
Cherry&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;8. 문자열 결합&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735874533704&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package pratic01;

public class Main5 {

	public static void main(String[] args) {
		String[] fruits = { &quot;Apple&quot;, &quot;Banana&quot;, &quot;Cherry&quot; };
		String result = String.join(&quot;, &quot;, fruits);
		System.out.println(result); // 출력: &quot;Apple, Banana, Cherry&quot;
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735874561406&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Apple, Banana, Cherry&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;8. 문자열 배열로 변환&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735874606222&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package pratic01;

public class Main5 {

	public static void main(String[] args) {
		String str = &quot;Hello&quot;;
		char[] chars = str.toCharArray();
		for (char c : chars) {
		    System.out.print(c + &quot; &quot;); // 출력: H e l l o
		}
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735874632408&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;H e l l o&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>WEB/JAVA</category>
      <author>jennet1</author>
      <guid isPermaLink="true">https://jennet1.tistory.com/26</guid>
      <comments>https://jennet1.tistory.com/26#entry26comment</comments>
      <pubDate>Fri, 3 Jan 2025 12:25:56 +0900</pubDate>
    </item>
    <item>
      <title>TeamMatch 프로젝트 문제해결 3[ 세션과 쿠키 ]</title>
      <link>https://jennet1.tistory.com/25</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 문제 상황&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배포 환경에서 세션 관리와 쿠키 설정에 대한 문제로 어려움을 겪었습니다. 로컬에서 개발할 때는 같은 도메인에서 HTTP로 통신을 하여 문제가 없었지만 https 배포 후 문제가 발생했습니다. 로그인 후 세션 값이 덮어지는 현상과 쿠키가 제대로 저장되지 않는 문제로 인해 며칠간 고생했습니다. 이 문제를 해결하는 과정에서 세션 관리와 쿠키 설정에 대한 더 깊은 이해를 얻을 수 있었습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서버쪽 use 설정&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1735470202813&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 세션 설정
app.use(
  session({
    secret: process.env.SESSION_SECRET, // 세션 암호화 키
    resave: true,
    saveUninitialized: false,
    cookie: {
      httpOnly: true,
      sameSite: &quot;None&quot;,
      // secure: true, // 개발 중에는 false로 설정 (HTTPS에서만 true)
      secure: true, // 개발 중에는 false로 설정 (HTTPS에서만 true)
      maxAge: 60 * 60 * 1000, // 세션 만료 1시간
    },
  })
);&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 배포 과정&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;리액트: &lt;a&gt;https://www.netlify.com/에&lt;/a&gt; 배포.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;노드 서버: AWS EC2 인스턴스에 배포.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;두 도메인이 달라서 크로스 도메인 설정과 CORS 설정을 했고 https 통신을 적용하기 위해 SSL 설정을 진행했습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;두 클라이언트와 서버 간의 https 통신이 완료되었지만 세션과 관련된 문제는 계속 발생했습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3. 문제 발생&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;로그인 후 사용자의 세션 값이 계속 덮어지는 문제가 발생했습니다. API 호출이 제대로 처리되지 않았고 쿠키가 저장되지 않는 문제를 발견했습니다. 이를 해결하기 위해 다양한 방법을 시도했습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;4. 나의 시도&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;크로스 도메인 설정: CORS 설정에서 origin 값을 내 클라이언트 도메인으로 수정했지만 문제가 해결되지 않았습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서버와 클라이언트 도메인 차이: 클라이언트와 서버의 도메인이 다르다는 사실이 문제의 원인일 수 있겠다고 생각했지만, 크로스 도메인 설정을 맞춰서 진행한 코드와 동일한 설정을 적용했음에도 불구하고 문제는 지속되었습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EC2 인스턴스에서 리액트와 노드를 같이 배포: 두 도메인이 동일한 인스턴스 내에서 작동하도록 배포를 변경했지만 여전히 문제가 해결되지 않았습니다.&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1735470068876&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// CORS 설정
app.use(
  cors({
    origin: origin, // 요청을 허용할 클라이언트 도메인
    credentials: true,
    methods: [&quot;GET&quot;, &quot;POST&quot;, &quot;UPDATE&quot;, &quot;PATCH&quot;], // 허용할 HTTP 메서드
  })
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;추가 시도:&lt;span&gt;&amp;nbsp;&lt;/span&gt;nginx 설정&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;nginx 설정: nginx에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;크로스 도메인 관련 헤더 설정을 추가했으나, 여전히 문제가 해결되지 않았습니다. 이를 통해,&lt;span&gt;&amp;nbsp;&lt;/span&gt;nginx에서 설정을 변경하는 것만으로는 세션 문제를 해결할 수 없다는 것을 알게 되었습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;561&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lZZYx/btsLCnVhzTb/9rm5nTVNNeXSKuX4G3cceK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lZZYx/btsLCnVhzTb/9rm5nTVNNeXSKuX4G3cceK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lZZYx/btsLCnVhzTb/9rm5nTVNNeXSKuX4G3cceK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlZZYx%2FbtsLCnVhzTb%2F9rm5nTVNNeXSKuX4G3cceK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1048&quot; height=&quot;561&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;561&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;5. 진행 중 절망적인 상황&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배포 후 3일이 지난 시점에서 도메인 설정이나 https 설정 자체가 문제였을까 고민했으며 도메인을 사용한 배포가 잘못된 선택이었을지 의문을 가졌습니다. 결국 배포를 포기할까 생각하였습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;6.&lt;span&gt;&amp;nbsp;&lt;/span&gt;해결의 실마리&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;로컬 환경에서 테스트를 진행하면서&lt;span&gt;&amp;nbsp;&lt;/span&gt;세션과 쿠키가 제대로 작동하는 것을 확인한 후 로컬에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;http 통신 설정을 그대로 서버에 적용해봤습니다. 서버에서 pull을 받고 실행했더니 배포한 서버에서 세션과 쿠키가&lt;span&gt;&amp;nbsp;&lt;/span&gt;정상적으로 작동하는 것을 확인했습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클라이언트 use 설정&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1735470112716&quot; class=&quot;yaml&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// 세션 설정
app.use(
  session({
    secret: process.env.SESSION_SECRET, // 세션 암호화 키
    resave: true,
    saveUninitialized: false,
    cookie: {
      httpOnly: true,
      sameSite: &quot;Lax&quot;,
      // secure: true, // 개발 중에는 false로 설정 (HTTPS에서만 true)
      secure: false, // 개발 중에는 false로 설정 (HTTPS에서만 true)
      maxAge: 60 * 60 * 1000, // 세션 만료 1시간
    },
  })
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;7. 설정 차이&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배포한 서버는 https 통신을 사용하고 있었기 때문에 secure 옵션을 true로 설정한 상태에서 문제를 해결하고자 했습니다. 그러나 로컬에서는 http 통신을 사용하고 있기 때문에 secure를 false로 설정하고 배포했던 설정이 달랐지만 같은 설정을 통해 문제를 해결하였습니다. 로컬과 배포환경&amp;nbsp; &lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;secure&lt;/span&gt;&lt;/b&gt;&amp;nbsp; false 로 설정함.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;8. 이유 불분명&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;현재로서는 정확한 이유를 파악하기 어렵습니다. 하지만 이 과정에서 https 설정과 관련된 세션 및 쿠키 관리의 중요성을 다시 한 번 인식하게 되었습니다. secure 값을 false 로 바꾸니 원래 로컬에서 처럼 정확하게 되었던게 세션과 관련된 개발과정이 조금 미숙했던점 그리고 로컬에서도 이점을 신경쓰지않고 개발했던점이 원인이 아닐까 생각합니다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;결론&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;세션과 쿠키 관리는 http와 https 간의 설정 차이로 인해 문제가 발생할 수 있습니다. 배포 환경에서 https 통신을 사용하고 있을 때, **secure: true**로 설정해주어야 쿠키가 정상적으로 동작합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;하지만 제프로젝트에서는 false 로 설정해야 동작합니다. 이거에 대한 원인은 아직까지 파악하지 못함&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;CORS 설정 및 크로스 도메인 처리는 중요하지만, 이 문제에서처럼 세션 관리와 쿠키 설정이 더 중요한 핵심 요소일 수 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;향후 로그인 관련 프로젝트에서는 세션과 쿠키 관리 방식을 다양하게 테스트하고 배포 환경에서의 통신 방식에 맞는 설정을 점검할 필요가 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;교훈&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;로컬과 배포 환경에서의 설정 차이를 면밀히 확인해야 합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;https에서 secure: true 설정을 반드시 적용해야 하며, 로컬에서는 http로 테스트를 진행할 때는 secure: false를 설정해야 합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;세션과 쿠키 문제는 단순히 CORS 설정만으로 해결되지 않으며 보안 설정이 중요한 역할을 한다는 점을 배웠습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;추가적으로 nginx나 서버 설정이 아닌 세션 및 쿠키 설정에서의 환경 차이가 문제의 원인이었음을 깨달았습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발 프로젝트/LOL-TEAM-MATCH</category>
      <author>jennet1</author>
      <guid isPermaLink="true">https://jennet1.tistory.com/25</guid>
      <comments>https://jennet1.tistory.com/25#entry25comment</comments>
      <pubDate>Sun, 29 Dec 2024 20:11:42 +0900</pubDate>
    </item>
    <item>
      <title>TeamMatch 프로젝트 문제해결 2[ 소셜로그인 ]</title>
      <link>https://jennet1.tistory.com/24</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제 해결 과정: API 토큰을 받아오지 못한 문제&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제 설명&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클라이언트에서 카카오 로그인 API 요청을 보냈지만 서버에서 토큰 값을 받아오지 못하는 문제가 발생했습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;해결 전:&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1735468330537&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;클라이언트에서 요청한 URI: http://localHost:8000/user/kakao/login&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;해결 후:&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1735468339671&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;클라이언트에서 요청한 URI를 http://127.0.0.1:8000/user/kakao/login으로 변경&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;원인 분석&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클라이언트와 서버 간의 주소 불일치&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;localHost와 127.0.0.1은 동일한 주소를 가리키는 것으로 보일 수 있지만&amp;nbsp; 실제론 다른 주소를 가르키는 것이었다.&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;localHost: 로컬호스트 주소는 DNS 설정에 따라 다르게 해석될 수 있고 가끔은 크로스 도메인 요청(CORS) 문제나 보안 설정에 영향을 미칠 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;따라서, 클라이언트와 서버의 요청 주소가 동일하지 않으면 CORS 설정 또는 서버가 잘못된 도메인으로 요청을 처리하려고 할 수 있습니다. 이로 인해 토큰 값을 올바르게 받아오지 못한 것입니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;해결 방법&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클라이언트와 서버의 요청 주소를 일치시켜야 합니다. 이를 통해 서버가 클라이언트의 요청을 정확히 인식하고 올바르게 응답할 수 있도록 합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;추가적인 고려 사항:&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;CORS 설정 확인: 로컬 환경에서 작업 시 클라이언트와 서버의 주소가 다르면 CORS 오류가 발생할 수 있습니다. 127.0.0.1로 설정을 일치시키면 이 문제를 방지할 수 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서버와 클라이언트 주소 일치: 프로젝트에서 다른 주소를 사용할 경우, 서버와 클라이언트 모두 동일한 주소를 사용하도록 설정하는 것이 중요합니다. 이를 통해 일관된 환경에서 API 호출을 할 수 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;결론&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클라이언트와 서버의 요청 주소가 일치하지 않으면 토큰 값을 받아올 수 없습니다. 따라서, 클라이언트와 서버에서 동일한 주소를 사용하도록 설정하여 문제를 해결했습니다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;http://127.0.0.1:8000/user/kakao/login&quot;&gt;http://127.0.0.1:8000/user/kakao/login&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v3zlw/btsLB3W2NhF/dJag0sJk3nMVogA5PBm331/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v3zlw/btsLB3W2NhF/dJag0sJk3nMVogA5PBm331/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v3zlw/btsLB3W2NhF/dJag0sJk3nMVogA5PBm331/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv3zlw%2FbtsLB3W2NhF%2FdJag0sJk3nMVogA5PBm331%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;799&quot; height=&quot;91&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발 프로젝트/LOL-TEAM-MATCH</category>
      <author>jennet1</author>
      <guid isPermaLink="true">https://jennet1.tistory.com/24</guid>
      <comments>https://jennet1.tistory.com/24#entry24comment</comments>
      <pubDate>Sun, 29 Dec 2024 19:32:41 +0900</pubDate>
    </item>
    <item>
      <title>TeamMatch 프로젝트 문제해결 1[ 밸런스 알고리즘 ]</title>
      <link>https://jennet1.tistory.com/23</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;밸런스 알고리즘 구현해보기&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;해당 프로젝트는 리그 오브 레전드 에서 팀 밸런스를 맞추기 위한 알고리즘을 구현한 것입니다. 이 게임에서는 각 팀에 특정 &lt;b&gt;포지션&lt;/b&gt;(탑, 정글, 미드, 원딜, 서폿)이 존재하며 플레이어의 &lt;b&gt;랭크 점수(RankScore)&lt;/b&gt; 를 기준으로 두 팀을 최대한 균등하게 나누는 것이 중요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;밸런스를 맞추기 위해 다음 요소들을 고려했습니다:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;포지션 균형&lt;/b&gt;: 각 팀에 모든 포지션이 골고루 배치되도록 함.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;점수 차 최소화&lt;/b&gt;: 두 팀 간의 총 점수 차이를 최소화하여 게임 밸런스를 유지.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;랜덤성과 공정성&lt;/b&gt;: 플레이어를 랜덤으로 섞어 배정 과정에서의 편향성을 줄임&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;랭크?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;&lt;b&gt;해당 게임에는 총&lt;span style=&quot;color: #006dd7;&quot;&gt; 10단계의 랭크&lt;/span&gt; 시스템이 존재한다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;각 랭크는 단계별로 구성되며&lt;span style=&quot;color: #006dd7;&quot;&gt; 4단계 부터 1단계&lt;/span&gt; 까지 존재한다. 예를들어 아이언1단계에서 특정 LP 조건을 만족하면 다음 단계인 브론즈 4단계 티어로 승급하는 시스템을 갖추고 있다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;팀프로젝트 때 얘기가 나온건 각 랭크별로 우리만의 알고리즘을 통해 랭크별로 점수를 부여하였다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wkCuT/btsLzDF3ogz/csb0ihhebtfqwn5Ixlsdmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wkCuT/btsLzDF3ogz/csb0ihhebtfqwn5Ixlsdmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wkCuT/btsLzDF3ogz/csb0ihhebtfqwn5Ixlsdmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwkCuT%2FbtsLzDF3ogz%2Fcsb0ihhebtfqwn5Ixlsdmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;372&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;밸런스 알고리즘을 구현하기 위해 엑셀로 각 티어단계별 점수를 임의적으로 적용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;965&quot; data-origin-height=&quot;464&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0BKTu/btsLBtBVsZ8/rNBSUdvA58HdFeudrGeEa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0BKTu/btsLBtBVsZ8/rNBSUdvA58HdFeudrGeEa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0BKTu/btsLBtBVsZ8/rNBSUdvA58HdFeudrGeEa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0BKTu%2FbtsLBtBVsZ8%2FrNBSUdvA58HdFeudrGeEa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;965&quot; height=&quot;464&quot; data-origin-width=&quot;965&quot; data-origin-height=&quot;464&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;라인?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;&lt;b&gt;탑/정글/미드/원딜/서폿 총 5개의 라인이 존재하며 포지션별로 각자의 역할과 수행목표가 존재함&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;게임에서의 포지션 중요성은 티어가 높은 유저일수록 정글의 실력이 크면 게임이 초반에 무너질 가능성이 존재&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;해당 포지션별 중요도를 정하고 각 특정 포지션의 경우 가중치 점수를 적용하였습니다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt; &lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #333333; text-align: start;&quot;&gt;다이아티어 4단계 유저가 탑일경우 34 + 3 이라는 점수를 부여받아서 총 해당 유저의 점수는 37점이 되게 된다.&lt;/span&gt; &lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K78Ux/btsLA9czPNr/ldJSZ1kfC2xLruZfV5umMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K78Ux/btsLA9czPNr/ldJSZ1kfC2xLruZfV5umMk/img.png&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;425&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;44.41&quot; style=&quot;width: 43.8909%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K78Ux/btsLA9czPNr/ldJSZ1kfC2xLruZfV5umMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK78Ux%2FbtsLA9czPNr%2FldJSZ1kfC2xLruZfV5umMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi6a9n/btsLzpnei5V/beFftM0VmGc6kWN44ixU4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi6a9n/btsLzpnei5V/beFftM0VmGc6kWN44ixU4k/img.png&quot; data-origin-width=&quot;289&quot; data-origin-height=&quot;168&quot; data-is-animation=&quot;false&quot; style=&quot;width: 54.9463%;&quot; data-widthpercent=&quot;55.59&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi6a9n/btsLzpnei5V/beFftM0VmGc6kWN44ixU4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi6a9n%2FbtsLzpnei5V%2FbeFftM0VmGc6kWN44ixU4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;289&quot; height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;데이터 전달&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프론트는 포지션과 팀원을 10명을 배치하여 서버쪽으로 다음과 같이 데이터를 넘겨주도록 하였다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1735463117916&quot; class=&quot;json&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;{
  &quot;mode&quot;: &quot;blance&quot;,
  &quot;players&quot;: [
    { &quot;id&quot;: 1, &quot;gameName&quot;: &quot;test1&quot;, &quot;RankScore&quot;: 10, &quot;position&quot;: &quot;top&quot; },
    { &quot;id&quot;: 2, &quot;gameName&quot;: &quot;test2&quot;, &quot;RankScore&quot;: 15, &quot;position&quot;: &quot;top&quot; },
    { &quot;id&quot;: 3, &quot;gameName&quot;: &quot;test3&quot;, &quot;RankScore&quot;: 20, &quot;position&quot;: &quot;jug&quot; },
    { &quot;id&quot;: 4, &quot;gameName&quot;: &quot;test4&quot;, &quot;RankScore&quot;: 18, &quot;position&quot;: &quot;jug&quot; },
    { &quot;id&quot;: 5, &quot;gameName&quot;: &quot;test5&quot;, &quot;RankScore&quot;: 12, &quot;position&quot;: &quot;mid&quot; },
    { &quot;id&quot;: 6, &quot;gameName&quot;: &quot;test6&quot;, &quot;RankScore&quot;: 22, &quot;position&quot;: &quot;mid&quot; },
    { &quot;id&quot;: 7, &quot;gameName&quot;: &quot;test7&quot;, &quot;RankScore&quot;: 14, &quot;position&quot;: &quot;ad&quot; },
    { &quot;id&quot;: 8, &quot;gameName&quot;: &quot;test8&quot;, &quot;RankScore&quot;: 17, &quot;position&quot;: &quot;ad&quot; },
    { &quot;id&quot;: 9, &quot;gameName&quot;: &quot;test9&quot;, &quot;RankScore&quot;: 13, &quot;position&quot;: &quot;sup&quot; },
    { &quot;id&quot;: 10, &quot;gameName&quot;: &quot;test10&quot;, &quot;RankScore&quot;: 19, &quot;position&quot;: &quot;sup&quot; }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제: 플레이어 데이터를 기반으로 팀을 구성하려 할 때, 각 팀에 동일한 포지션이 2개 이상 들어가면 안 된다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;조건:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;10명의 플레이어 데이터를 기준으로 팀을 5명씩 나눈다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;각 팀에는 탑, 정글, 미드, 원딜, 서폿 포지션이 1개씩만 존재해야 한다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;제약 사항: 포지션이 중복될 경우, 팀의 밸런스가 깨질 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;해결 방법에 대한 고민&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;첫 번째 고민: 무작위로 나누는 방식은 포지션 중복을 방지하기 어려움.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;두 번째 고민: 데이터를 포지션별로 그룹화하여, 각 팀에 1명씩 배치하면 어떨까?&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;filter 를 사용해서 해당 포지션값에 해당하는 플레이어들만 묶어서 출력을 해보았다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이렇게 하면 포지션이 순서대로 넘어오지 않더라도 포지션별로 그룹화를 진행할 수 있어서 좋았던거 같다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1735464018085&quot; class=&quot;sqf&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;  // 포지션별로 데이터를 그룹화
const groupedPlayers = {
  top: players.filter(player =&amp;gt; player.position === &quot;top&quot;),
  jug: players.filter(player =&amp;gt; player.position === &quot;jug&quot;),
  mid: players.filter(player =&amp;gt; player.position === &quot;mid&quot;),
  ad: players.filter(player =&amp;gt; player.position === &quot;ad&quot;),
  sup: players.filter(player =&amp;gt; player.position === &quot;sup&quot;)
};

console.log(groupedPlayers);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kTtdR/btsLyVNrocj/neDrfHxnanahMQBs5yB6V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kTtdR/btsLyVNrocj/neDrfHxnanahMQBs5yB6V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kTtdR/btsLyVNrocj/neDrfHxnanahMQBs5yB6V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkTtdR%2FbtsLyVNrocj%2FneDrfHxnanahMQBs5yB6V0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;745&quot; height=&quot;511&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;해당 그룹에서 포지션별로 각 팀에서 한명씩 가져가면 해당 배열에서 제거되고 각 팀별로 5명씩 구성이 된다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;read팀에서 먼저 해당 포지션에 있는 유저 한명을 가져가면 그룹에서 두명에서 한명으로 바뀌게 되는 것이다.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;블루쪽은 자연스럽게 남은 한명을 가져가게 된다.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1735464474005&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 랜덤으로 팀 구성 함수
function getRandomPlayer(positionGroup) {
  const randomIndex = Math.floor(Math.random() * positionGroup.length);
  return positionGroup.splice(randomIndex, 1)[0]; // 선택된 플레이어 반환 후 배열에서 제거
}

// 팀 구성
const redTeam = [
  getRandomPlayer(groupedPlayers.top),
  getRandomPlayer(groupedPlayers.jug),
  getRandomPlayer(groupedPlayers.mid),
  getRandomPlayer(groupedPlayers.ad),
  getRandomPlayer(groupedPlayers.sup)
];

const blueTeam = [
  getRandomPlayer(groupedPlayers.top),
  getRandomPlayer(groupedPlayers.jug),
  getRandomPlayer(groupedPlayers.mid),
  getRandomPlayer(groupedPlayers.ad),
  getRandomPlayer(groupedPlayers.sup)
];&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;어려웠던 점&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;데이터의 랜덤성을 유지하는 것이 어렵다&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;초기엔 포지션을 랜덤으로 배치하려고 했지만, 동일한 포지션이 겹치지 않게 하는 제약 때문에 생각보다 복잡해졌다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm17Dh/btsLzpAIt0D/5LhZfkK63cliOVp6L8ft80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm17Dh/btsLzpAIt0D/5LhZfkK63cliOVp6L8ft80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm17Dh/btsLzpAIt0D/5LhZfkK63cliOVp6L8ft80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm17Dh%2FbtsLzpAIt0D%2F5LhZfkK63cliOVp6L8ft80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;350&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;최종 밸런스 매칭 코드&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735460860221&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 밸런스 섞기
const balanceTeams = (players) =&amp;gt; {
  // 포지션별 점수 -&amp;gt; 정글-미드-원딜-탑-서폿
  const positionPoints = { jug: 5, mid: 4, ad: 3, top: 2, sup: 1 };

  // 포지션별 그룹화
  const positionPlayers = {
    jug: [],
    mid: [],
    ad: [],
    top: [],
    sup: [],
  };

  // 선수 데이터 새로 복사하고 랜덤 섞기
  const shuffledPlayers = [...players]; // 원본을 변경하지 않기 위해 복사
  shufflePlayers(shuffledPlayers);

  // 복사된 선수들을 포지션별로 분류
  shuffledPlayers.forEach((player) =&amp;gt; {
    positionPlayers[player.position].push(player);
  });

  // 각 포지션별로 점수 추가
  for (const position of Object.keys(positionPoints)) {
    const playersInPosition = positionPlayers[position];

    // rankScore가 20 이상인 선수만 점수 추가
    playersInPosition.forEach((player) =&amp;gt; {
      if (player.RankScore &amp;gt;= 20) {
        player.RankScore += positionPoints[position];
      }
    });
  }

  // 점수 기준으로 내림차순 정렬
  shuffledPlayers.sort((a, b) =&amp;gt; b.RankScore - a.RankScore);

  // 두 팀으로 균등 분배 (각 팀에 5명씩)
  const teams = [
    { players: [], totalRankScore: 0 },
    { players: [], totalRankScore: 0 },
  ];

  // 포지션 순서대로 팀에 분배
  const positionOrder = [&quot;top&quot;, &quot;jug&quot;, &quot;mid&quot;, &quot;ad&quot;, &quot;sup&quot;];

  // 각 포지션에서 한 명씩 배정
  positionOrder.forEach((position) =&amp;gt; {
    const team1Player = positionPlayers[position].shift();
    const team2Player = positionPlayers[position].shift();

    // 점수가 적은 팀에 배정
    if (team1Player) {
      teams[0].players.push(team1Player);
      teams[0].totalRankScore += team1Player.RankScore;
    }
    if (team2Player) {
      teams[1].players.push(team2Player);
      teams[1].totalRankScore += team2Player.RankScore;
    }
  });

  // 나머지 선수들 균등 배정
  let remainingPlayers = [].concat(...Object.values(positionPlayers));
  remainingPlayers = shufflePlayers(remainingPlayers);

  // 남은 선수들을 순차적으로 팀에 추가
  remainingPlayers.forEach((player) =&amp;gt; {
    if (teams[0].players.length &amp;lt; 5) {
      teams[0].players.push(player);
      teams[0].totalRankScore += player.RankScore;
    } else if (teams[1].players.length &amp;lt; 5) {
      teams[1].players.push(player);
      teams[1].totalRankScore += player.RankScore;
    }
  });

  // 클라이언트로 전달할 때 탑 -&amp;gt; 정글 -&amp;gt; 미드 -&amp;gt; 원딜 -&amp;gt; 서폿 순으로 정렬
  const sortPositionClient = (team) =&amp;gt; {
    const positionOrder = [&quot;top&quot;, &quot;jug&quot;, &quot;mid&quot;, &quot;ad&quot;, &quot;sup&quot;];
    return positionOrder
      .map((position) =&amp;gt; {
        return team.players.filter((player) =&amp;gt; player.position === position);
      })
      .flat();
  };

  // 각 팀의 포지션 순서대로 정렬 후 전달
  const blueTeam = sortPositionClient(teams[0]);
  const redTeam = sortPositionClient(teams[1]);

  return {
    blueTeam: {
      players: blueTeam,
      totalRankScore: teams[0].totalRankScore,
    },
    redTeam: {
      players: redTeam,
      totalRankScore: teams[1].totalRankScore,
    },
  };
};
// 선수 랜덤 섞기
const shufflePlayers = (arr) =&amp;gt; {
  for (let i = arr.length - 1; i &amp;gt; 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [arr[i], arr[j]] = [arr[j], arr[i]]; // 요소를 교환
  }
  return arr;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;응답데이터&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735466875168&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;message&quot;: &quot;밸런스 팀 생성 완료&quot;,
    &quot;redTeam&quot;: {
        &quot;players&quot;: [
            {
                &quot;id&quot;: 2,
                &quot;gameName&quot;: &quot;test2&quot;,
                &quot;RankScore&quot;: 15,
                &quot;position&quot;: &quot;탑&quot;
            },
            {
                &quot;id&quot;: 4,
                &quot;gameName&quot;: &quot;test4&quot;,
                &quot;RankScore&quot;: 18,
                &quot;position&quot;: &quot;정글&quot;
            },
            {
                &quot;id&quot;: 6,
                &quot;gameName&quot;: &quot;test6&quot;,
                &quot;RankScore&quot;: 26,
                &quot;position&quot;: &quot;미드&quot;
            },
            {
                &quot;id&quot;: 8,
                &quot;gameName&quot;: &quot;test8&quot;,
                &quot;RankScore&quot;: 17,
                &quot;position&quot;: &quot;원딜&quot;
            },
            {
                &quot;id&quot;: 10,
                &quot;gameName&quot;: &quot;test10&quot;,
                &quot;RankScore&quot;: 19,
                &quot;position&quot;: &quot;서폿&quot;
            }
        ],
        &quot;totalRankScore&quot;: 95
    },
    &quot;blueTeam&quot;: {
        &quot;players&quot;: [
            {
                &quot;id&quot;: 1,
                &quot;gameName&quot;: &quot;test1&quot;,
                &quot;RankScore&quot;: 10,
                &quot;position&quot;: &quot;탑&quot;
            },
            {
                &quot;id&quot;: 3,
                &quot;gameName&quot;: &quot;test3&quot;,
                &quot;RankScore&quot;: 25,
                &quot;position&quot;: &quot;정글&quot;
            },
            {
                &quot;id&quot;: 5,
                &quot;gameName&quot;: &quot;test5&quot;,
                &quot;RankScore&quot;: 12,
                &quot;position&quot;: &quot;미드&quot;
            },
            {
                &quot;id&quot;: 7,
                &quot;gameName&quot;: &quot;test7&quot;,
                &quot;RankScore&quot;: 14,
                &quot;position&quot;: &quot;원딜&quot;
            },
            {
                &quot;id&quot;: 9,
                &quot;gameName&quot;: &quot;test9&quot;,
                &quot;RankScore&quot;: 13,
                &quot;position&quot;: &quot;서폿&quot;
            }
        ],
        &quot;totalRankScore&quot;: 74
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;br /&gt;단계별 코드 분석&lt;/span&gt;&lt;/blockquote&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-4o&quot; data-message-id=&quot;3a93600b-eb8c-42e3-a4e6-1b0c1ece57b5&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 포지션별 점수 가중치 부여&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;-&amp;nbsp; 이 가중치는 팀 밸런스를 맞추기 위해 RankScore에 추가할 점수&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;pre id=&quot;code_1735465016208&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const positionPoints = { jug: 5, mid: 4, ad: 3, top: 2, sup: 1 };&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-4o&quot; data-message-id=&quot;3a93600b-eb8c-42e3-a4e6-1b0c1ece57b5&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 플레이어 섞기 (shufflePlayers)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp; &amp;nbsp;-&amp;nbsp; 처음엔 팀을 무작위로 섞어주기 순서대로 나누거나 정렬할 경우 한팀에만 잘하는 유저들이 분포될 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;pre id=&quot;code_1735465083034&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const shuffledPlayers = [...players];
shufflePlayers(shuffledPlayers);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 3. 포지션별 그룹화 &lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;- 포지션이 겹치지 않게 그룹화하기&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1735465216235&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;shuffledPlayers.forEach((player) =&amp;gt; {
  positionPlayers[player.position].push(player);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;4. 포지션 순서대로 팀 배정&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;- 점수가 적은 팀에 우선적으로 배정하면서 두팀의 점수 차이를 최소화 하기&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1735465268187&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;positionOrder.forEach((position) =&amp;gt; {
  const team1Player = positionPlayers[position].shift();
  const team2Player = positionPlayers[position].shift();

  if (team1Player) {
    teams[0].players.push(team1Player);
    teams[0].totalRankScore += team1Player.RankScore;
  }
  if (team2Player) {
    teams[1].players.push(team2Player);
    teams[1].totalRankScore += team2Player.RankScore;
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;5. 남은 선수 팀 배정&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735465331045&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;remainingPlayers.forEach((player) =&amp;gt; {
  if (teams[0].players.length &amp;lt; 5) {
    teams[0].players.push(player);
    teams[0].totalRankScore += player.RankScore;
  } else if (teams[1].players.length &amp;lt; 5) {
    teams[1].players.push(player);
    teams[1].totalRankScore += player.RankScore;
  }
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드의 강점&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;점수 차이를 최소화&lt;/b&gt;: 플레이어 점수를 기준으로 균등 분배를 진행하여, 두 팀 간 점수 차이가 최대한 적도록 설계했습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;포지션 겹침 방지&lt;/b&gt;: 각 포지션에서 한 명씩 배정하여, 게임 밸런스를 해치지 않도록 했습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;확장 가능성&lt;/b&gt;: 가중치나 팀 배정 방식을 쉽게 변경할 수 있어, 다른 요구 사항에 맞게 조정하기 용이합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;랜덤성과 공정성 보장&lt;/b&gt;: 플레이어를 무작위로 섞고, 점수 및 포지션 기준으로 배정하여 편향성을 방지했습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;개선 방향 및 목표&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;사용자 피드백 기반 데이터 수집&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 프로그램을 사용하는 유저들에게 추가적인 데이터와 피드백을 받아 현재 점수 시스템의 한계를 보완하고 개선 방향을 찾습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다양한 유저의 플레이 스타일과 의견을 반영해 밸런스를 보다 정교하게 조정합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다양한 플레이 스타일 반영&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;현재는 단순히 티어별 점수를 기준으로 밸런스를 평가하고 있지만 유저들의 플레이 스타일에 따라 점수를 조정할 필요가 있습니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;예를 들어:&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;특정 챔피언 하나만 잘 다루는 유저: 해당 챔피언에 대한 높은 숙련도로 티어를 유지하는 경우&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다양한 챔피언을 다루며 지능적으로 플레이하는 유저: 특정 챔피언에 의존하지 않고 전반적으로 실력을 발휘해 티어를 올리는 경우.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;지속적인 업데이트&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;수집한 데이터와 유저 피드백을 바탕으로 점수 시스템과 밸런스 알고리즘을 주기적으로 업데이트합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이를 통해 유저들이 프로그램을 사용할수록 점점 더 공정하고 만족스러운 결과를 얻을 수 있도록 개선합니다.&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기대 효과&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다양한 유저의 플레이 스타일을 반영한 맞춤형 밸런스 제공&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;유저 피드백을 바탕으로 점진적으로 발전하는 시스템 구축&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;단순한 티어별 점수 배정 방식을 넘어 실제 실력을 보다 정확히 반영&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발 프로젝트/LOL-TEAM-MATCH</category>
      <author>jennet1</author>
      <guid isPermaLink="true">https://jennet1.tistory.com/23</guid>
      <comments>https://jennet1.tistory.com/23#entry23comment</comments>
      <pubDate>Sun, 29 Dec 2024 19:11:11 +0900</pubDate>
    </item>
    <item>
      <title>React 앱 생성하기</title>
      <link>https://jennet1.tistory.com/22</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. &lt;b&gt;리액트 소개&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;리액트란?&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리액트(React)는 페이스북에서 개발한 JavaScript 라이브러리로, 사용자 인터페이스(UI)를 구축하는 데 사용됩니다.&lt;/li&gt;
&lt;li&gt;컴포넌트 기반 아키텍처를 사용하여 재사용 가능하고 관리하기 쉬운 UI를 만들 수 있습니다.&lt;/li&gt;
&lt;li&gt;선언형(Declarative) 방식으로 UI를 설계하여, 상태가 변경될 때 자동으로 UI를 갱신합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;리액트 프로젝트 시작하기&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;리액트 환경 설정&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Node.js 설치&lt;/b&gt;: 리액트 프로젝트를 시작하려면 Node.js가 필요합니다. &lt;a href=&quot;https://nodejs.org/&quot;&gt;&lt;span&gt;Node&lt;/span&gt;&lt;span&gt;.js&lt;/span&gt;&lt;span&gt; 공식&lt;/span&gt;&lt;span&gt; 웹사이트&lt;/span&gt;&lt;/a&gt;에서 최신 버전을 설치합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Create React App 사용&lt;/b&gt;: create-react-app은 리액트 애플리케이션을 쉽게 시작할 수 있게 해주는 명령어 도구입니다.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1734360525682&quot; class=&quot;javascript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;[ git bash ]
npx create-react-app my-app
cd my-app
npm start&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;에러1) npx create-react-app my-app 설치 완료 후 에러 발생 시&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4dUcA/btsLjUnnMlt/b22zFUFK4apE1VGAUkKJk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4dUcA/btsLjUnnMlt/b22zFUFK4apE1VGAUkKJk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4dUcA/btsLjUnnMlt/b22zFUFK4apE1VGAUkKJk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4dUcA%2FbtsLjUnnMlt%2Fb22zFUFK4apE1VGAUkKJk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;926&quot; height=&quot;92&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1734361194914&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm config set legacy-peer-deps true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러2) &amp;gt; npm start 실행 후 아래와 같이 에러가 난다면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;55&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxBVBg/btsLjEE71ZR/Kfql6wgcVoPd2C71RVZTc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxBVBg/btsLjEE71ZR/Kfql6wgcVoPd2C71RVZTc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxBVBg/btsLjEE71ZR/Kfql6wgcVoPd2C71RVZTc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxBVBg%2FbtsLjEE71ZR%2FKfql6wgcVoPd2C71RVZTc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;446&quot; height=&quot;55&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;55&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1734361569785&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ npm install --save-dev ajv@^7&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BFF5j/btsLlbPeTUf/4DnFV49YiwM8K4SuXP1Yqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BFF5j/btsLlbPeTUf/4DnFV49YiwM8K4SuXP1Yqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BFF5j/btsLlbPeTUf/4DnFV49YiwM8K4SuXP1Yqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBFF5j%2FbtsLlbPeTUf%2F4DnFV49YiwM8K4SuXP1Yqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;524&quot; height=&quot;230&quot; data-origin-width=&quot;524&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;575&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rx9EK/btsLlQKqjmb/3MrqV8kbxddjyfsqU9B6P1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rx9EK/btsLlQKqjmb/3MrqV8kbxddjyfsqU9B6P1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rx9EK/btsLlQKqjmb/3MrqV8kbxddjyfsqU9B6P1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frx9EK%2FbtsLlQKqjmb%2F3MrqV8kbxddjyfsqU9B6P1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;734&quot; height=&quot;575&quot; data-origin-width=&quot;734&quot; data-origin-height=&quot;575&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>라이브러리/React</category>
      <author>jennet1</author>
      <guid isPermaLink="true">https://jennet1.tistory.com/22</guid>
      <comments>https://jennet1.tistory.com/22#entry22comment</comments>
      <pubDate>Tue, 17 Dec 2024 00:08:53 +0900</pubDate>
    </item>
    <item>
      <title>Jquery 기본문법</title>
      <link>https://jennet1.tistory.com/21</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt; jQuery란? &lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;- javascript 라이브러리로 더 간편하게 사용하기 위해 만들어졌다. 주로 DOM,이벤트,애니메이션,AJAX 요청 등을 쉽게 할 수 있게 도와준다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;jQuery와 javaScript 의 차이점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;1. 코드 간결성 : 일반적인 javascript 복잡한 작업을 간단하게 처리할 수 있다. 즉 짧은 코드로 처리가 가능하다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;2. 호환성 : 브라우저 호환성을 처리해주기 때문에, 다양한 브라우저에서 동일하게 작동하는 코드를 쉽게 작성이 가능하다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;javaScript 는 브라우저 별로 코드가 다르게 작동할 수 있어 호환성 문제가 발생할 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;3. 기능 : ajax,애니메이션,이벤트 핸들링 등을 간단하고 효율적으로 구현이 가능한 함수들이 내장되어있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;JavaScript:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1727176693364&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;document.getElementById('myElement').style.color = 'red';&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;jQuery:&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1727176704359&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$('#myElement').css('color', 'red');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;기본 문법에 대해 알아보자&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1727176804517&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// ID로 요소 선택
$('#myElement');

// 클래스 이름으로 요소 선택
$('.myClass');

// 태그 이름으로 요소 선택
$('p');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;클릭 이벤트 처리&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1727176823469&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 클릭 이벤트 처리
$('#myButton').on('click', function() {
  alert('버튼이 클릭되었습니다!');
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;CSS 조작&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1727176836122&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 요소의 색상 변경
$('#myElement').css('color', 'blue');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;DOM 조작&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1727176847178&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 요소의 내용을 변경
$('#myElement').html('&amp;lt;p&amp;gt;새로운 내용&amp;lt;/p&amp;gt;');

// 요소에 내용 추가
$('#myElement').append('&amp;lt;p&amp;gt;추가된 내용&amp;lt;/p&amp;gt;');&lt;/code&gt;&lt;/pre&gt;</description>
      <category>WEB/Jquery</category>
      <category>과정(웹개발자)</category>
      <category>부트캠프</category>
      <category>코딩온</category>
      <category>코딩온30일챌린지</category>
      <category>포스코</category>
      <author>jennet1</author>
      <guid isPermaLink="true">https://jennet1.tistory.com/21</guid>
      <comments>https://jennet1.tistory.com/21#entry21comment</comments>
      <pubDate>Tue, 24 Sep 2024 20:26:57 +0900</pubDate>
    </item>
  </channel>
</rss>