<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>super_iaan.log</title>
        <link>https://velog.io/</link>
        <description>code runner</description>
        <lastBuildDate>Tue, 13 Apr 2021 07:41:31 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>super_iaan.log</title>
            <url>https://images.velog.io/images/super_iaan/profile/cb2ce14e-1c37-4e50-a121-1a8eb52d7159/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. super_iaan.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/super_iaan" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[CSS table-layout:fixed를 했는데 th, td 한 부분만 너비를 변경하고 싶다고?]]></title>
            <link>https://velog.io/@super_iaan/CSS-table-layoutfixed%EB%A5%BC-%ED%96%88%EB%8A%94%EB%8D%B0-th-td-%ED%95%9C-%EB%B6%80%EB%B6%84%EB%A7%8C-%EB%84%88%EB%B9%84%EB%A5%BC-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B3%A0-%EC%8B%B6%EB%8B%A4%EA%B3%A0</link>
            <guid>https://velog.io/@super_iaan/CSS-table-layoutfixed%EB%A5%BC-%ED%96%88%EB%8A%94%EB%8D%B0-th-td-%ED%95%9C-%EB%B6%80%EB%B6%84%EB%A7%8C-%EB%84%88%EB%B9%84%EB%A5%BC-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B3%A0-%EC%8B%B6%EB%8B%A4%EA%B3%A0</guid>
            <pubDate>Tue, 13 Apr 2021 07:41:31 GMT</pubDate>
            <description><![CDATA[<p>table을 하면서 규격을 한방에 맞추려고 table-layout:fixed;  옵션을 주어버렸다. 
그러니까 화면에는 이쁘게 출력되지만 너비조정이 불가하게 되어버린 상황...
고럴때 바로 태그네임(colgroup과 col)이 필요하다.</p>
<pre><code> &lt;table&gt;
   &lt;colgroup&gt;
     &lt;col style={{ width: &#39;15%&#39; }} /&gt;
     &lt;col style={{ width: &#39;45%&#39; }} /&gt;
     &lt;col style={{ width: &#39;40%&#39; }} /&gt;
   &lt;/colgroup&gt;            
   &lt;thead&gt;
     &lt;tr&gt;
       &lt;th colSpan={3}&gt;우리집 소식&lt;/th&gt;
     &lt;/tr&gt;
   &lt;/thead&gt;
   &lt;tbody&gt;
     &lt;tr&gt;
       &lt;td&gt;1&lt;/td&gt;
       &lt;td&gt;101동 104호&lt;/td&gt;
       &lt;td&gt;2021-03-28&lt;/td&gt;
     &lt;/tr&gt;
   &lt;/tbody&gt;
 &lt;/table&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Redux toolkit 을 React에 적용하기 ep.2 (counter 예제)]]></title>
            <link>https://velog.io/@super_iaan/Redux-toolkit-%EC%9D%84-React%EC%97%90-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-ep.2-counter-%EC%98%88%EC%A0%9C</link>
            <guid>https://velog.io/@super_iaan/Redux-toolkit-%EC%9D%84-React%EC%97%90-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-ep.2-counter-%EC%98%88%EC%A0%9C</guid>
            <pubDate>Fri, 02 Apr 2021 05:16:05 GMT</pubDate>
            <description><![CDATA[<p>CRA(create-react-app) +Typescript 위에서 redux-toolkit 공식문서에 있는 간단한 카운터를 따라해보자</p>
<pre><code>//src/index.js
import React from &#39;react&#39;
import ReactDOM from &#39;react-dom&#39;
import &#39;./index.css&#39;
import App from &#39;./App&#39;
import store from &#39;./app/store&#39;
import { Provider } from &#39;react-redux&#39;

ReactDOM.render(
  &lt;Provider store={store}&gt;
    &lt;App /&gt;
  &lt;/Provider&gt;,
  document.getElementById(&#39;root&#39;)
)</code></pre><pre><code>//src/store
import { configureStore } from &#39;@reduxjs/toolkit&#39;;
import { TypedUseSelectorHook, useDispatch, useSelector } from &#39;react-redux&#39;;
import countSlice from &#39;src/store/counter/counterSlice&#39;;
const store = configureStore({
  reducer: { counter: countSlice },
});

export default store;

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType&lt;typeof store.getState&gt;;
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;

// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = () =&gt; useDispatch&lt;AppDispatch&gt;();
export const useAppSelector: TypedUseSelectorHook&lt;RootState&gt; = useSelector;
</code></pre><pre><code>//src/store/counter/counterSlice
import { createSlice, PayloadAction } from &#39;@reduxjs/toolkit&#39;;
import { RootState, useAppSelector, useAppDispatch } from &#39;src/store&#39;;

interface CounterState {
  value: number;
}

// Define the initial state using that type
const initialState: CounterState = {
  value: 0,
};

export const counterSlice = createSlice({
  name: &#39;counter&#39;,
  initialState,
  reducers: {
    increment: (state) =&gt; {
      state.value = state.value + 1;
    },
    decrement: (state) =&gt; {
      state.value = state.value - 1;
    },
    incrementByAmount: (state, action: PayloadAction&lt;number&gt;) =&gt; {
      state.value = state.value + action.payload;
    },
  },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;

export function HooksCounter() {
  const count = useAppSelector((state: RootState) =&gt; state.counter.value);
  const dispatch = useAppDispatch();

  return {
    count,
    dispatch,
  };
}

export default counterSlice.reducer;
</code></pre><pre><code>//src/components/Counter/CounterComponent
import React from &#39;react&#39;;
import { decrement, increment, HooksCounter } from &#39;src/store/counter/counterSlice&#39;;
export default function CounterComponent() {
  const { count, dispatch } = HooksCounter();
  return (
    &lt;div&gt;
      &lt;button aria-label=&quot;Increment value&quot; onClick={() =&gt; dispatch(increment())}&gt;
        Increment
      &lt;/button&gt;
      &lt;span&gt;{count}&lt;/span&gt;
      &lt;button aria-label=&quot;Decrement value&quot; onClick={() =&gt; dispatch(decrement())}&gt;
        Decrement
      &lt;/button&gt;
    &lt;/div&gt;
  );
}

</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Redux toolkit 을 React에 적용하기 ep.1 (설치 및 api 설명)]]></title>
            <link>https://velog.io/@super_iaan/Redux-toolkit-%EC%9D%84-React%EC%97%90-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-ep.1-%EC%84%A4%EC%B9%98-%EB%B0%8F-api-%EC%84%A4%EB%AA%85</link>
            <guid>https://velog.io/@super_iaan/Redux-toolkit-%EC%9D%84-React%EC%97%90-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-ep.1-%EC%84%A4%EC%B9%98-%EB%B0%8F-api-%EC%84%A4%EB%AA%85</guid>
            <pubDate>Fri, 02 Apr 2021 04:38:10 GMT</pubDate>
            <description><![CDATA[<p>공식문서 참고
<a href="https://redux-toolkit.js.org/introduction/getting-started%5B%EB%A7%81%ED%81%AC%ED%85%8D%EC%8A%A4%ED%8A%B8%5D(https://redux-toolkit.js.org/introduction/getting-started)">https://redux-toolkit.js.org/introduction/getting-started[링크텍스트](https://redux-toolkit.js.org/introduction/getting-started)</a></p>
<p>맨날 redux랑 redux-saga를 접합하여 쓰다가 container와 component 및 module,saga 구조로 코드를 짜다보니 코드를 쓸 양이 방대해지기도 하고 이제 질리기도 하여 .. 핫하다는 redux-toolkit을 사용해보기로 함!</p>
<p>우선 react를 띄웠다고 가정하고 시작!</p>
<p>redux-toolkit 설치 명령어</p>
<pre><code>#npm
npm install @reduxjs/toolkit

#yarn
yarn add @reduxjs/toolkit</code></pre><p>redux-toolkit이 가지고 있는 api</p>
<pre><code>import {configureStore, createReducer, createAction, createSlice, createAsyncThunk, createEntityAdapter, createSelector} from &quot;@reduxjs/toolkit&quot;

1. configureStore :  슬라이스 리듀서를 자동으로 결합하고 제공하는 Redux 미들웨어를 추가하고, 기본적으로 redux-thunk를 포함하며 Redux DevTools Extension을 사용할 수 있게 해줌 ( configureStore 자체가 내장이 되어있다니! )
2. createReducer : switch문 없이 알아서 action과 reducer를 감지해준다. (immer자체가 내장이 되어있다!! 와우)
3. createAction : action type을 받아서 action을 발생시킨다.
4. createSlice : reducer, initialState, slice이름을 하나로 묶어서 사용가능하게 함 (리듀서 함수 세트 메뉴라고 생각하면 된다)
5. createAsyncThunk : 비동기 담당하고 있다! action type을 받아서  =&gt; promise값을 내보내고 &quot;pending / fulfilled / rejected&quot;를 dispatch하는 thunk를 만들어준다 
6. createEntityAdapter : store에 들어있는 data를 관리하기 위한 재사용이 가능한 reducer와 selector를 만들어준다
7. createSelector :  state값들을 사용하기 쉽게 내보내주는 역할 (영문설명: re-exported for ease of use)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[import {combineReducers, createStore, applyMiddleware, compose } from 'redux ' 란 무엇인가? ]]></title>
            <link>https://velog.io/@super_iaan/import-combineReducers-createStore-applyMiddleware-compose-from-redux-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@super_iaan/import-combineReducers-createStore-applyMiddleware-compose-from-redux-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Tue, 30 Mar 2021 04:03:02 GMT</pubDate>
            <description><![CDATA[<h3 id="1-combinereducers">1. combineReducers</h3>
<p>redux를 사용시, 유의할 점은 앱에 하나 이외의 스토어를 만들면 안된다는 것이다. 그렇기에 코드의 유지보수를 위해서 단위별로 reducer를 분기하여 사용하게 되는게 일반적인데 =&gt; 이때, 여러개의 reducer들을 단!!! 하나의 reducer(예시에서는 이게 rootReducer에 해당)로 묶어서(통합된 하나의 스토어를 만들기 위함) 사용하기 위해 combineReducers가 필요하다</p>
<pre><code>예시) 
import { combineReducers } from &#39;redux&#39;;
import loadingReducer from &#39;./loadingReducer&#39;; // 로딩 체크하기 위한 reducer
import errorReducer from &#39;./errorReducer&#39;; // 에러를 체크하기 위한 reducer

const rootReducer = combineReducers({
  isLoading: loadingReducer,
  error: errorReducer,
});

export default rootReducer;</code></pre><h3 id="2-createstore">2. createStore</h3>
<p>앱 내에, 단 하나만 존재해야하는 =&gt; 앱의 상태 트리 전체를 보관하는 Redux 스토어를 만들때 쓰인다.</p>
<pre><code>예시)
import { createStore } from &#39;redux&#39;
import rootReducer from &#39;../reducers&#39;; // 어디에선가 가져오는 rootReducer

const configureStore = () =&gt; {
  const store = createStore(
    rootReducer,
  );
  return store;
}
</code></pre><h3 id="3-applymiddleware">3. applyMiddleware</h3>
<p>applyMiddleware의 존재 이유는 redux에서 비동기를 편리하게 처리하기 위해 미들웨어를 생성하기 위해 필요한 api이다. (미들웨어는 정말 강력하다. 너무 편함...)</p>
<pre><code>예시)
import { createStore, applyMiddleware, compose } from &#39;redux&#39;;
import createSagaMiddleware from &#39;redux-saga&#39;;
import rootReducer from &#39;../reducers&#39;;
import rootSaga from &#39;../saga&#39;;

const sagaMiddleware = createSagaMiddleware();

const configureStore = () =&gt; {
  const store = createStore(
    rootReducer,
    applyMiddleware(sagaMiddleware),
  );

  sagaMiddleware.run(rootSaga);

  return store;
}</code></pre><h3 id="4-compose">4. compose</h3>
<p>redux-saga사용을 위한 middleware를 만들때, 필요!</p>
<p>공식문서를 보면 compose에 대한 정의를 =&gt;  <strong>함수를 오른쪽에서 왼쪽으로 조합합니다.
이것은 함수형 프로그래밍 유틸리티로, Redux에는 편리함을 위해 포함되었습니다. 여러 스토어 함수(enhancer)들을 순차적으로 적용하기 위해 사용할 수 있습니다</strong> 라고 해놓았다.</p>
<p>이게 무슨 의미인지는 아래 compose의 사용법으로 알 수 있다. </p>
<pre><code>예시)
import { compose } from &#39;redux&#39;;
(args): 인자를 받은 함수의 return 값은 왼쪽에 있는 함수의 인수로 제공되는 식으로 연속된다. 
compose(f, g, h) = (...args) =&gt; f(g(h(...args)))


import { createStore, applyMiddleware, compose } from &#39;redux&#39;;
import createSagaMiddleware from &#39;redux-saga&#39;;

const sagaMiddleware = createSagaMiddleware(); 
const configureStore = () =&gt; {
  const store = createStore(
    rootReducer,
    compose(
      applyMiddleware(sagaMiddleware),
      window.__REDUX_DEVTOOLS_EXTENSION__ &amp;&amp;
        window.__REDUX_DEVTOOLS_EXTENSION__(),
    ),
  );

  sagaMiddleware.run(rootSaga);

  return store;
}
</code></pre><p>해당 내용에 대한 자세한 탐구는 역시 공식문서이다.</p>
<blockquote>
<p>(<a href="https://lunit.gitbook.io/redux-in-korean/api">https://lunit.gitbook.io/redux-in-korean/api</a>)해당 api 더 알아보러가기</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[CRA - react typescript ESlint + Prettier  설정]]></title>
            <link>https://velog.io/@super_iaan/CRA-react-typescript-ESlint-Prettier-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@super_iaan/CRA-react-typescript-ESlint-Prettier-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Mon, 29 Mar 2021 06:49:47 GMT</pubDate>
            <description><![CDATA[<p>해당 내용은 CRA(create-react-app)+ typescript 를 사용할때의 내용이다.</p>
<p>eslint(airbnb 스타일) 와 prettier 동시 사용을 위한 패키지 설치를 위해, CRA의 터미널 창에 하단의 명령어를 입력한다.</p>
<pre><code>yarn add -D eslint prettier
yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser
yarn add -D eslint-config-airbnb
yarn add -D eslint-config-prettier eslint-plugin-prettier
</code></pre><h3 id="eslint-설정">ESlint 설정</h3>
<p>src와 같은 최상위 경로에 .eslintrc 파일 생성</p>
<pre><code>{
  &quot;parser&quot;: &quot;@typescript-eslint/parser&quot;,
  &quot;plugins&quot;: [&quot;@typescript-eslint&quot;, &quot;prettier&quot;],
  &quot; extends&quot;: [
    &quot;airbnb&quot;,
    &quot;plugin:import/errors&quot;,
    &quot;plugin:import/warnings&quot;,
    &quot;plugin:prettier/recommended&quot;,
    &quot;plugin:@typescript-eslint/recommended&quot;,
    &quot;prettier/@typescript-eslint&quot;
  ],
  &quot;rules&quot;: {
    &quot;linebreak-style&quot;: 0,
    &quot;import/prefer-default-export&quot;: 0,
    &quot;prettier/prettier&quot;: 0,
    &quot;import/extensions&quot;: 0,
    &quot;no-use-before-define&quot;: 0,
    &quot;import/no-unresolved&quot;: 0,
    &quot;import/no-extraneous-dependencies&quot;: 0, // 테스트 또는 개발환경을 구성하는 파일에서는 devDependency 사용을 허용
    &quot;no-shadow&quot;: 0,
    &quot;react/prop-types&quot;: 0,
    &quot;react/jsx-filename-extension&quot;: [
      2,
      { &quot;extensions&quot;: [&quot;.js&quot;, &quot;.jsx&quot;, &quot;.ts&quot;, &quot;.tsx&quot;] }
    ],
    &quot;jsx-a11y/no-noninteractive-element-interactions&quot;: 0
  }
}
</code></pre><h3 id="prettier--설정">Prettier  설정</h3>
<p>src와 같은 최상위 경로에 .prettierrc 파일 생성</p>
<pre><code>{
  &quot;singleQuote&quot;: true,
  &quot;semi&quot;: true,
  &quot;useTabs&quot;: false,
  &quot;tabWidth&quot;: 2,
  &quot;trailingComma&quot;: &quot;all&quot;,
  &quot;printWidth&quot;: 120,
  &quot;arrowParens&quot;: &quot;always&quot;
}</code></pre><h3 id="settings-설정">settings 설정</h3>
<p><strong>,</strong> + <strong>command</strong>키를 누르면 setting창이 나온다 </p>
<p>setting창의 내부 검색창에 formatter를 검색 후, </p>
<ol>
<li>Editor: Default Formatter에 <strong>esbenp.prettier-vscode</strong> 를 설정 </li>
<li>Editor: Format On Save 란에 <strong>체크!</strong></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[CRA - react typescript 시작 및 초기 설정]]></title>
            <link>https://velog.io/@super_iaan/CRA-react-typescript-%EC%8B%9C%EC%9E%91-%EB%B0%8F-%EC%B4%88%EA%B8%B0-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@super_iaan/CRA-react-typescript-%EC%8B%9C%EC%9E%91-%EB%B0%8F-%EC%B4%88%EA%B8%B0-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Mon, 29 Mar 2021 05:09:22 GMT</pubDate>
            <description><![CDATA[<p>CRA를 이용하여 react와 typescript 시작하기 </p>
<h3 id="터미널을-이용한-설치">터미널을 이용한 설치</h3>
<p><strong>npx create-react-app 프로젝트(이름) --template typescript</strong>
<strong>yarn create react-app 프로젝트(이름) --template typescript</strong></p>
]]></description>
        </item>
    </channel>
</rss>