<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Jaewook.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sat, 13 Aug 2022 13:21:48 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Jaewook.log</title>
            <url>https://images.velog.io/images/dev-jwjeong/profile/f8dd7c2e-d712-4b40-a531-74c793114b40/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Jaewook.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev-jwjeong" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Redux Toolkit을 사용해 보자]]></title>
            <link>https://velog.io/@dev-jwjeong/Redux-Toolkit%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%B4-%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@dev-jwjeong/Redux-Toolkit%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%B4-%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Sat, 13 Aug 2022 13:21:48 GMT</pubDate>
            <description><![CDATA[<h2 id="redux-toolkit-이란-뭘까">Redux Toolkit 이란 뭘까?</h2>
<p>RTK의 핵심은 리덕스의 복잡함을 낮추고 사용성을 개선하는 것입니다.
그럼 리덕스는 왜 복잡하다고 생각할까요?</p>
<ul>
<li>리덕스에는 보일러 플레이트가 너무 많습니다. 하나의 상태를 관리하기 위해서 액션 타입, 액션 생성 함수, 리듀서를 작성해야 하는 번거로움이 있습니다.</li>
<li>리덕스의 초기 환경설정을 하는 과정이 복잡합니다.</li>
<li>리덕스를 잘 사용하기 위해서 많은 패키 치를 설치해야 합니다.</li>
<li>불변성을 지키기 위해 spread를 사용하거나 immer 등 다른 라이브러리를 사용해야 합니다.</li>
</ul>
<h2 id="rtk의-장점은-뭘까">RTK의 장점은 뭘까?</h2>
<ul>
<li>기본적은 immer가 내장되어 있어 상태의 불변성을 지키는 것이 매우 편리하다.</li>
<li>타입 스크립트를 지원하고 있다.</li>
<li>redux thunk가 내장되어 있어 비동기 작업이 수월하다</li>
<li>보일러 플레이트가 필요 없이 내장 함수 하나만으로 액션 타입, 액션 생성 함수, 리듀서를 작성할 수 있다.</li>
</ul>
<h2 id="rtk-설치">RTK 설치</h2>
<pre><code class="language-javascript">npm install @reduxjs/toolkit //npm

yarn add @reduxjs/toolkit //yarn</code></pre>
<h2 id="configurestore">configureStore</h2>
<p>redux와 같이 store를 생성해 줍니다.
configureStore를 통해 reducer를 정의해 줍니다.
또한 store.getState를 통해서 state의 값을 가져옵니다.</p>
<pre><code class="language-javascript">import { configureStore } from &#39;@reduxjs/toolkit&#39;
// ...
const store = configureStore({
  reducer: {
    one: oneSlice.reducer,
    two: twoSlice.reducer,
  },
})

//state
export type RootState = ReturnType&lt;typeof store.getState&gt;
//dispatch
export const useAppDispatch: () =&gt; AppDispatch = useDispatch

export default store</code></pre>
<h2 id="createslice">createSlice</h2>
<p>createSlice를 통해서 reducer를 간단하게 정의할 수 있습니다.
간단한 counter 예제를 통해 알아보겠습니다.</p>
<p>createSlice 안에는 name, initialState, reducers로 구성될 수 있습니다.
RTK의 장점에서 봤듯이 immer가 내장되어 있기 때문에 불변성을 신경 쓰지 않고 코드를 작성할 수 있습니다.</p>
<pre><code class="language-javascript">import { createSelector, createSlice, PayloadAction } from &#39;@reduxjs/toolkit&#39;;
import { RootState } from &#39;./store&#39;;

//initialState의 타입
interface CounterState {
  count: number;
  countExtra: number;
}

const initialState: CounterState = {
  count: 0,
  countExtra: 0,
};

//createSlice
export const counterSlice = createSlice({
  name: &#39;counter&#39;,
  initialState,
  reducers: {
    increase: (state) =&gt; {
      state.count += 1;
    },
    decrease: (state) =&gt; {
      state.count -= 1;
    },
    increaseBy: (state, action: PayloadAction&lt;number&gt;) =&gt; {
      state.count += action.payload;
    },
  },
});

export const { increase, decrease, increaseBy } = counterSlice.actions;
export default counterSlice.reducer;</code></pre>
<h2 id="createselector">CreateSelector</h2>
<p>createSelector는 우리가 알고 있는 Reselect와 동일합니다.
먼저 살펴보기 전에 기존에 사용해왔던 useSelector의 문제점을 알아봅시다.</p>
<h3 id="useselector">useSelector</h3>
<p>useSelector는 store에서 필요한 state를 가져와서 사용하기 위해 사용하는 함수이다.</p>
<ul>
<li>리액트는 state가 변경되는 경우 컴포넌트가 re-rendering이 된다.</li>
<li>useSelector를 통해 매번 컴포넌트가 redering 될 때마다 객체를 만들게 되면 매번 dispatch, 또는 해당 컴포넌트에서 값이 바뀌지 않는 state 값도 다시 redering이 되는 문제점이 있다.</li>
</ul>
<p>이렇기 때문에 createSelector는 현재의 state 값을 memoization을 하여 state의 값이 변하지 않는다면 이전에 저장되었던 값을 불러오는 방식으로 불필요한 re-rendering을 막을 수 있다.</p>
<pre><code class="language-javascript">import { createSelector, createSlice, PayloadAction } from &#39;@reduxjs/toolkit&#39;;
import { RootState } from &#39;./store&#39;;

//initialState의 타입
interface CounterState {
  count: number;
  countExtra: number;
}

const initialState: CounterState = {
  count: 0,
  countExtra: 0,
};

//createSlice
export const counterSlice = createSlice({
  name: &#39;counter&#39;,
  initialState,
  reducers: {
    increase: (state) =&gt; {
      state.count += 1;
    },
    decrease: (state) =&gt; {
      state.count -= 1;
    },
    increaseBy: (state, action: PayloadAction&lt;number&gt;) =&gt; {
      state.count += action.payload;
    },
  },
});


//createSelector
//count의 값만 참조하는 selector 반환
const countSelector = (state: RootState): number =&gt; {
  return state.counter.count | initialState.count;
};
//countExtra값만 참조하는 selector 반환
const countExtraSelector = (state: RootState): number =&gt; {
  return state.counter.countExtra | initialState.countExtra;
};

//위에 정의한 2개의 함수로 createSelector 생성
export const counterSelector = createSelector(
  countSelector,
  countExtraSelector,
  (count, countExtra) =&gt; ({
    count,
    countExtra,
  }),
);

export const { increase, decrease, increaseBy } = counterSlice.actions;
export default counterSlice.reducer;</code></pre>
<h2 id="정리">정리</h2>
<p>무엇보다도 코드의 양을 줄일 수 있다는 것이 굉장한 장점인 것 같다.
매번 액션 타입, 액션 생성 함수, 리듀스를 작성하는 것에 피로감을 느끼고 있었기 때문에,,</p>
<p>아직 모든 기능을 사용해 보지는 않았지만 다른 많은 기능이 있기 때문에 공식 문서를 통해 알아보는 것이 중요할 거 같다.</p>
<h2 id="참조">참조</h2>
<p><a href="https://redux-toolkit.js.org/">https://redux-toolkit.js.org/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React Hook Form을 사용해보자]]></title>
            <link>https://velog.io/@dev-jwjeong/React-Hook-Form%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@dev-jwjeong/React-Hook-Form%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Sun, 07 Aug 2022 10:38:26 GMT</pubDate>
            <description><![CDATA[<h2 id="react-hook-form이란-뭘까">React Hook Form이란 뭘까?</h2>
<p>공식 문서에는 유연하고 확장 가능한 사용하기 쉬운 고성능 폼 검증 라이브러리라고 소개되어 있다.</p>
<ul>
<li>작성하는 코드 양이 줄어든다</li>
<li>컴포넌트의 리랜더링을 분리할 수 있다.<ul>
<li>여러 input의 상태를 관리해야 할 때 전체 폼이 리랜더링되지 않게 관리할 수 있다.</li>
</ul>
</li>
<li>유효성 검사에 탁월하다</li>
<li>TypeScript를 기본적으로 지원한다</li>
<li>hook기반이기 때문에 제공하는 useForm hook을 통해 거의 모든 기능을 사용할 수 있다.<h2 id="시작해봅시다">시작해봅시다.</h2>
React Hook Form을 설치하는 커맨드는 간단합니다.<pre><code>npm install react-hook-form //npm 사용
</code></pre></li>
</ul>
<p>yarn add react-hook-form //yarn 사용</p>
<pre><code>

## Register
&gt; useState대신에 쉽고 적은 코드로 input 값을 가져 올 수 있습니다. 

```javascript
export default function App() {
  const { register } = useForm();

  return(
    &lt;input {...register(&quot;username&quot;)} /&gt;
      &lt;input {...register(&quot;password&quot;)} /&gt;
  );
}</code></pre><p>register를 통해서 user name이라는 이름으로 name 필드를 바로 사용할 수 있고 value, onChange 기능이 register 하나로 처리될 수 있습니다.</p>
<p>만약 내가 작성하고 있는 input의 값을 알고 싶다면?</p>
<pre><code class="language-javascript">export default function App() {
  const { register, watch } = useForm();

  console.log(watch()); //입력받고 있는 input의 모든 value
  console.log(watch(&quot;username&quot;)); // username 필드의 input value
  console.log(watch(&quot;password&quot;)); // password 필드의 input value

  return(
    &lt;input {...register(&quot;username&quot;)} /&gt;
      &lt;input {...register(&quot;password&quot;)} /&gt;
  );
}</code></pre>
<p>watch를 통해서 input 필드의 value 값을 가져올 수 있습니다.</p>
<h2 id="유효성-검사">유효성 검사</h2>
<blockquote>
</blockquote>
<p>input 값의 유효성 검사는 formState의 errors 객체로 쉽게 확인할 수 있습니다.
오류가 생긴 input 필드로 자동 focus가 잡히는 것도 확인할 수 있습니다</p>
<pre><code class="language-javascript">export default function App() {
  const { register, watch, formState : {errors}} = useForm();

  cons
  return(
    &lt;input {...register(&quot;username&quot;, {required : true, minLength : { value : 10, message : &quot;10글자 이상 입력해주세요&quot;})} /&gt;
      &lt;input {...register(&quot;password&quot;), {required : true} /&gt;
  );
}</code></pre>
<h2 id="handlesubmit">handleSubmit</h2>
<blockquote>
<p>지금까지 form의 onSubmit 할 때 페이지 re-load를 막기 위해서 e.preventDefault를 사용해 왔습니다.
하지만 handleSubmit을 사용하면 e.preventDefault가 필요 없습니다.</p>
</blockquote>
<pre><code class="language-javascript">export default function App() {
  const { register, watch, formState : {errors}, handleSubmit} = useForm();

  const onSubmit = (data) =&gt; {
    console.log(data);
  }

  return(
    &lt;form onSubmit = {handleSubmit(onSubmit)}&gt;
         &lt;input {...register(&quot;username&quot;, {required : true, minLength : { value : 10, message : &quot;10글자 이상 입력해주세요&quot;})} /&gt;
          &lt;input {...register(&quot;password&quot;), {required : true} /&gt;
      &lt;/form&gt;
  );
}</code></pre>
<p>form을 제출할 onSubmit 함수를 handleSubmit으로 감싸주면 끝입니다.</p>
<p>handleSubmit을 통해 onSubmit 함수는 data를 인자로 받을 수 있고 data를 통해서 form으로 관리되는 data를 확인할 수 있다.</p>
<h3 id="결론">결론</h3>
<p>register, handleSubmit, formState 말고도 여러 가지 api들이 있다.
여러 개의 input 상태를 관리해야 할 때 쓰기 좋을 것 같다.</p>
<hr>
<h2 id="출처">출처</h2>
<p><a href="https://react-hook-form.com/kr/">react-hook-form</a></p>
]]></description>
        </item>
    </channel>
</rss>