<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>yerin.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 23 Feb 2022 12:13:50 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>yerin.log</title>
            <url>https://images.velog.io/images/ye-r1/profile/03a1b370-4460-4856-9b68-2133c07761d1/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. yerin.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/ye-r1" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[220223 중첩된 미디어쿼리는.. ie 😡]]></title>
            <link>https://velog.io/@ye-r1/220223-%EC%A4%91%EC%B2%A9%EB%90%9C-%EB%AF%B8%EB%94%94%EC%96%B4%EC%BF%BC%EB%A6%AC%EB%8A%94..-ie</link>
            <guid>https://velog.io/@ye-r1/220223-%EC%A4%91%EC%B2%A9%EB%90%9C-%EB%AF%B8%EB%94%94%EC%96%B4%EC%BF%BC%EB%A6%AC%EB%8A%94..-ie</guid>
            <pubDate>Wed, 23 Feb 2022 12:13:50 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/ye-r1/post/c94ad5e9-444b-4403-8b14-9f459640a3b7/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-02-23%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.09.06.png" alt=""></p>
<p>하고 보니까 또 익스플로러다..😡
중첩된 미디어쿼리는 익스플로러에서 안된다..
다른 방법이 있는지 고민중. . 💡</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[position: sticky와 overflow는 궁합이 좋지 않다.]]></title>
            <link>https://velog.io/@ye-r1/position-sticky%EC%99%80-overflow%EB%8A%94-%EA%B6%81%ED%95%A9%EC%9D%B4-%EC%A2%8B%EC%A7%80-%EC%95%8A%EB%8B%A4</link>
            <guid>https://velog.io/@ye-r1/position-sticky%EC%99%80-overflow%EB%8A%94-%EA%B6%81%ED%95%A9%EC%9D%B4-%EC%A2%8B%EC%A7%80-%EC%95%8A%EB%8B%A4</guid>
            <pubDate>Sat, 05 Feb 2022 16:27:28 GMT</pubDate>
            <description><![CDATA[<p><code>sticky</code>와 <code>scroll 컨테이너</code> 사이에 <code>overflow:hidden</code>을 넣었더니 <code>sticky</code>가 망가졌다.
작업중 root 컨테이너에 넘치는 케이스를 안전하게 제거하기 위해, 위 같은 방식을 사용하였는데 이러한 이슈가 생길지 몰랐다..</p>
<p>편한 생활을 위해 실험적인 스타일을 사용하는 것에 대해 반 부정적으로 살아왔었다.
쓰지 않으면 안되는 이유에 대해 물어볼때 대답하기 어려웠지만 잊고 있었던 것이다.
모든 side-effect에 대응할 수 없는 최신 css 문법은 한번씩 공식문서나 mdn을 읽고 사용하자 ^_ㅠ.. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[#13 Today I Learned - 21.01.20]]></title>
            <link>https://velog.io/@ye-r1/13-Today-I-Learned-21.01.20</link>
            <guid>https://velog.io/@ye-r1/13-Today-I-Learned-21.01.20</guid>
            <pubDate>Wed, 20 Jan 2021 16:17:54 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>mini project : Redux Movie App</li>
<li>javascript : axios로 받아온 state 값 assign 하기</li>
</ul>
<hr>
<br />

<h2 id="💻-✏️-mini-project--redux-movie-app">💻 ✏️ mini project : Redux Movie App</h2>
<div>
<img src="https://images.velog.io/images/ye-r1/post/c1eab9ac-d61b-4c4d-a2fb-0edeed92e463/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-01-21%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.18.57.png" />
</div>

<p>링크 🔗 - <a href="https://github.com/ye-r1/netflix-app">https://github.com/ye-r1/netflix-app</a></p>
<br />

<h2 id="javascript--axios로-받아온-state-값-assign-하기">javascript : axios로 받아온 state 값 assign 하기</h2>
<pre><code class="language-jsx">const {movie = []} = useSelector(state =&gt; state?.app);
const item = movie.filter((i) =&gt; i.genres.indexOf(genres) !== -1);</code></pre>
<p>list_movies.json으로 가져오는 값이 정의되지 않았을 경우를 위해 구조분해 할 때 기본값으로 빈 array를 할당하였다.</p>
<pre><code class="language-jsx">const {movie} = useSelector(state =&gt; state?.app);
const item = movie.length &amp;&amp; movie.filter((i) =&gt; i.genres.indexOf(genres) !== -1);</code></pre>
<p>하지만 기본값을 할당하지 않고서도 <code>movie.length &amp;&amp;</code> 조건을 더해준다면 더 안정적이게 데이터를 받아 올 수 있다. 안정적인 코드를 위한다면 두 방법 모두 사용하는 것이 좋다.</p>
<br />

<hr>
<h2 id="review-📃">review 📃</h2>
<p>distructing 와 오타 그 어딘가에 함정에서 오늘 하루를 불태웠다..
오류도 발전해 갈 수 있는 좋은 밑거름이 되기에 오늘의 시간을 후회하지 않는다
다음에 실수 안 하게 된다면 그걸로 만족한다</p>
<p>그리고 실무자분께 코드리뷰도 받았다 궁금했던 것들도 물어보고 고마운 하루였다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[#12 Today I Learned - 21.01.19]]></title>
            <link>https://velog.io/@ye-r1/12-Today-I-Learned-21.01.19</link>
            <guid>https://velog.io/@ye-r1/12-Today-I-Learned-21.01.19</guid>
            <pubDate>Tue, 19 Jan 2021 14:20:07 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>mini project : Redux Movie App</li>
<li>github : git commit edit, delete tutorial</li>
</ul>
<hr>
<br />

<h2 id="💻-✏️-mini-project--redux-movie-app">💻 ✏️ mini project : Redux Movie App</h2>
<div>
<img src="https://images.velog.io/images/ye-r1/post/96ba85d4-55b5-4f7b-a08a-1e026e9b101e/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-01-21%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.29.16.png" />
</div>

<p>링크 🔗 - <a href="https://github.com/ye-r1/netflix-app">https://github.com/ye-r1/netflix-app</a></p>
<br />

<h2 id="github--git-commit-edit-delete-tutorial">github : git commit edit, delete tutorial</h2>
<blockquote>
<ul>
<li><ol>
<li>git log &nbsp; <code>commit 내역 확인</code></li>
</ol>
</li>
</ul>
</blockquote>
<ul>
<li><ol start="2">
<li>git reset HEAD^ &nbsp; <code>commit 삭제</code>
(^ 뒤에 2를 붙이면 <strong>최근 커밋의 2개가</strong> 삭제됩니다.)</li>
</ol>
</li>
<li><ol start="3">
<li>git push -f &nbsp; <code>git 반영</code></li>
</ol>
</li>
</ul>
<br />

<hr>
<h2 id="review-📃">review 📃</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[#11 Today I Learned - 21.01.18]]></title>
            <link>https://velog.io/@ye-r1/11-Today-I-Learned-21.01.18</link>
            <guid>https://velog.io/@ye-r1/11-Today-I-Learned-21.01.18</guid>
            <pubDate>Mon, 18 Jan 2021 14:48:52 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>mini project : Redux Movie App</li>
</ul>
<hr>
<br />

<h2 id="💻-✏️-mini-project--redux-movie-app">💻 ✏️ mini project : Redux Movie App</h2>
<div>
<img src="https://images.velog.io/images/ye-r1/post/39f5791c-50b6-4d15-b82e-6b9c9a9a8d4c/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-01-21%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.24.58.png" />
</div>

<p>링크 🔗 - <a href="https://github.com/ye-r1/netflix-app">https://github.com/ye-r1/netflix-app</a></p>
<br />


<hr>
<h2 id="review-📃">review 📃</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[#10 Today I Learned - 21.01.16]]></title>
            <link>https://velog.io/@ye-r1/10-Today-I-Learned-21.01.16</link>
            <guid>https://velog.io/@ye-r1/10-Today-I-Learned-21.01.16</guid>
            <pubDate>Sat, 16 Jan 2021 04:24:38 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>mini project : Redux Movie App</li>
<li>antd : import antd css</li>
</ul>
<hr>
<br />

<h2 id="💻-✏️-mini-project--redux-movie-app">💻 ✏️ mini project : Redux Movie App</h2>
<div>
<img src="https://images.velog.io/images/ye-r1/post/7d22ae6a-847f-4757-8680-deb1bf5ccb5a/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-01-21%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.21.46.png" />
</div>

<p>링크 🔗 - <a href="https://github.com/ye-r1/netflix-app">https://github.com/ye-r1/netflix-app</a></p>
<br />

<h2 id="antd--import-antd-css">antd : import antd css</h2>
<pre><code class="language-jsx">import &#39;antd/dist/antd.css&#39;;</code></pre>
<p>antd 플러그인을 사용하려면 css 파일을 직접 import 해야 한다</p>
<br/> 

<hr>
<h2 id="review-📃">review 📃</h2>
<p>드디어 리액트로 만드는 첫 프로젝트를 만들어보려고 한다
주제는 예전부터 너무 하고 싶었던 영화 앱 클론하기
시작은 어렵지만 첫 발자국을 찍는다는게 정말 중요하다
어쩜 그리 겁이 나는지 다 막막해보인다ㅠ 그래도 파이팅!</p>
<p>근데 새벽에 효율이 배로 나오는데.. 새벽형 인간이 될 수는 없는걸까?
인간은 왜 그런걸까?.. Life is egg</p>
<p>🤔 오늘 열심히 쓴 커밋이 올라가긴 했는데 잔디가 없다
영화 앱 클론하려고 first commit 했는데 그건 올라가고 기존에 하고 있었던     리덕스 프로젝트는 잔디만 안 보인다..
중간에 이름을 바꿨는데 아무래도 그 영향이 있나보다..🥺
앞으로 더 조심해야겠다 💧💧</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[#9 Today I Learned - 21.01.15]]></title>
            <link>https://velog.io/@ye-r1/9-Today-I-Learned-21.01.15</link>
            <guid>https://velog.io/@ye-r1/9-Today-I-Learned-21.01.15</guid>
            <pubDate>Fri, 15 Jan 2021 14:36:09 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>mini project : redux todo list</li>
<li>github : git push tutorial</li>
<li>es6 : filter()</li>
<li>javascript : json.stringify()</li>
</ul>
<hr>
<br />

<h2 id="💻-✏️-mini-project--redux-todo-list">💻 ✏️ mini project : redux todo list</h2>
<div>
<img src="https://images.velog.io/images/ye-r1/post/14a181aa-cb39-4375-84cb-fac77def2729/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-01-16%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2012.33.33.png" />
</div>

<p>링크 🔗 - <a href="https://github.com/ye-r1/vanilla-redux">https://github.com/ye-r1/vanilla-redux</a></p>
<br />

<h2 id="github--git-push-tutorial">github : git push tutorial</h2>
<blockquote>
<ul>
<li><ol>
<li>git init &nbsp; <code>git 저장소 생성</code></li>
</ol>
</li>
</ul>
</blockquote>
<ul>
<li><ol start="2">
<li>*<em>git add * *</em> &nbsp;<code>git 저장소에 보낼 file 선택</code></li>
</ol>
</li>
<li><ol start="3">
<li><strong>git commit -m &quot;&quot;</strong> &nbsp;<code>commit 메세지 작성</code></li>
</ol>
</li>
<li><ol start="4">
<li>git remote add origin &quot;url&quot; &nbsp;<code>원격 저장소 연결</code></li>
</ol>
</li>
<li><ol start="5">
<li><strong>git push</strong> -u origin main &nbsp;<code>git 보내기</code></li>
</ol>
</li>
<li><ol start="6">
<li>기존 데이터가 손실될 수 있어서 push를 막은 경우에는 <strong>강제 push</strong>를 진행한다. (git push -u origin <strong>+main</strong>)</li>
</ol>
</li>
<li><p>git add *</p>
</li>
<li><p>git commit -m &quot;&quot;</p>
</li>
<li><p>git push</p>
</li>
</ul>
<p>이후 커밋을 할 때에는 이 부분만 해줘도 된다.</p>
<br />

<h2 id="es6--filter">es6 : filter()</h2>
<p>** javascript filter() **</p>
<blockquote>
<p>해당하는 값만 모아 새로운 배열로 생성한다.</p>
</blockquote>
<pre><code class="language-javascript">const words = [&#39;apple&#39;, &#39;pizza&#39;, &#39;candle&#39;, &#39;cup&#39;];
const result = word.filter(word =&gt; word.length &gt; 5);</code></pre>
<ul>
<li>filter는 새로운 array를 생성하고 새로 선언된 result 변수가 새로운 배열을 저장해준다.</li>
<li>new array를 생성한 후 return시켜서 words의 array를 수정하지 않는다.</li>
</ul>
<br />

<h2 id="javascript--jsonstringify">javascript : json.stringify()</h2>
<blockquote>
<p>json을 문자열로 변환시켜준다.</p>
</blockquote>
<br />

<hr>
<h2 id="review-📃">review 📃</h2>
<p>redux와 친해지는게 어렵다..
자주 반복해서 써보려 한다..ㅠㅠ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[#7 Today I Learned - 21.01.12]]></title>
            <link>https://velog.io/@ye-r1/7-Today-I-Learned-21.01.12</link>
            <guid>https://velog.io/@ye-r1/7-Today-I-Learned-21.01.12</guid>
            <pubDate>Tue, 12 Jan 2021 14:04:22 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>mini project : redux todo list</li>
<li>react : prop-types</li>
</ul>
<hr>
<br />

<h2 id="💻-✏️-mini-project--redux-todo-list">💻 ✏️ mini project : redux todo list</h2>
<div>
<img src="https://images.velog.io/images/ye-r1/post/05264660-2df5-4068-b6ef-3ca16d8c7978/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-01-16%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.29.55.png" />
</div>

<p>링크 🔗 - <a href="https://github.com/ye-r1/vanilla-redux">https://github.com/ye-r1/vanilla-redux</a></p>
<br />

<h2 id="react--prop-types">react : prop-types</h2>
<blockquote>
<p>typescript와 같은 javascript 도구 이다.
Component의 <strong>props에 type 확인</strong>을 하려면 propTypes를 선언해야 한다.</p>
</blockquote>
<pre><code class="language-jsx">import PropTypes from &#39;prop-types&#39;;

const App = () =&gt; {
    return(
        &lt;Component /&gt;
    )
}</code></pre>
<pre><code class="language-jsx">App.propTypes = {
  Component: PropTypes.element.isRequired,
};</code></pre>
<ul>
<li>PropTypes는 <code>elementType</code> React element 타입이며, <code>.isRequired</code> 존재하지 않으면 에러를 띄운다.</li>
</ul>
<br />

<pre><code class="language-jsx">import PropTypes from &#39;prop-types&#39;;

class Greeting extends React.Component {
  render() {
    return (
      &lt;h1&gt;Hello, {this.props.name}&lt;/h1&gt;
    );
  }
}

Greeting.propTypes = {
  name: PropTypes.string
};</code></pre>
<pre><code class="language-jsx">컴포넌트.propTypes = { 
    props_name : PropTypes.해당하는_타입
}</code></pre>
<ul>
<li>props에 type 확인을 하려면 propTypes를 선언해야 한다.</li>
</ul>
<pre><code class="language-jsx">//React element
PropTypes.element,

//array
PropTypes.array,

//boolean
PropTypes.bool,

//function
PropTypes.func,

//number
PropTypes.number,

//object
PropTypes.object,

//string
PropTypes.string,

//symbol
PropTypes.symbol,

//prop가 특정 값들로 제한되도록 한다.
PropTypes.oneOf([&#39;sage&#39;, &#39;citrus&#39;]),

//number를 가진 array
PropTypes.arrayOf(PropTypes.number),

//number를 가진 object
PropTypes.objectOf(PropTypes.number),

//특정 형태를 갖는 object
PropTypes.shape({
  color: PropTypes.string,
  fontSize: PropTypes.number
}),</code></pre>
<ul>
<li>다음과 같이 사용할 수도 있다.</li>
</ul>
<br />

<hr>
<h2 id="reference-🔗">reference 🔗</h2>
<p>[React] PropTypes와 함께 하는 타입 확인
<a href="https://ko.reactjs.org/docs/typechecking-with-proptypes.html">https://ko.reactjs.org/docs/typechecking-with-proptypes.html</a></p>
<hr>
<h2 id="review-📃">review 📃</h2>
<p>nomad corder의 react와 pure javascript로 만드는 redux 강의를 듣기 시작했다. redux가 손에 익숙치 않아 어려움을 겪고 있었는데 나에게 좋은 기회가 될 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[#5 Today I Learned - 21.01.10]]></title>
            <link>https://velog.io/@ye-r1/5-Today-I-Learned-21.01.10</link>
            <guid>https://velog.io/@ye-r1/5-Today-I-Learned-21.01.10</guid>
            <pubDate>Sun, 10 Jan 2021 14:58:37 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>classnames</li>
<li>react : custom hooks 기본 사용법</li>
</ul>
<hr>
<br />

<h2 id="classnames">classnames</h2>
<blockquote>
<p>조건에 따라 ** class를 추가 / 삭제 ** 할 수 있는 react package이다.</p>
</blockquote>
<p>사용법은 간단하다.</p>
<pre><code class="language-jsx">import cn from &quot;classnames&quot;;

const [sidebar, setSidebar] = useState(false);
</code></pre>
<pre><code class="language-jsx">&lt;Container className={cn(&quot;sidebar&quot;, {open: sidebar})}&gt;

&lt;/Container&gt;</code></pre>
<p>Container의 기본 class는 &quot;sidebar&quot;이며 sidebar가 true일 경우 key의 대한 value값이 true이기에 key 값인 &quot;open&quot;을 toggleClass로 달아줄 수 있다.</p>
<blockquote>
<pre><code class="language-jsx">cn(&quot;foo&quot;, &quot;bar&quot;); // &quot;foo bar&quot;
cn(&quot;foo&quot;, {bar : true}); // &quot;foo bar&quot;
cn({&quot;foo-bar&quot; : true}); // &quot;foo-bar&quot;
cn({&quot;foo-bar&quot; : false});
cn({foo : true}, {bar : true}); // &quot;foo bar&quot; 
cn({foo : true, bar : true}); // &quot;foo bar&quot;</code></pre>
</blockquote>
<pre><code>
- classnames는 다양한 방법으로 표현할 수 있다.
- 문자열일 경우 true로 인식해 기본으로 보여지며, object는 key에 대한 value가 true일 경우 **key값을 class로** return한다.

```jsx
let buttonType = &quot;primary&quot;;
classNames({ [`btn-${buttonType}`] : true });</code></pre><ul>
<li>또한 동적으로 class를 주입할 수도 있다.</li>
</ul>
<pre><code class="language-jsx"> const btnClass = cn(‘btn&#39;, this.props.className, {
  &#39;btn-pressed&#39;: this.state.isPressed,
  &#39;btn-over&#39;: !this.state.isPressed &amp;&amp; this.state.isHovered
});</code></pre>
<ul>
<li>객체, 배열 및 인수를 함께 혼합할 수 있다.</li>
</ul>
<br />


<h2 id="react--custom-hooks-기본-사용법">react : custom hooks 기본 사용법</h2>
<blockquote>
<p>component 로직을 재사용 가능한 hook으로 만드는 것</p>
</blockquote>
<pre><code class="language-jsx">const [id, onChangeId] = useInput(&#39;&#39;);</code></pre>
<p>/hooks/useInput.js</p>
<pre><code class="language-jsx">import { useState, useCallback } from &#39;react&#39;;

export default (initValue = null) =&gt; {
  const [value, setValue] = useState(initValue);
  const handler = useCallback((e) =&gt; {
    setValue(e.target.value);
  }, []);
  return [value, handler];
};</code></pre>
<ul>
<li>원래 useState하면 value값과 setValue값을 배열로 리턴하는데 custom hook에서는 useCallback을 포함한 채로 value와 handler로 처리된 값이 반환된다.</li>
</ul>
<br />

<p><strong>🔗 Collection of React Custom Hooks</strong>
<a href="https://nikgraf.github.io/react-hooks/">https://nikgraf.github.io/react-hooks/</a>
<a href="https://github.com/rehooks/awesome-react-hooks">https://github.com/rehooks/awesome-react-hooks</a></p>
<br />
]]></description>
        </item>
        <item>
            <title><![CDATA[#4 Today I Learned - 21.01.08]]></title>
            <link>https://velog.io/@ye-r1/4-Today-I-Learned-21.01.08</link>
            <guid>https://velog.io/@ye-r1/4-Today-I-Learned-21.01.08</guid>
            <pubDate>Sat, 09 Jan 2021 10:19:53 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>react : 기초 복습    </li>
<li>react : useCallback, useMemo</li>
</ul>
<hr>
<br />

<h2 id="react--기초-복습">react : 기초 복습</h2>
<p><strong>state 저장하는법</strong></p>
<ul>
<li>변수로 저장하거나 useState를 이용해 저장할 수 있다.</li>
<li>변수는 변경되어도 자동 rendering 되지 않고 새로고침 해야만 rendering 된다.</li>
<li>useState를 이용해서 state를 만들면 state값이 변경되었을때 html이 자동으로 재 rendering 된다.</li>
</ul>
<p><strong>component의 특징</strong></p>
<ul>
<li>컴포넌트는 보통 영어 대문자로 시작한다.</li>
<li>return 밑에는 여러개의 태그가 들어갈 수 없다.</li>
<li>만약 여러개의 태그를 넣고 싶으면 div로 묶을 수 있지만, 의미없는 div를 사용하고 싶지 않으면 <code>&lt;&gt;&lt;/&gt;</code> fragments로 묶을 수도 있다.</li>
<li>보통 component안에 component를 만들지는 않는다.</li>
<li>컴포넌트는 자신의 state가 변경되거나, 부모에게서 받는 props가 변경되었을 때마다 재 rendering 된다.</li>
</ul>
<blockquote>
<p><strong>component로 만드는 경우</strong></p>
</blockquote>
<ul>
<li>사이트에 반복해서 출현하는 html</li>
<li>내용이 자주 변경될 것 같은 부분</li>
<li>같은 layout의 page를 제작할때</li>
</ul>
<br />

<h2 id="react--usecallback-usememo">react : useCallback, useMemo</h2>
<p>useCallback 은 useMemo 와 비슷한 Hook이다</p>
<blockquote>
<p>useCallback 은 <strong>특정 함수</strong>를 새로 만들지 않고 재사용하고 싶을때 사용하는 반면, useMemo 는 <strong>특정 결과값</strong>을 재사용하고 싶을때 사용합니다.</p>
</blockquote>
<ul>
<li>useCallback을 사용하면 해당 함수가 필요할 때만 변경이 된다</li>
<li>의존성 배열이 바뀌기 전까지 함수 자체를 기억한다</li>
<li>자식 컴포넌트에 함수를 props로 내릴때는 useCallback을 반드시 사용한다 (자식 리 rendering 방지)<br />

</li>
</ul>
<p>useCallback - 함수를 캐싱하는것
useMemo - 값을 캐싱하는 것</p>
<br />

<hr>
<h2 id="reference-🔗">reference 🔗</h2>
<p>[모던리액트] 17. useMemo 를 사용하여 연산한 값 재사용하기
<a href="https://react.vlpt.us/basic/18-useCallback.html">https://react.vlpt.us/basic/18-useCallback.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[#3 Today I Learned - 21.01.06]]></title>
            <link>https://velog.io/@ye-r1/3-Today-I-Learned-21.01.06</link>
            <guid>https://velog.io/@ye-r1/3-Today-I-Learned-21.01.06</guid>
            <pubDate>Wed, 06 Jan 2021 14:38:57 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>redux-saga : function*(){ }, redux-saga-effect</li>
<li>redux-saga : saga 사용법</li>
<li>javascript : 구조 분해 할당</li>
<li>javascript : axios</li>
</ul>
<hr>
<br />

<h2 id="redux-saga--function--redux-saga-effect">redux-saga : function*(){ }, redux-saga-effect</h2>
<blockquote>
<ul>
<li>redux를 사용할때 특정 action을 관찰하고 있다가 action이 실행되면서 <strong>동시에 다른 행동을 취할 수 있게</strong> 해 주는 함수이다.</li>
</ul>
</blockquote>
<ul>
<li>주로 back-end 통신을 할때 많이 사용한다.</li>
</ul>
<p><strong>Generator function</strong></p>
<blockquote>
</blockquote>
<pre><code class="language-javascript">function* name() {
    yield
    yield
}</code></pre>
<p>해당하는 값이 나올때까지 실행하다가 <strong>해당하는 yield 값이 있으면</strong> 거기서 return하고 <code>next()</code> 를 기다리는 함수이다.</p>
<p><strong>redux-saga-effect</strong>
effect들은 generator function을 사용하여 이루어진다.</p>
<blockquote>
<ul>
<li><strong>call :</strong> 함수를 동기적으로 실행, <del>( api 사용할때 )</del></li>
</ul>
</blockquote>
<ul>
<li><strong>all :</strong> 여러 saga를 한번에 실행, 배열로 <code>[]</code> 내보낸다.</li>
<li><strong>fork :</strong> 함수를 비동기적으로 실행</li>
<li><strong>takeLatest :</strong> 짧은 시간내에 액션이 관측되면 그 액션이 들어온 맨 마지막 것만 받아서 실행</li>
<li><strong>delay :</strong> 매개변수에 있는 시간만큼 잠깐 멈춤</li>
<li><strong>put :</strong> dispatch()와 동일</li>
</ul>
<p><del>saga에서는 arrow function 을 쓸 수 없다.</del></p>
<br />

<h2 id="redux-saga--saga-사용법">redux-saga : saga 사용법</h2>
<p><em>/redux/sagas.js</em></p>
<pre><code class="language-jsx">import {all} from &quot;redux-saga/effects&quot;;
import appSaga from &quot;./app/saga&quot;;
import userSaga from &quot;./user/saga&quot;;

export default function* (){
    yield all([
        appSaga(),
        userSaga(),
    ])
}</code></pre>
<ul>
<li>먼저 generator function을 만들고 <code>all()</code> 함수를 이용해 여러개의 saga를 한번에 실행한다.</li>
</ul>
<br />

<p><em>/redux/store.js</em></p>
<pre><code class="language-jsx">import {/*createStore*/, applyMiddleware} from &quot;redux&quot;;
//import reducers from &quot;./reducers&quot;;
import createSagaMiddleware from &quot;redux-saga&quot;;
import sagas from &quot;./sagas&quot;;

const sagaMiddleware = createSagaMiddleware();
const store = createStore(/*reducers*/, applyMiddleware(sagaMiddleware));
sagaMiddleware.run(sagas);

//export default store;</code></pre>
<ul>
<li><code>createSagaMiddleware</code> 를 redux-saga에서 가져와서 saga를 생성한다.</li>
<li>기존 <code>createStore</code> 인자 값에 생성한 saga함수를 <code>=sagaMiddleware</code> <code>applyMiddleware()</code>로 감싸서 추가한다.</li>
<li>그리고 sagaMiddleware 인자 값에 <code>sagaMiddleware.run()</code>  saga들을 합친 <code>sagas</code>.js를 import하여 sagaMiddleware를 실행시킨다.</li>
</ul>
<br />

<p><em>/api/index.js</em></p>
<pre><code class="language-jsx">import axios from &quot;axios&quot;;

const API = {
    getUsers: () =&gt; axios.get(&quot;https://jsonplaceholder.typicode.com/users&quot;)
}

export default API;</code></pre>
<ul>
<li>axios get을 통해 url로 data를 요청한다.</li>
</ul>
<br />

<p><em>/view/pages/User/index.js</em></p>
<pre><code class="language-jsx">useEffect(() =&gt; {
    userActions.getUsers();
},[])</code></pre>
<ul>
<li>렌더링이 될 때 액션을 실행한다.</li>
</ul>
<br />

<p><em>/redux/user/saga.js</em></p>
<pre><code class="language-jsx">import {all, takeLatest, call, put} from &quot;redux-saga/effects&quot;;
import {Action} from &quot;../user/redux&quot;;
import API from &quot;../../api&quot;;
import {userActions} from &quot;../actionCreators&quot;;

export default function* (){
    yield all([
        takeLatest(Action.Types.GET_USERS, function* (){
            const result  = yield call(API.getUsers);
            if(result?.data) {
                yield put(userActions.updateState({
                    users: result.data,
                }))
            }
        })
    ])
}</code></pre>
<ul>
<li>먼저 여러 saga를 한번에 실행해주는 <code>all</code> 함수를 실행한다.</li>
<li>그리고 data를 받아오기위해 가장 최근에 일어난 것만 받아서 실행하는 <code>takeLatest</code> 함수를 작성하여 첫번째 인자로는 실행할 type의 action을 넣고, 두번째로 콜백함수 generator function을 넣어준다.</li>
<li>axios로 http 통신하여 api data를 가져오는 파일을 분리 시켜줬었는데     export한 파일을 불러와서 <code>yield call(API.getUsers)</code> 함수를 동기적으로 호출한다. 이 과정에서 call을 할때 자동으로 promise가 벗겨진다.</li>
<li>만약 axios로 불러온 data가 있을 경우에만 <code>put()</code> 을 사용하여 action 생성자 함수를 호출하고 user 객체를 redux에 dispatch한다.</li>
</ul>
<br />

<h2 id="javascript--구조-분해-할당">javascript : 구조 분해 할당</h2>
<p><strong>기본 객체구조 분해</strong></p>
<pre><code class="language-javascript">const user = {
    name: &#39;name&#39;,
    gender: &#39;female&#39;
};
const { gender } = user;
console.log(gender);  // &#39;female&#39;</code></pre>
<p><strong>새로운 변수명 할당하기</strong></p>
<blockquote>
</blockquote>
<pre><code class="language-javascript">const user = {
    name: &#39;name&#39;,
    gender: &#39;female&#39;
};
const { gender : newGender } = user;
console.log(newGender);  // &#39;female&#39;</code></pre>
<p>객체구조 분해시 새로운 변수명을 대입해 <code>gender : newGender</code> 사용 할 수 있다.</p>
<p><strong>기본값 할당하기</strong></p>
<pre><code class="language-javascript">const user = {
  name: &#39;name&#39;,
  sns: [
    &#39;facebook&#39;,
    &#39;instagram&#39;,
  ]
};
const { sns = [] } = user;
console.log(sns);  // Array</code></pre>
<ul>
<li>만약 user의 값이 정의되지 않았다면 에러가 난다. 이를 막기 위해 구조분해시 기본값을 할당 <code>sns = []</code> 할 수도 있다.</li>
<li>결과적으로 기본값으로 빈 Array를 내 뱉기 때문에 Data가 없더라도 error가 나지 않는다.</li>
</ul>
<p><strong>새로운 변수명과 기본값 할당하기</strong></p>
<pre><code class="language-javascript">const user = {
  name: &#39;name&#39;,
  sns: [
    &#39;facebook&#39;,
    &#39;instagram&#39;,
  ]
};
const { sns : newsns = [] } = user;
console.log(newsns);  // Array</code></pre>
<ul>
<li>또한 기본값을 할당하면서 동시에 새로운 변수명을 선언하는것도 가능하다.</li>
</ul>
<p><strong>즉시 구조 분해 하기</strong></p>
<pre><code class="language-jsx">function Home({data, dispatch}) {

}</code></pre>
<ul>
<li><strong>인자값 (arguments)</strong> 안에서도 바로 할당이 가능하다.</li>
</ul>
<br />

<h2 id="javascript--axios">javascript : axios</h2>
<blockquote>
<p>axios는 http 통신을 위한 자바스크립트 라이브러리이다. 비동기통신으로 data를 가져올 수 있다.</p>
</blockquote>
<pre><code class="language-jsx">useEffect( () =&gt; {

}, [])</code></pre>
<ul>
<li>axios 사용시 통신을 무한 loop에 빠지지 않게 하기 위한 방법으로 react hook인 useEffect를 사용해 처음 렌더링 될 때에만 실행시켜줄 수 있다.</li>
<li>useEffect 훅은 뒤에 인자값으로 <code>[]</code> 빈 배열을 넣어주면 처음 렌더링 될 때에만 실행시켜준다.</li>
</ul>
<p><code>axios.get()</code>은 url로 data를 호출해온다.</p>
<br />

<hr>
<h2 id="reference-🔗">reference 🔗</h2>
<p>리덕스 툴킷으로 리덕스 사가 사용하기
<a href="https://velog.io/@jwisgenius/Redux-ToolKit-With-Redux-Saga-%EB%A6%AC%EB%8D%95%EC%8A%A4-%ED%88%B4%ED%82%B7%EC%9C%BC%EB%A1%9C-%EB%A6%AC%EB%8D%95%EC%8A%A4-%EC%82%AC%EA%B0%80-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0">https://velog.io/@jwisgenius/Redux-ToolKit-With-Redux-Saga-%EB%A6%AC%EB%8D%95%EC%8A%A4-%ED%88%B4%ED%82%B7%EC%9C%BC%EB%A1%9C-%EB%A6%AC%EB%8D%95%EC%8A%A4-%EC%82%AC%EA%B0%80-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0</a></p>
<hr>
<h2 id="review-📃">review 📃</h2>
<p>이전에는 공부하면서 메모장에 정리를 했었는데 가독성도 떨어지고 다시 열어보는 일이 적어지다 보니 코드에 주석을 쓰면서 정리하는 일이 빈번했다.</p>
<p>til를 작성하게 되면서 달라진 점이 있다면
공부한 개념을 까먹기 전에 정리하는 것이 일상 루틴으로 자리 잡았다는 것이다.
코드를 따라 칠 때보다 개념을 정리할때 더 확실히 이해할 수 있다는 것이 til의 매력적인 점이 아닐까 싶다.</p>
<p>벨로그를 접하게 된 이후로 til을 작성하면서 마크다운이라는 걸 처음 작성해봤는데 생각보다 너무 편리하다. html 에디터 보다도 좋은 것 같다. 게다가 velog 만의 uiux 디자인이 마음에 들어서 불편함이 적은 것 같다.</p>
<p>그래서 나는 하루를 마치고 작성하는 이 시간을 좋아하게 되었다.
이 벨로그가 나에게 더 긍정적인 에너지를 전달해주는 힘을 가질 수 있기를.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[#2 Today I Learned - 21.01.05]]></title>
            <link>https://velog.io/@ye-r1/2-Today-I-Learned-21.01.05</link>
            <guid>https://velog.io/@ye-r1/2-Today-I-Learned-21.01.05</guid>
            <pubDate>Tue, 05 Jan 2021 08:02:05 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>styled-components : 상속과 분리</li>
<li>react-redux : actionCreators를 미리 binding 하기</li>
<li>javascript : 논리연산자 단축평가</li>
<li>javascript : optional chaining = ?.</li>
</ul>
<hr>
<br />

<h2 id="styled-components--상속과-분리">styled-components : 상속과 분리</h2>
<p><strong>styled-components 상속하기</strong></p>
<pre><code class="language-jsx">const NavItem = styled(Link)`

`
&lt;NavItem to={“/”}&gt;Home&lt;/NavItem&gt;</code></pre>
<p>react-router-dom에 있는 기능인 Link를 상속시켜 link tag로 만들 수 있다.</p>
<pre><code class="language-jsx">const StyledNavItem = styled(NavItem)`

`
&lt;StyledNavItem&gt;&lt;/StyledNavItem&gt;</code></pre>
<p>또한 기존 컴포넌트에 별도로 덧입히고 싶은 스타일이 있다면 styled()안에 컴포넌트명을 적어 기존 스타일을 상속할 수 있다.</p>
<br />

<p><strong>styled-components 분리하기</strong></p>
<p>/Layout/Layout.Styled.js</p>
<pre><code class="language-jsx">import styled from &quot;styled-components&quot;;

export const ContentContainer = styled.div`
  max-width: 1230px;
  padding: 0 15px;
  margin: 0 auto;
`
&lt;ContentContainer&gt;&lt;/ContentContainer&gt;</code></pre>
<p>layout grid 처럼 자주 쓰는 레이아웃 컴포넌트를 생성하고 컴포넌트들을 모아 한 파일로 정리한다. 쓰고자 하는 곳에 import하여 어디든지 같은 스타일로 재사용 할 수 있다.</p>
<br />

<h2 id="react-redux--actioncreators를-미리-binding-하기">react-redux : actionCreators를 미리 binding 하기</h2>
<blockquote>
<p>redux 안에 dispatch와 action을 미리 binding 해 줄 수 있는 함수가 있다
= <strong>bindActionCreators</strong></p>
</blockquote>
<p>파일마다 action을 전송할 때에 dispatch를 계속 쓰려면 코드가 길어질 수 밖에 없다.
bindActionCreators 함수는 전송해 줄 action과 dispatch를 미리 binding해서 선언한 후 가져와 dispatch 선언 없이 간단하게 action을 전송해줄 수 있다.</p>
<p>따로 분리해놓기 위해 actionCreators.js라는 하나의 파일을 만든다.
<br /></p>
<pre><code class="language-jsx">import {bindActionCreators} from &quot;redux&quot;;</code></pre>
<ol>
<li>bindActionCreators를 import 시킨다</li>
</ol>
<pre><code class="language-jsx">//store에서 dispatch를 가져온다.
import store from &quot;./store&quot;;
const {dispatch} = store;

//app에 대한 action 생성자를 가져온다.
import {Action as AppAction} from &quot;./app/redux&quot;;

//action생성자와 dispatch를 binding한다.
export const appActions = bindActionCreators(AppAction.Creators, dispatch);</code></pre>
<ol start="2">
<li>store 안에 미리 만든 action 생성자를 가져온 후 bindActionCreators 안에 action 생성자와 dispatch를 인자값으로 대입한다. (실행되면 액션이 반환되는데 그걸 미리 디스패치와 묶어주는 역할을 한다.)</li>
</ol>
<p>기존에는 파일마다 일일히 dispatch를 불러와서 전송 했는데 미리 binding하여 호출하면 dispatch 구문을 불러오는 작업을 생략하여 간편하게 쓸 수 있다.</p>
<p><code>react hook인 useDispatch를 사용하려면 react가 import된 환경에서 쓸 수 있기 때문에     react없이도 store에서 dispatch를 꺼내올 수 있다.</code></p>
<pre><code class="language-jsx">&lt;Close onClick={() =&gt; appActions.updateState({popup:{}})}&gt;&lt;/Close&gt;</code></pre>
<ol start="3">
<li>dispatch를 사용할 공간에 dispatch 대신 미리 binding한 appAction를 사용한다.</li>
</ol>
<br />

<h2 id="javascript--논리연산자-단축평가">javascript : 논리연산자 단축평가</h2>
<blockquote>
<p><strong>|| (논리합) &amp;&amp; (논리곱) 연산자는 왼쪽부터 평가를 진행한다.</strong>
연산 중 평가결과가 나오면 오른쪽까지 가지 않고 평가를 반환하는 것을 단축평가라고 한다.</p>
</blockquote>
<br />

<p><strong>|| (논리합)의 단축평가</strong></p>
<blockquote>
<p><strong>true</strong> || false;
<strong>true</strong> || true;</p>
</blockquote>
<ul>
<li>|| (논리합) 의 경우 둘 중 하나만 true이면 true로 평가되므로 왼쪽 연산자가 true이면 오른쪽은 보지도 않고 <strong>바로 왼쪽을 반환시킨다.</strong></li>
</ul>
<p><strong>“apple”</strong> || false;
<strong>“apple”</strong> || true;</p>
<ul>
<li>만약 피연산자가 <strong>문자열일 경우에 빈 문자열이 아니면 true</strong> 로 평가된다.</li>
</ul>
<p>false || <strong>true</strong>;
false || <strong>false</strong>;
false || <strong>“banana”</strong>;</p>
<ul>
<li>|| (논리합) 연산자는 <strong>왼쪽이 false일 경우에는 오른쪽 피연산자 값이 false라도 그대로 반환</strong> 시킨다.</li>
</ul>
<p><strong>“apple”</strong> || “banana”</p>
<ul>
<li>둘 다 문자열일 경우에도 왼쪽을 반환한다.</li>
</ul>
<br />

<p><strong>&amp;&amp; (논리곱)의 단축평가</strong></p>
<blockquote>
</blockquote>
<p>false &amp;&amp; true =&gt; <strong>false</strong>
false &amp;&amp; false =&gt; <strong>false</strong>
false &amp;&amp; “banana” =&gt; <strong>false</strong></p>
<ul>
<li>논리곱의 경우 둘다 true여야만 true가 반환되므로 왼쪽이 false일때엔 바로 false로 평가된다.</li>
<li>왼쪽이 true일때 <strong>오른쪽 값을 그대로 반환</strong>한다 </li>
</ul>
<p><strong>null</strong> &amp;&amp; false</p>
<ul>
<li>만약 <strong>왼쪽에 null이 들어온다면 왼쪽 null이 반환</strong>된다.</li>
</ul>
<p>true &amp;&amp; true =&gt; <strong>true</strong>
true &amp;&amp; false =&gt; <strong>false</strong></p>
<ul>
<li>왼쪽이 true일때는 오른쪽도 true여야 true를 반환한다.
( = 왼쪽이 true일때 오른쪽 값을 그대로 반환한다 )</li>
</ul>
<p>“apple” &amp;&amp; <strong>true</strong>
“apple” &amp;&amp; <strong>false</strong></p>
<ul>
<li>만약 왼쪽이 문자열일 때에는 <strong>문자열은 true</strong>로 평가되기 때문에 오른쪽 값을 그대로 반환한다.</li>
</ul>
<p>true &amp;&amp; <strong>“banana”</strong></p>
<ul>
<li>왼쪽이 true면서 오른쪽은 문자열일때에는 오른쪽 값을 그대로 반환하므로 문자열이 반환된다.</li>
</ul>
<p>“apple” &amp;&amp; <strong>“banana”</strong></p>
<ul>
<li>만약 양쪽 다 문자열일때에는 오른쪽 문자열 값을 그대로 반환한다.
이는 왼쪽 문자열이 true로 평가되어서 오른쪽 값을 그대로 반환하기 때문이다.</li>
</ul>
<br />

<p><strong>단축평가 사용법</strong></p>
<blockquote>
<ol>
<li>null / undefined 체크</li>
<li>함수 매개변수 기본값 설정</li>
<li>조건부 변수값 할당</li>
</ol>
</blockquote>
<br />

<p><strong>1. null / undefined 체크</strong></p>
<blockquote>
<p>단축평가를 사용하면 null과 undefined의 관련된 문제를 예방할 수 있으며, 안정성 있는 코딩이 가능하다.</p>
</blockquote>
<pre><code class="language-javascript">const a = null;
const name = a.name;</code></pre>
<p>a.name은 값이 없기 때문에 type error가 발생한다.</p>
<pre><code class="language-javascript">const a = null;
const name = a &amp;&amp; a.name;
console.log(name);  //null</code></pre>
<p>하지만 단축평가를 사용하면 왼쪽이 null일 경우 null이 반환되므로 type error는 나지 않는다.</p>
<pre><code class="language-javascript">let a;  //초기화 없이 선언하면 undefined가 발생한다.
console.log(a.name);  //타입에러
console.log(a &amp;&amp; a.name);  //undefined</code></pre>
<p>undefined의 프로퍼티를 참조할때도 동일하게 해결할 수 있다.</p>
<br />

<p><strong>2.함수 매개변수 기본값 설정</strong></p>
<blockquote>
<pre><code class="language-javascript">function getName(name){
    const yourName = name;
    return yourName;  
}
getName();  // undefined</code></pre>
</blockquote>
<pre><code>- getName() 호출시 인자를 전달하지 않았지만 함수 내부에서 인자 값을 리턴하고 있기 때문에 undefined가 할당된다.
```javascript
function getName(name){
    const yourName = name || “홍길동”;
    return yourName;
};</code></pre><ul>
<li>|| (논리합) 연산자를 이용한다면 <strong>매개변수의 기본값을 설정</strong>할 수 있다.</li>
</ul>
<pre><code class="language-javascript">getName(&#39;정우성&#39;)  //&quot;정우성&quot;
getName()  //“홍길동”</code></pre>
<p>|| (논리합) 연산자는 <strong>왼쪽값이 false일 경우 오른쪽 값을 무조건 반환</strong>하기 때문이다.</p>
<br />

<p><strong>3.조건부 변수값 할당</strong></p>
<blockquote>
<pre><code class="language-javascript">if(true) name = “홍길동”;
⬇️
name = true &amp;&amp; “홍길동”;</code></pre>
</blockquote>
<pre><code>**if문으로 변수에 값을 할당**하는 코드를 단축평가로 대체할 수 있다.

&lt;br /&gt;

## javascript : optional chaining = ?.
```jsx
{
    app?.popup?.title &amp;&amp;
    &lt;Popup/&gt;
}

= app &amp;&amp; app.popup &amp;&amp; app.popup.title &amp;&amp; 과 같은 뜻으로 사용된다.</code></pre><p>?. 옵셔널 체이닝은 앞의 평가대상이 undefined거나 null이면 평가를 멈추고 undefined를 반환한다.
사용시 프로퍼티가 없는 중첩 객체를 <strong>에러없이 안전하게 접근</strong>할 수 있다.</p>
<blockquote>
<p>❗️ <strong>옵셔널 체이닝을 남용하지 마세요.</strong>
?.는 존재하지 않아도 괜찮은 대상에만 사용해야 합니다.
사용자 주소를 다루는 예시에서 논리상 user는 반드시 있어야 하는데 address는 필수값이 아닙니다. 그러니 user?address.street 보다 user.address?.street를 사용하는 것이 바람직합니다.
실수로 인해 user에 값을 할당하지 않았다면 바로 알아낼 수 있도록 해야 합니다. 그렇지 않으면 에러를 조기에 발견하지 못하고 디버깅이 어려워집니다.</p>
</blockquote>
<p>또한 옵셔널 체이닝 앞의 변수는 무조건 선언되어 있어야 한다.</p>
<pre><code class="language-javascript">user?.address;  //user값이 없을때 error</code></pre>
<br />

<hr>
<h2 id="reference-🔗">reference 🔗</h2>
<p>[카레유] 자바스크립트 논리연산자 (&amp;&amp;, ||) 단축평가
  <a href="https://curryyou.tistory.com/193">https://curryyou.tistory.com/193</a></p>
<p>모던 자바스크립트 튜토리얼 옵셔널 체이닝
<a href="https://ko.javascript.info/optional-chaining">https://ko.javascript.info/optional-chaining</a>
<Br /></p>
<hr>
<h2 id="review-📃">review 📃</h2>
<p>오늘의 til은 잘 모르고 넘어갔었던 개념들을 조금 더 톺아볼 수 있어서 정리 포스팅에서 시원한 스프라이트맛이 난다 🌊 🌊
그리고 bindActionCreators는 내가 원했던 기능!!
묶어서 깔끔하게 사용할 수 있다니 너무 좋았다.
조금 더 공부했으면 좋았을텐데 ㅠㅠ 하루가 금방금방 넘어가는 것 같다.
시간 대비 효율적으로 학습 할 수 있는 좋은 방안을 생각해 봐야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[#1 Today I Learned - 21.01.04]]></title>
            <link>https://velog.io/@ye-r1/1-Today-I-Learned-21.01.04</link>
            <guid>https://velog.io/@ye-r1/1-Today-I-Learned-21.01.04</guid>
            <pubDate>Mon, 04 Jan 2021 14:58:55 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/ye-r1/post/60a8c146-09b6-4e96-9f85-f3e3d60d5a58/til.png" alt=""></p>
<hr>
<h2 id="today-i-learned-📝">Today I Learned 📝</h2>
<ul>
<li>react-redux: 연결하기</li>
<li>styled-components: props로 style 제어</li>
<li>es6: arrow function 구분하기</li>
</ul>
<hr>
<br />

<h2 id="react-redux--연결하기">react-redux : 연결하기</h2>
<p><strong>action</strong></p>
<blockquote>
<p>action 생성자를 호출했을때 type이 담긴 객체{}를 반환해준다.</p>
</blockquote>
<br />

<p><strong>reducer</strong></p>
<ul>
<li>인자 값으로 initValue와 action을 받는다.</li>
<li>reducer에서는 switch문으로 현재 받은 <strong>action.type 값을 받아 비교하여 값에 맞는 action을 return</strong> 해 준다.</li>
<li>return 할 때에는 기존 state를 spread 연산자를 이용해 풀어서 넣고 업데이트 할 payload 값을 뒤에 넣어준다.</li>
<li>만약 해당하는 action.type이 있으면 기존 state에 추가할 값을 얹어서 return 하면 된다. 없다면 default값으로 기존 state값을 return 해주면 된다.<br />

</li>
</ul>
<p><strong>store 적용하기</strong></p>
<blockquote>
</blockquote>
<pre><code class="language-jsx">import {reducer as appReducer} from &quot;./app/redux&quot;;</code></pre>
<p>reducer를 결합하는 과정에서 기존 reducer 이름으로 사용하게 되면 다른 reducer와 겹칠 수 있는데 이를 해결할 수 있는 방법은 as를 사용하는 것이다.
as를 사용하면 기존 export하던 이름을 변경하여 가져올 수 있다.</p>
<ol>
<li>reducer가 여러 개인 경우 combineReducers 를 사용하여 하나로 결합한다.</li>
<li>결합한 reducer를 최종적으로 createStore로 생성 시켜준다.</li>
<li>생성한 store를 export하고 index.js에 불러와 provider로 &lt;App / &gt;을 감싸준 후 props 값으로 store를 필수로 넘겨주어야한다.</li>
<li>최종적으로 <App /> 안에서 redux로 state를 관리할 수 있다.</li>
</ol>
<br />

<p><strong>dispatch</strong></p>
<blockquote>
<p>** action 전송하기 **
dispatch는 store에 있는 state 값을 변경하고자 할 때 사용한다.</p>
</blockquote>
<p>useDispatch 라는 hooks을 사용하여 dispatch를 선언해준다.</p>
<pre><code class="language-jsx">const dispatch = useDispatch();</code></pre>
<ul>
<li>dispatch()의 인자로는 type이 담긴 action을 넣어주어야한다. (action 생성자는 type이 담긴 plain object를 반환한다.)</li>
<li>dispatch로 인자에 원하는 값을 넘길 수 있다.</li>
<li>dispatch는 받은 인자를 reducer로 전송한다. 그러면 reducer는 현재 state와 받은 action을 콜백으로 가지고 있게된다.</li>
<li>받은 action이 어떤 type인지 확인해준 후 거기에 맞는 state를 update 된다.<br />

</li>
</ul>
<p><strong>useSelector</strong></p>
<blockquote>
<p><strong>state를 꺼내서 사용하기</strong>
useSelector를 이용하여 어디서나 쉽게 꺼낼 수 있다.</p>
</blockquote>
<pre><code class="language-jsx">const app = useSelector(state =&gt; state.app);
//화살표 함수에서 바로 리턴한것</code></pre>
<p>const app 으로 선언하여 사용하면 app.openSidebar처럼 사용할 수 있으며</p>
<pre><code class="language-jsx">const { openSidebar } = useSelector(state =&gt; state.app);</code></pre>
<p>chaining 하지 않고 바로 쓰고 싶다면 객체 분해 할당으로 바로 분해해서 사용 가능하다.</p>
<br />

<h2 id="styled-components-props로-style-제어">styled-components: props로 style 제어</h2>
<p>styled-components에서 props 여부로 스타일을 다르게 줄 수 있다.
<br /></p>
<pre><code class="language-jsx">&lt;Container openSidebar={openSidebar}&gt;
&lt;/Container&gt;</code></pre>
<p>먼저 제어할 컴포넌트에 props를 넣어준다.</p>
<pre><code class="language-jsx">const Container = styled.div`
    transform: ${props =&gt; props.openSidebar ?
    &quot;none&quot; : &quot;translateX(-100%)&quot;};
`</code></pre>
<p>style을 적용하는 곳에 props를 가져와서 삼항연산자로 대입한다.
es6 문법인 백틱(``) 기호 안에 있기 때문에 중괄호 표현법 ${ }을 사용하여 자바스크립트 언어를 사용할 수 있다.</p>
<br />

<h2 id="es6-arrow-function-구분하기">es6: arrow function 구분하기</h2>
<ul>
<li>() =&gt; (({})) 객체 리턴</li>
<li>() =&gt; ({}) 객체 {} 를 리턴</li>
<li>() =&gt; {} 함수 내부 (block)</li>
<li>() =&gt; 1 즉시 리턴</li>
</ul>
<pre><code class="language-javascript">() =&gt; {
    dispatch()
}</code></pre>
<p>dispatch는 return으로 값을 반환하지 않고 단순히 실행하는 구문이기에 ({}) 리턴하는 소괄호가 필요하지 않다.</p>
<br />

<hr>
<h2 id="review-📃">review 📃</h2>
<p>첫 til이다 📒
공부하면서 메모했던 것을 다시 옮겨 적는 데에만 두시간이 걸렸다..ㅠㅠ</p>
<p>이해 하는 것과 그걸 정리하는 것은 정말 어마어마한 차이가 나는 것 같다.
하지만 부족한 내용을 다듬고 글로 표현하면서 한번 더 이해 할 수 있고, 다음에 꺼내어 읽기에 편하게 정리해놓으니 좋았다.
앞으로 작성하면서 잘 정리해놓은 좋은 기록물들이 될 수 있었으면 좋겠다.</p>
]]></description>
        </item>
    </channel>
</rss>