<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>real_q_kakaoki.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Fri, 11 Apr 2025 02:49:42 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>real_q_kakaoki.log</title>
            <url>https://velog.velcdn.com/images/real_q_kakaoki/profile/6e6d0a26-5a37-4a17-a522-9ddab8c3d9d4/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. real_q_kakaoki.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/real_q_kakaoki" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[복습] 제어컴포넌트의 기본]]></title>
            <link>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5-%EC%A0%9C%EC%96%B4%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%9D%98-%EA%B8%B0%EB%B3%B8</link>
            <guid>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5-%EC%A0%9C%EC%96%B4%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%9D%98-%EA%B8%B0%EB%B3%B8</guid>
            <pubDate>Fri, 11 Apr 2025 02:49:42 GMT</pubDate>
            <description><![CDATA[<h3 id="폼의-입력값을-처리하는-컴포넌트의-기본예제">폼의 입력값을 처리하는 컴포넌트의 기본예제</h3>
<pre><code class="language-js">import { useState } from &#39;react&#39;;

export default function StateForm() {
  const [myForm, setMyForm] = useState({
    name: &#39;김철수&#39;,
    age: 20
  });

  const handleForm = e =&gt; {
    setMyForm({
      const { name, value } = e.target;
      setForm(prevForm =&gt; ({
        /* 기존의 객체정보는 모두 그대로 복사 */
        ...prevForm,
        /* 변경된 부분만 갱신 */
        [name]: value
      }));
    });
  };

  const show = () =&gt; {
    console.log(`안녕하세요, ${myForm.name}（${myForm.age}세） 님！`);
  };

  return (
    &lt;form&gt;
      &lt;div&gt;
        &lt;label htmlFor=&quot;_name_&quot;&gt;이름: &lt;/label&gt;
        &lt;input id=&quot;_name_&quot; name=&quot;name&quot; type=&quot;text&quot; 
            onChange={handleForm} value={myForm.name} /&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;label htmlFor=&quot;_age_&quot;&gt;나이:&lt;/label&gt;
        &lt;input id=&quot;_age_&quot; name=&quot;age&quot; type=&quot;number&quot; 
            onChange={handleForm} value={myForm.age} /&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;button type=&quot;button&quot; onClick={show}&gt;보내기&lt;/button&gt;
      &lt;/div&gt;
      &lt;p&gt;안녕하세요, {myForm.name}（{myForm.age}세） 님！&lt;/p&gt;
    &lt;/form&gt;
  );
}</code></pre>
<ul>
<li>React Hook Form 써서 코드 짧게 쓰는 방법도 많이 사용된다. 또한, 유효성검사 라이브러리인 Yup 으로 유효성 검사 자동화하는 방법을 쓰는 것도 좋다.<pre><code>// 먼저 라이브러리를 설치한다.
npm install react-hook-form
npm install yup</code></pre><pre><code class="language-js">import { useForm } from &#39;react-hook-form&#39;;
import { yupResolver } from &#39;@hookform/resolvers/yup&#39;;
import * as yup from &#39;yup&#39;;
</code></pre>
</li>
</ul>
<p>// 1. Yup 스키마 작성
const schema = yup.object({
  name: yup.string().required(&#39;이름은 필수입니다.&#39;),
  age: yup.number().required(&#39;나이는 필수입니다.&#39;).positive(&#39;양수만 가능합니다.&#39;).integer(&#39;정수여야 합니다.&#39;)
}).required();</p>
<p>export default function MyForm() {
  // 2. useForm에서 yupResolver를 적용
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: yupResolver(schema)
  });</p>
<p>  const onSubmit = (data) =&gt; {
    console.log(data);
  };</p>
<p>  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label>이름</label>
        &lt;input {...register(&#39;name&#39;)} /&gt;
        {errors.name &amp;&amp; <p>{errors.name.message}</p>}
      </div></p>
<pre><code>  &lt;div&gt;
    &lt;label&gt;나이&lt;/label&gt;
    &lt;input type=&quot;number&quot; {...register(&#39;age&#39;)} /&gt;
    {errors.age &amp;&amp; &lt;p&gt;{errors.age.message}&lt;/p&gt;}
  &lt;/div&gt;

  &lt;button type=&quot;submit&quot;&gt;제출&lt;/button&gt;
&lt;/form&gt;</code></pre><p>  );
}
/*</p>
<ul>
<li><p>useForm()      폼을 쉽게 관리할 수 있게 해주는 Hook</p>
</li>
<li><p>register(&#39;name&#39;)      input을 폼에 등록(바인딩)하는 명령어</p>
</li>
<li><p>handleSubmit(onSubmit)    제출할 때 validation 검사 + 데이터 전달</p>
</li>
<li><p>errors.name, errors.age     입력 검증 실패 시 에러 정보 담긴 객체</p>
</li>
<li><p>yup.object({})    입력값 전체를 객체처럼 검증하는 스키마 생성</p>
</li>
<li><p>yup.string().required()    문자열이고, 필수 입력인지 검증</p>
</li>
<li><p>yup.number().positive().integer()    숫자, 양수, 정수 조건 검증</p>
</li>
<li><p>resolver: yupResolver(schema)    이 스키마를 React Hook Form에 연결해서 자동검증</p>
</li>
<li><p>errors.name.message    에러 메시지를 바로 출력</p>
</li>
<li><p>/</p>
<pre><code></code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[복습] 함수선언 vs 함수표현식]]></title>
            <link>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5-%ED%95%A8%EC%88%98%EC%84%A0%EC%96%B8-vs-%ED%95%A8%EC%88%98%ED%91%9C%ED%98%84%EC%8B%9D</link>
            <guid>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5-%ED%95%A8%EC%88%98%EC%84%A0%EC%96%B8-vs-%ED%95%A8%EC%88%98%ED%91%9C%ED%98%84%EC%8B%9D</guid>
            <pubDate>Fri, 11 Apr 2025 01:47:28 GMT</pubDate>
            <description><![CDATA[<h3 id="함수선언과-함수표현식의-차이점">함수선언과 함수표현식의 차이점</h3>
<p><img src="https://velog.velcdn.com/images/real_q_kakaoki/post/e091df4f-8f69-4230-acdc-697393597b3f/image.png" alt=""></p>
<ul>
<li>함수선언에서의 this<pre><code class="language-js">const obj = {
name: &quot;Giggles&quot;,
greet: function() {
  console.log(this.name);
}
};
</code></pre>
</li>
</ul>
<p>obj.greet(); // 결과: &quot;Giggles&quot;</p>
<pre><code>
* 함수표현식에서의 this
``` js
const obj = {
  name: &quot;Giggles&quot;,
  greet: () =&gt; {
    console.log(this.name);
  }
};

obj.greet(); // 결과: undefined
/* 화살표 함수에서는 this가 obj를 가리키지 않고,
함수가 선언된 상위 스코프(전역, 또는 모듈의 this)를 그대로 사용함. */</code></pre><ul>
<li>함수선언에서의 this
function A() { } 은 → &quot;나를 누가 부르냐?&quot;를 보고 그때그때 this를 정함.</li>
<li>화살표함수에서의 this
() =&gt; { } 은 → &quot;나 태어날 때 주인 누구였냐?&quot;를 보고 고정함. (출생 시점이 중요함)</li>
<li>화살표 함수는 객체 안에서 쓰더라도 this를 객체인 &quot;obj&quot;에 바인딩하지 않는다. 오직 &quot;선언 당시의 바깥 this&quot;를 캡처할 뿐이다. 그래서 객체 안의 메서드는 보통 함수선언의 형태 function A() 로 쓴다.</li>
<li>화살표함수는 콜백 안에서 this 를 유지하고 싶을 때 유용하다.<pre><code class="language-js">const obj = {
name: &quot;Giggles&quot;,
greet() {
  setTimeout(() =&gt; {
    console.log(this.name);
  }, 1000);
}
};
</code></pre>
</li>
</ul>
<p>obj.greet(); // &quot;Giggles&quot;
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[복습] 마우스이벤트와 좌표]]></title>
            <link>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5-%EB%A7%88%EC%9A%B0%EC%8A%A4%EC%9D%B4%EB%B2%A4%ED%8A%B8%EC%99%80-%EC%A2%8C%ED%91%9C</link>
            <guid>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5-%EB%A7%88%EC%9A%B0%EC%8A%A4%EC%9D%B4%EB%B2%A4%ED%8A%B8%EC%99%80-%EC%A2%8C%ED%91%9C</guid>
            <pubDate>Thu, 10 Apr 2025 04:51:03 GMT</pubDate>
            <description><![CDATA[<p>복습용</p>
<p><img src="https://velog.velcdn.com/images/real_q_kakaoki/post/e72b460a-15e2-411d-8080-25afd61df5dd/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[복습] 리액트 학습일지 [2] (모던 리액트)]]></title>
            <link>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5-%EB%AA%A8%EB%8D%98-%EB%A6%AC%EC%95%A1%ED%8A%B8</link>
            <guid>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5-%EB%AA%A8%EB%8D%98-%EB%A6%AC%EC%95%A1%ED%8A%B8</guid>
            <pubDate>Thu, 10 Apr 2025 04:33:15 GMT</pubDate>
            <description><![CDATA[<h3 id="-자식-컴포넌트에서-부모-컴포넌트로-정보를-전달">* 자식 컴포넌트에서 부모 컴포넌트로 정보를 전달</h3>
<ul>
<li>부모컴포넌트에서 자식컴포넌트로 정보를 전달하는 일반적인 방법은 Props 를 이용하는 것이다. </li>
<li>반면에, 자식컴포넌트에서 부모컴포넌트로는 <strong>State를 업데이트</strong>하는 것으로 정보를 전달할 수 있다.</li>
</ul>
<p>부모컴포넌트에서 State 를 관리하고, 이 State 를 컨트롤하는 handler 를 자식에게 전달하면, 자식컴포넌트에서는 이 handler 를 통해서 부모의 State 에 접근할 수 있다. 이를 이용하여 자식에서 부모로 정보를 보낼 수 있게 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[복습] 리액트 학습일지 [1] (모던 리액트)]]></title>
            <link>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5-%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%95%99%EC%8A%B5%EC%9D%BC%EC%A7%80-1-%EB%AA%A8%EB%8D%98-%EB%A6%AC%EC%95%A1%ED%8A%B8</link>
            <guid>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5-%EB%A6%AC%EC%95%A1%ED%8A%B8-%ED%95%99%EC%8A%B5%EC%9D%BC%EC%A7%80-1-%EB%AA%A8%EB%8D%98-%EB%A6%AC%EC%95%A1%ED%8A%B8</guid>
            <pubDate>Thu, 10 Apr 2025 04:18:56 GMT</pubDate>
            <description><![CDATA[<h3 id="-컴포넌트가-리렌더링하는-타이밍">* 컴포넌트가 리렌더링하는 타이밍</h3>
<ol>
<li>State 가 업데이트 된 경우</li>
<li>전달받는 Props 가 변경된 경우</li>
<li>부모 컴포넌트가 리렌더링된 경우</li>
</ol>
<p>리렌더링 되더라도 State의 초기화는 생성시에 한 번만 수행된다.</p>
<h3 id="-리액트-디벨로퍼-툴">* 리액트 디벨로퍼 툴</h3>
<p>React Developer Tools 는 크롬, 엣지 등의 브라우저에서 다운 받아 사용할 수 있는 확장프로그램이다. 컴포넌트트리와 실행시간, 부하측정 등에 유용하게 사용된다.</p>
<h3 id="-배열의-map-함수를-통하여-새로운-배열을-반환할-때에-새로운-배열의-각-반환-요소는-key-값을-가지고-있어야-한다">* 배열의 map 함수를 통하여 새로운 배열을 반환할 때에 새로운 배열의 각 반환 요소는 key 값을 가지고 있어야 한다.</h3>
<pre><code class="language-js">myArray.map((elem, idx)=&gt;{
  &lt;React.Fragment key={elem.unique_key}&gt;
    ...
  &lt;/React.Fragment&gt;
});</code></pre>
<p>단순히 map 함수의 인자로 전달되는 index 를 key 값으로 사용하는 것은 매우 좋지 않다. key 는 고유한 값을 가져야 하기 때문이다. 참고로 key 값은 map 메서드의 내부에서만 고유하면 되며, 다른 배열의 key 와는 겹쳐도 상관없다. 즉, 동일한 배열 내의 요소들 사이에서 key 가 중복되지만 않으면 된다.</p>
<ul>
<li>key 값으로 고유한 값을 할당하는 방법
1) 데이터 자체의 정보로부터 key 를 생성
2) Date.Now() 함수와 데이터를 섞어서 key 를 생성
3) uuid 라이브러리를 이용하여 key 를 생성</li>
</ul>
<pre><code class="language-js">/* 터미널에서 라이브러리 설치 */
npm install uuid  

/* 터미널에서 라이브러리 설치 */
import { v4 as uuidv4 } from &#39;uuid&#39;;
uuidv4();  // &#39;971dea4d-3b7d-4bad-9bdd-2b0h7b3dc26d&#39;</code></pre>
<h3 id="-if-구문의-삽입">* if 구문의 삽입</h3>
<p>if 구문을 직접 JSX 식에 삽입할 수 없기 때문에, <strong>즉시함수</strong>를 이용해서 JSX 식에 삽입할 수 있다.</p>
<pre><code class="language-js">export default function MyComponent() {
    return(
      &lt;&gt;
          { 
          (()=&gt;{
              if(/*조건식*/)
               return &lt;p&gt; O &lt;/p&gt;
            else
               return &lt;p&gt; X &lt;/p&gt;
          })() /*즉시실행*/
        }
      &lt;/&gt;
    )
}</code></pre>
<h3 id="-간단한-조건분기-연산자">* 간단한 조건분기 연산자</h3>
<p>1) isActive ? 참일 때 : 거짓일 때
2) isActive &amp;&amp; 참일 때    // isActive 가 참일 때에만 처리
3) isActive || 거짓일 때  // isActive 가 거짓일 때에만 처리</p>
<h3 id="-classnames-라이브러리의-활용">* classnames 라이브러리의 활용</h3>
<p>className 속성에 공백을 활용하여 <strong>고정스타일</strong>과 <strong>선택스타일</strong>을 섞어서 사용할 때에 스타일 클래스 이름을 나열하기 쉽도록 도와준다.</p>
<pre><code class="language-js">/*기존*/
&lt;div className=&quot;box light&quot;&gt;&lt;/div&gt;

/*라이브러리 활용*/
npm install classnames

import cn from &#39;classnames&#39;;
&lt;div className={cn(&#39;box&#39;, &#39;light&#39;)}&gt;&lt;/div&gt;</code></pre>
<h3 id="-꾸미기-컴포넌트의-활용법">* 꾸미기 컴포넌트의 활용법</h3>
<p>대상 컴포넌트를 꾸미기 컴포넌트로 감싸서 대상 컴포넌트를 특정한 방식으로 꾸미거나 조작할 수 있다.</p>
<pre><code class="language-js">/* StyledComponent.js */
export default function StyledComponent( {children} ) {
    return(
      &lt;div style={padding: 10, border:&#39;1px solid #111&#39;}&gt;
          {children}
      &lt;/div&gt;
    );
}

/* MyComponent.js */
import StyledComponent from &#39;./StyledComponent.js&#39;

export default function MyComponent() {
    return(
      &lt;StyledComponent&gt;
          &lt;p&gt;이 문장은 꾸며지게 됩니다.&lt;/p&gt;
      &lt;/StyledComponent&gt;
    );
}</code></pre>
<h3 id="-children-에-매개변수-전달하기">* children 에 매개변수 전달하기</h3>
<pre><code class="language-js">/* ListTemplate.js */
export default function ListTemplate( {arr, children} ) {
    return(
      &lt;div style={padding: 10, border:&#39;1px solid #111&#39;}&gt;
          {
              arr.map( (elem) =&gt; {
              &lt;React.Fragment key={elem.id}&gt;
                {children(elem.value)}
              &lt;/React.Fragment&gt;
            }
        }
      &lt;/div&gt;
    );
}

/* MyComponent.js */
import ListTemplate from &#39;./ListTemplate.js&#39;

export default function MyComponent() {
    return(
      &lt;ListTemplate arr={myArrayData}&gt;
          {
              /* children 을 함수로 만든다. */
              /* 이 함수에서 반환하는 대상이 children 이 된다. */
              /* 함수이기 때문에 매개변수 전달하는 것이 자유롭다. */
              (value) =&gt; {
              &lt;p&gt; 반환되어 children 이 된다. &lt;/p&gt;
              &lt;p&gt; {value} 값의 전달도 자유롭다. &lt;/p&gt;
            }
        }
      &lt;/ListTemplate&gt;
    );
}</code></pre>
<ul>
<li>참고할 내용 <strong>렌더프롭 Render Props</strong></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[학습] useState 의 set 함수]]></title>
            <link>https://velog.io/@real_q_kakaoki/%ED%95%99%EC%8A%B5-useState-%EC%9D%98-set-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@real_q_kakaoki/%ED%95%99%EC%8A%B5-useState-%EC%9D%98-set-%ED%95%A8%EC%88%98</guid>
            <pubDate>Tue, 04 Mar 2025 05:45:37 GMT</pubDate>
            <description><![CDATA[<h3 id="-usestate-의-업데이트-함수에는-업데이트-함수를-지정하는-것이-좋다">* useState 의 업데이트 함수에는 업데이트 함수를 지정하는 것이 좋다.</h3>
<pre><code class="language-js">// 적절하지 못한 코드
function MyComponent() {
  const [num, setNum] = useState(0);

  const onClickButton = () =&gt; {
      setNum(num + 1); // 직접 num 을 변경
  };

  &lt;button onClick={onClickButton}&gt;버튼&lt;/button&gt;
}</code></pre>
<hr>
<pre><code class="language-js">// 적절하게 변경한 코드
function MyComponent() {
  const [num, setNum] = useState(0);

  const onClickButton = () =&gt; {
      setNum( (prev) =&gt; prev + 1 ); // 변경할 함수를 지정
  };

  &lt;button onClick={onClickButton}&gt;버튼&lt;/button&gt;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[학습] 배열의 map, filter]]></title>
            <link>https://velog.io/@real_q_kakaoki/%ED%95%99%EC%8A%B5-%EB%B0%B0%EC%97%B4%EC%9D%98-map-filter</link>
            <guid>https://velog.io/@real_q_kakaoki/%ED%95%99%EC%8A%B5-%EB%B0%B0%EC%97%B4%EC%9D%98-map-filter</guid>
            <pubDate>Tue, 04 Mar 2025 05:25:26 GMT</pubDate>
            <description><![CDATA[<ul>
<li>map : 배열의 모든 요소를 순회하며 로직을 실행한다.<pre><code class="language-js">let arr1 = [1, 2, 3];
</code></pre>
</li>
</ul>
<p>arr1.map(
  (element, index) =&gt; {
    console.log(<code>index : ${index} , element is ${element}</code>);<br>  }
);</p>
<pre><code>&gt; 출력결과
index : 0 , element is 1
index : 1 , element is 2
index : 2 , element is 3


- filter : 배열의 모든 요소를 순회하며 참인 요소에 대해서만 로직을 실행한다. 아래는 짝수인 요소만 출력하는 코드이다.
```js
let arr1 = [1, 2, 3, 4, 5, 6];

arr1.filter(
  (element, index) =&gt; {
      if( element % 2 === 0 )
        return console.log(`index : ${index} , element is ${element}`);  
  }
);</code></pre><blockquote>
<p>출력결과
index : 1 , element is 2
index : 3 , element is 4
index : 5 , element is 6</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[학습] 요소전개 및 분해할당]]></title>
            <link>https://velog.io/@real_q_kakaoki/%ED%95%99%EC%8A%B5-%EC%9A%94%EC%86%8C%EC%A0%84%EA%B0%9C-%EB%B0%8F-%EB%B6%84%ED%95%B4%ED%95%A0%EB%8B%B9</link>
            <guid>https://velog.io/@real_q_kakaoki/%ED%95%99%EC%8A%B5-%EC%9A%94%EC%86%8C%EC%A0%84%EA%B0%9C-%EB%B0%8F-%EB%B6%84%ED%95%B4%ED%95%A0%EB%8B%B9</guid>
            <pubDate>Tue, 04 Mar 2025 05:18:57 GMT</pubDate>
            <description><![CDATA[<ul>
<li>배열의 요소를 하나씩 꺼내는(전개) 연산자<pre><code class="language-js">let arr1 = [1, 2, 3];
console.log(arr1);         // [ 1, 2, 3 ]
console.log(...arr1);     // 1 2 3
</code></pre>
</li>
</ul>
<pre><code>- 배열의 얕은 복사와 깊은 복사
```js
let arr1 = [1, 2, 3];
let arr2 = arr1; // 얕은 복사(참조값 복사)

let arr3 = [4, 5, 6];
let arr4 = [...arr3]; // 깊은 복사
</code></pre><ul>
<li>배열의 합성<pre><code>let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let arr3 = [...arr1, ...arr2];</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[학습] 패키지관리자]]></title>
            <link>https://velog.io/@real_q_kakaoki/%ED%95%99%EC%8A%B5-%ED%8C%A8%ED%82%A4%EC%A7%80%EA%B4%80%EB%A6%AC%EC%9E%90</link>
            <guid>https://velog.io/@real_q_kakaoki/%ED%95%99%EC%8A%B5-%ED%8C%A8%ED%82%A4%EC%A7%80%EA%B4%80%EB%A6%AC%EC%9E%90</guid>
            <pubDate>Tue, 04 Mar 2025 01:15:10 GMT</pubDate>
            <description><![CDATA[<ul>
<li>NPM 은 많은 사람들이 만들어 둔 패키지의 공개 저장소이며, 이를 이용하는 명령어는 npm 이다.</li>
<li>아래와 같은 명령어를 이용하여 패키지를 설치할 수 있다.<pre><code>  npm install [패키지이름] </code></pre></li>
<li>패키지를 설치하면 package.json 파일과 package-lock.json 파일이 자동으로 생성 및 업데이트 된다.
(1) package.json 파일은 프로젝트에서 사용하는 패키지의 종류와 버전을 기록한다.
(2) package-lock.json 파일은 패키지들 사이의 의존성 관계를 트리의 형태로 관리한다.</li>
<li>package.json 과 package-lock.json 파일로부터 node_modules 라는 폴더 안에다가 실제 패키지들을 설치하여 프로젝트에서 사용할 수 있도록 한다. 그렇기 때문에 node_modules 폴더는 용량이 매우 크며, 실제로 git허브 등에 커밋하지 않아도 된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[복습용] 리액트 라우터의 사용 ( react router )]]></title>
            <link>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5%EC%9A%A9-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%9D%BC%EC%9A%B0%ED%84%B0%EC%9D%98-%EC%82%AC%EC%9A%A9-react-router</link>
            <guid>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5%EC%9A%A9-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%9D%BC%EC%9A%B0%ED%84%B0%EC%9D%98-%EC%82%AC%EC%9A%A9-react-router</guid>
            <pubDate>Wed, 26 Feb 2025 04:46:15 GMT</pubDate>
            <description><![CDATA[<p>라우터는 페이지의 전환을 위하여 사용한다.</p>
<blockquote>
<p>a 태그는 페이지를 전환하면서 화면을 새로고침한다. 그러나, 라우터는 페이지를 새로고침하지 않으며 페이지를 전환할 수 있기 때문에 렌더링을 최소화하여 빠르게 화면전환이 가능하다.</p>
</blockquote>
<p>(1) 라우터를 설치한다. 라우터를 설치할 프로젝트 상단 폴더에서 터미널을 열고 아래와 같이 명령어를 입력한다. ( 설치 후에는 package.json 파일의 dependencies 에서 설치된 라우터의 버전을 확인할 수 있다. )</p>
<pre><code class="language-cmd">npm install react-router-dom</code></pre>
<p>(2) BrowserRouter 는 Routers 로 감싸고, Routers 는 여러 개의 Route 를 감싸는 형태로 사용할 수 있다. </p>
<pre><code class="language-js">&lt;BrowserRouter&gt;
    &lt;Routes&gt;
        &lt;Route path=&quot;/&quot; element={&lt;Main&gt;&lt;/Main&gt;}&gt;&lt;/Route&gt;
        &lt;Route path=&quot;/About&quot; element={&lt;About&gt;&lt;/About&gt;}&gt;&lt;/Route&gt;
        &lt;Route path=&quot;/QNA&quot; element={&lt;QNA&gt;&lt;/QNA&gt;}&gt;&lt;/Route&gt;
    &lt;/Routes&gt;
&lt;/BrowserRouter&gt;</code></pre>
<ul>
<li>Route 컴포넌트의 path 속성에 페이지의 경로를 지정하고, elememt 속성에 원하는 페이지(컴포넌트)를 지정한다.</li>
</ul>
<pre><code class="language-js">&lt;Route path=&quot;페이지경로&quot; element={&lt;Component&gt;&lt;/Component&gt;}&gt;&lt;/Route&gt;</code></pre>
<ul>
<li>Link 컴포넌트는 마치 a 태그와 같은 역할을 하며, 페이지간 전환(이동)을 가능하게 한다. 단, a 링크를 사용하면 페이지의 전환 시 새로고침이 일어나지만 Link 컴포넌트를 이용하면 새로고침이 일어나지 않는다. ( Link 컴포넌트는 BrowserRouter 로 감싸야 한다. ) </li>
</ul>
<pre><code class="language-js">&lt;BrowserRouter&gt;
      &lt;Link to=&quot;/&quot;&gt; Main 페이지로 이동 &lt;/Link&gt;
      &lt;Link to=&quot;/About&quot;&gt; About 페이지로 이동 &lt;/Link&gt;
    &lt;Link to=&quot;/QNA&quot;&gt; QNA 페이지로 이동 &lt;/Link&gt;
    &lt;Routes&gt;
        &lt;Route path=&quot;/&quot; element={&lt;Main&gt;&lt;/Main&gt;}&gt;&lt;/Route&gt;
        &lt;Route path=&quot;/About&quot; element={&lt;About&gt;&lt;/About&gt;}&gt;&lt;/Route&gt;
        &lt;Route path=&quot;/QNA&quot; element={&lt;QNA&gt;&lt;/QNA&gt;}&gt;&lt;/Route&gt;
    &lt;/Routes&gt;
&lt;/BrowserRouter&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[import 할 때 중괄호를 쓰는 이유]]></title>
            <link>https://velog.io/@real_q_kakaoki/import-%ED%95%A0-%EB%95%8C-%EC%A4%91%EA%B4%84%ED%98%B8%EB%A5%BC-%EC%93%B0%EB%8A%94-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@real_q_kakaoki/import-%ED%95%A0-%EB%95%8C-%EC%A4%91%EA%B4%84%ED%98%B8%EB%A5%BC-%EC%93%B0%EB%8A%94-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Tue, 25 Feb 2025 00:35:52 GMT</pubDate>
            <description><![CDATA[<p>(1) export 할 때, default 로 지정된 대상은 import 할 때 중괄호를 쓸 필요가 없으며, import 할 때 이름도 마음대로 지정할 수 있다.</p>
<pre><code class="language-javascript">//[A.js]
export default myArray = 1;

//[B.js]
import arr from &quot;./A.js&quot;</code></pre>
<hr>
<p>(2) export 할 때, default 로 지정되지 않은 대상은 import 할 때 중괄호 { } 의 내부에 써야하며, 이름도 export 할 때의 이름을 그대로 써야한다. 만약, 다른 이름으로 import 하고 싶다면 as 키워드를 사용한다.</p>
<pre><code class="language-javascript">//[C.js]
export myMap = 2;

 //[D.js]
import { myMap as MAP } from &quot;./C.js&quot;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[복습용] State]]></title>
            <link>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5%EC%9A%A9-State</link>
            <guid>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5%EC%9A%A9-State</guid>
            <pubDate>Mon, 24 Feb 2025 14:28:48 GMT</pubDate>
            <description><![CDATA[<p>리액트 16.8 버전부터는 함수형 컴포넌트에서 훅을 이용한 상태(State)의 관리가 가능하게 되었다.</p>
<p>기본적인 훅</p>
<ul>
<li>useState</li>
<li>userEffect</li>
<li>useContext</li>
</ul>
<p>추가적인 훅</p>
<ul>
<li>useReducer</li>
<li>useCallback</li>
<li>useMemo</li>
<li>useRef</li>
<li>useImperativeHandle</li>
<li>useLayoutEffect</li>
<li>useDebugValue</li>
</ul>
<p>이 외에 사용자정의 훅도 사용할 수 있다.</p>
<pre><code>import {useState} from &#39;react&#39;;

export default function Hello() {
    // name : 변수의 이름
    // setName : 변수를 변경하는 함수
    // setName 이라는 함수를 통해서 name 변수를 변경하면 렌더링을 자동으로 한다.
    // useStat() 는 배열을 반환하며, 매개변수는 name 의 초기값이 들어간다.
    const [name, setName] = useState(&#39;Mike&#39;);

    function changeName() {
        const newName = name === &quot;Mike&quot; ? &quot;Jane&quot; : &quot;Mike&quot;;
        setName(newName);
    }

    return (
        &lt;div&gt;
            &lt;h1&gt; State &lt;/h1&gt;
            &lt;h2&gt; {name} &lt;/h2&gt;
            &lt;button onClick={changeName}&gt; Change &lt;/button&gt;
        &lt;/div&gt;
    );
}</code></pre><p>위의 name 이라는 state 는 컴포넌트마다 따로 관리가 되기 때문에 Hello 컴포넌트가 3개 존재할 때, 첫 번째 name 이 바뀌어도 나머지 2개의 컴포넌트의 name 은 바뀌지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[복습용] 컴포넌트의 태그에 CSS 적용]]></title>
            <link>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5%EC%9A%A9-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%9D%98-%ED%83%9C%EA%B7%B8%EC%97%90-CSS-%EC%A0%81%EC%9A%A9</link>
            <guid>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5%EC%9A%A9-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%9D%98-%ED%83%9C%EA%B7%B8%EC%97%90-CSS-%EC%A0%81%EC%9A%A9</guid>
            <pubDate>Mon, 24 Feb 2025 06:48:29 GMT</pubDate>
            <description><![CDATA[<p>컴포넌트에 포함되는 태그에 CSS 를 적용하는 방법</p>
<p>(1) 태그에 직접 인라인 스타일로 적용하는 방법. 이 때, CSS 문법에서의 대쉬 &quot;-&quot;를 쓰지 않고, 카멜케이스로 적어야 한다. (예: border-right 대신에 borderRight 로 적는다 ) 하지만 큰 프로젝트에서는 적용하기 힘든 방법이다.</p>
<pre><code>export default function Component () {
    return (
        &lt;div&gt;
            &lt;p style={
                {
                    color: &#39;red&#39;,
                    borderRight: &#39;2px solid #000&#39;,
                    backgroundColor: &#39;blue&#39;,
                    marginBottom: &#39;30px&#39;,
                    opacity: 1,
                }
            }&gt;
                Hello
            &lt;/p&gt;
        &lt;/div&gt;
    );
}</code></pre><p>(2) 컴포넌트별 css 모듈을 작성하고 이용하는 방법. 
Hello.js 모듈에서 사용할 css 는 Hello.module.css 파일에 작성한다.
css 파일이 header 에서 중복되는 문제를 해결할 수 있다.</p>
<pre><code class="language-css">/* Hello.module.css */
.box {
    width: 200px;
    height: 50px;
    background-color: blueviolet;
}</code></pre>
<pre><code class="language-js">// Hello.js
import styles from &quot;./Hello.module.css&quot;;

export default function Hello () {
    return (
        &lt;div&gt;
            &lt;p className={styles.box}&gt; 
                Hello 
            &lt;/p&gt;
        &lt;/div&gt;
    );
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[복습용] 컴포넌트 작성]]></title>
            <link>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5%EC%9A%A9-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%9E%91%EC%84%B1</link>
            <guid>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5%EC%9A%A9-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%9E%91%EC%84%B1</guid>
            <pubDate>Mon, 24 Feb 2025 06:28:24 GMT</pubDate>
            <description><![CDATA[<p>컴포넌트의 작성</p>
<p>(1) 컴포넌트는 함수로 작성하며, 컴포넌트 이름은 대문자로 시작한다.
(2) export 하여 다른 파일에서 사용할 수 있도록 한다.
(3) return 값은 반드시 하나의 태그를 반환하도록 한다.</p>
<pre><code>export default function Component {
    return (
        &lt;div&gt;
            ...
        &lt;/div&gt;
    );
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[복습용] 리액트 시작하기]]></title>
            <link>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5%EC%9A%A9-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@real_q_kakaoki/%EB%B3%B5%EC%8A%B5%EC%9A%A9-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 24 Feb 2025 05:44:51 GMT</pubDate>
            <description><![CDATA[<p>&lt;복습용&gt;</p>
<p>리액트 프로젝트 시작하기</p>
<p>(1) 먼저 node js 를 설치한다.
(2) 코드에디터(예 visual code 등)를 설치한다.
(3) cmd 또는 power shell 같은 명령창에서 아래 명령어를 입력한다.</p>
<pre><code>    npx create-react-app [폴더이름]</code></pre><p>(4) 코드에디터에서 만들어진 프로젝트 폴더를 열고 터미널을 연다.
(5) npm start 명령어를 입력하면 웹페이지가 열린다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 배열의 map 함수로 반복처리]]></title>
            <link>https://velog.io/@real_q_kakaoki/React-%EB%B0%98%EB%B3%B5%EC%9D%80-map-%EC%9C%BC%EB%A1%9C-%EC%B2%98%EB%A6%AC%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8B%A4</link>
            <guid>https://velog.io/@real_q_kakaoki/React-%EB%B0%98%EB%B3%B5%EC%9D%80-map-%EC%9C%BC%EB%A1%9C-%EC%B2%98%EB%A6%AC%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8B%A4</guid>
            <pubDate>Sat, 07 Dec 2024 01:04:49 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-javascript">let arr = [2, 4, 6, 8];

// element : 배열의 각 요소
// index : 배열의 요소 인덱스
// array : 배열 전체
let newArr = arr.map((element, index, array) =&gt; {
    console.log(element);
    console.log(index);
    console.log(array);
});

// -- 결과 --

// 2
// 0
// [ 2, 4, 6, 8 ]

// 4
// 1
// [ 2, 4, 6, 8 ]

// 6
// 2
// [ 2, 4, 6, 8 ]

// 8
// 3
// [ 2, 4, 6, 8 ]</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] import / require]]></title>
            <link>https://velog.io/@real_q_kakaoki/React-import-require</link>
            <guid>https://velog.io/@real_q_kakaoki/React-import-require</guid>
            <pubDate>Sat, 07 Dec 2024 00:51:20 GMT</pubDate>
            <description><![CDATA[<h1 id="require-는-node-의-모듈시스템">require 는 node 의 모듈시스템</h1>
<ol>
<li><p>아래의 두 코드는 같은 기능이다.
// 노드에서는 require 만 사용가능하다
const React = require(&#39;react&#39;);
// 바벨이 import 를 require 로 바꿔준다.
import React from &#39;react&#39;;</p>
</li>
<li><p>export 되는 것이 &quot;객체&quot;이거나 &quot;배열&quot;이라면 구조분해의 형식으로 import/require 할 수 있다.</p>
</li>
<li><p>내보낼 때, default 가 아니라면 여러번 내보내기가 가능하다.
export const hello = &#39;hello&#39;; 
가져올 때,
import { hello }</p>
</li>
</ol>
<p>내보낼 때, default 는 한 번만 사용 가능하다.
export default NumberBaseball;
가져올 때,
import NumberBaseball;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] webpack 설정하기]]></title>
            <link>https://velog.io/@real_q_kakaoki/React-webpack-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@real_q_kakaoki/React-webpack-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 29 Nov 2024 10:42:37 GMT</pubDate>
            <description><![CDATA[<ul>
<li>웹팩의 설치와 설정</li>
</ul>
<ol>
<li>node 설치</li>
<li>VS code 에서 프로젝트 폴더를 생성하고 터미널을 연다.</li>
<li>npm init 을 입력하여 프로젝트를 초기화 한다. (npm : 노드패키지매니저)</li>
<li>npm i react react-dom 을 입력하여 설치한다.</li>
<li>npm i -D webpack webpack-cli 를 입력하여 설치한다. (-D : 개발용)</li>
<li>npm i -D @babel/core @babel/preset-env @babel/preset-react @babel-loader</li>
</ol>
<ul>
<li>webpack 설정 파일</li>
</ul>
<ol start="7">
<li>프로젝트 폴더에 webpack.config.js 를 생성한다.<pre><code class="language-javascript">const path = require(&quot;path&quot;);
</code></pre>
</li>
</ol>
<p>module.exports = {
  name: &quot;project-name&quot;,         // 모듈이름
  mode: &#39;development&#39;,             // 배포시 : production
  devtool: &quot;inline-source-map&quot;, // 소스맵 생성 여부와 방법을 제어
  resolve: {                    // 모듈을 해석하는 방식 
    extensions: [&quot;.js&quot;, &quot;.jsx&quot;],
  },
  entry: {    // file.js 를 대상으로 웹팩이 빌드를 수행
    app: [&quot;./file.js&quot;],
  },
  module: {
    rules: [
      {
        // babel-loader를 이용해 규칙에 적용
        test: /.jsx?/,
        loader: &quot;babel-loader&quot;,
        options: {
          presets: [&quot;@babel/preset-env&quot;, &quot;@babel/preset-react&quot;],
        },
      },
    ],
  },
  // 컴파일 + 번들링된 js 파일이 저장될 경로와 이름 지정
  output: {
    path: path.join(__dirname, &quot;dist&quot;),
    filename: &quot;app.js&quot;,
  },
};</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[픽셀아트] 걷기]]></title>
            <link>https://velog.io/@real_q_kakaoki/%ED%94%BD%EC%85%80%EC%95%84%ED%8A%B8-%EA%B1%B7%EA%B8%B0</link>
            <guid>https://velog.io/@real_q_kakaoki/%ED%94%BD%EC%85%80%EC%95%84%ED%8A%B8-%EA%B1%B7%EA%B8%B0</guid>
            <pubDate>Thu, 29 Jun 2023 14:05:47 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/real_q_kakaoki/post/43529604-5a32-42c2-b3a7-a8ef1f74c286/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <link>https://velog.io/@real_q_kakaoki/7yc300oh</link>
            <guid>https://velog.io/@real_q_kakaoki/7yc300oh</guid>
            <pubDate>Thu, 29 Jun 2023 13:08:05 GMT</pubDate>
            <description><![CDATA[<ol>
<li><p>단색
<img src="https://velog.velcdn.com/images/real_q_kakaoki/post/85b71e9a-33ba-466e-9b3d-099c55e52613/image.png" alt=""></p>
</li>
<li><p>인접색상
<img src="https://velog.velcdn.com/images/real_q_kakaoki/post/66602520-1c06-47d3-a2b9-911f09da72f6/image.png" alt=""></p>
</li>
<li><p>보색
<img src="https://velog.velcdn.com/images/real_q_kakaoki/post/7dec41c7-5071-4ab0-b26d-34aae222d621/image.png" alt=""></p>
</li>
</ol>
]]></description>
        </item>
    </channel>
</rss>