<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>atomicdev 님의 블로그</title>
    <link>https://atomicdev.tistory.com/</link>
    <description>자유로운 개발자 | Developing Life

30년간의 개발 경험을 바탕으로 자유롭고 창의적인 개발 노하우를 공유합니다. 발전을 꿈꾸는 개발자와 개발자를 꿈꾸는 미래의 개발자 모두와 함께 만들어 가고 싶습니다.</description>
    <language>ko</language>
    <pubDate>Wed, 15 Apr 2026 06:14:47 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>atomicdev</managingEditor>
    <image>
      <title>atomicdev 님의 블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/7265276/attach/c03976e2d56d415bbc446b7aac4b0908</url>
      <link>https://atomicdev.tistory.com</link>
    </image>
    <item>
      <title>슬라이딩테크 부착형 도어 클로저 출시 예정</title>
      <link>https://atomicdev.tistory.com/461</link>
      <description>&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #000000; text-align: left;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;슬라이딩테크, 부착형 도어 클로저 출시 예정&amp;hellip; 안전&amp;middot;편의성&lt;/span&gt;&lt;span&gt;&amp;nbsp;강화&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bV5KQ8/btsMkDQ0jim/8bHB5y4fVnZ6KNwnrz8ynk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bV5KQ8/btsMkDQ0jim/8bHB5y4fVnZ6KNwnrz8ynk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bV5KQ8/btsMkDQ0jim/8bHB5y4fVnZ6KNwnrz8ynk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbV5KQ8%2FbtsMkDQ0jim%2F8bHB5y4fVnZ6KNwnrz8ynk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;420&quot; height=&quot;283&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스마트 도어 솔루션 전문기업 **슬라이딩테크(Sliding Tech)**가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;신개념 부착형 도어 클로저&lt;/b&gt;를 출시할 예정이라고 밝혔다. 이번 신제품은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;무전원 반자동 방식&lt;/b&gt;을 적용해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;에너지 절감과 사용자 안전성&lt;/b&gt;을 강화한 것이 특징이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◇ 기존 제품 대비 설치 편의성 및 유지보수 효율 극대화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슬라이딩테크의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;부착형 도어 클로저&lt;/b&gt;는 기존 일체형 제품과 달리&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;기존 미닫이문에 간단히 부착하는 방식&lt;/b&gt;으로, 별도의 전기 배선이나 복잡한 설치 과정 없이 누구나 손쉽게 장착할 수 있다. 특히,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;유압 댐퍼 기술을 적용&lt;/b&gt;해 문이 부드럽게 닫히며, 끼임 사고를 방지하는 기능이 포함돼&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;어린이, 노약자, 반려동물이 있는 공간에서도 안전하게 사용할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 기존 일체형 제품과 비교해 유지보수 시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;고장난 부품만 교체할 수 있어 비용 절감 효과&lt;/b&gt;도 기대된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◇ 무전동 반자동 기술 적용&amp;hellip; 에너지 절감 및 친환경성 강화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슬라이딩테크는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;전력 없이 자동 개폐가 가능한 반자동 시스템&lt;/b&gt;을 적용해, 정전 시에도 정상 작동할 수 있도록 설계했다. 이는 전력 소모를 줄여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;냉난방비 절감 및 친환경적인 운영이 가능&lt;/b&gt;하다는 점에서 공공기관, 학교, 병원 등에서 큰 관심을 받고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슬라이딩테크 관계자는 **&amp;ldquo;기존 자동문 대비 경제적이면서도 안전한 솔루션을 제공하는 것이 목표&amp;rdquo;**라며, **&amp;ldquo;부착형 도어 클로저는 설치가 간편해 기존 도어를 쉽게 업그레이드할 수 있는 최적의 선택&amp;rdquo;**이라고 강조했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 제품은 현재 특허 출원을 완료했으며, 정식 출시는 오는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;하반기&lt;/b&gt;로 예정되어 있다. 기업 및 공공기관을 대상으로 한 사전 테스트도 진행 중이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;패키지.JPG&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2aMYr/btsMjLiOmAv/TKHubI1OuxcgywFqvjyFIk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2aMYr/btsMjLiOmAv/TKHubI1OuxcgywFqvjyFIk/img.jpg&quot; data-alt=&quot;도어클로저 패키지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2aMYr/btsMjLiOmAv/TKHubI1OuxcgywFqvjyFIk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2aMYr%2FbtsMjLiOmAv%2FTKHubI1OuxcgywFqvjyFIk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;414&quot; height=&quot;144&quot; data-filename=&quot;패키지.JPG&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;도어클로저 패키지&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;◇ 시장 전망과 기대 효과&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도어 하드웨어 및 인테리어 시장이 지속 성장하는 가운데,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;반자동 도어 클로저의 수요도 꾸준히 증가&lt;/b&gt;하고 있다. 슬라이딩테크의 신제품은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;기존 자동문과 수동문 사이의 틈새 시장을 공략&lt;/b&gt;하며, 특히&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;공간 활용과 유지보수 편의성을 중시하는 건축&amp;middot;인테리어 시장에서 높은 경쟁력을 가질 것으로 기대된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편, 슬라이딩테크는 신제품 출시와 함께 국내외 시장 진출을 확대하고, 공공기관 및 기업과의 협업을 통해 보급 확대에 나설 계획이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &amp;nbsp;&lt;b&gt;출시 예정일:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;2025년 하반기&lt;br /&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;문의:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;슬라이딩테크 공식 홈페이지 또는 고객센터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://slatech.co.kr/boards/14/view?referer=%2Fpages%2Fnews&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://slatech.co.kr/boards/14/view?referer=%2Fpages%2Fnews&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>아이디어</category>
      <category>슬라이딩테크 #중문 #반자동 #도어클로저 #부착형 #반자동도어클로저 #미다지</category>
      <author>atomicdev</author>
      <guid isPermaLink="true">https://atomicdev.tistory.com/461</guid>
      <comments>https://atomicdev.tistory.com/461#entry461comment</comments>
      <pubDate>Sat, 15 Feb 2025 08:22:36 +0900</pubDate>
    </item>
    <item>
      <title>18.Flux 아키텍처 완벽 이해: React 애플리케이션 상태 관리의 기초</title>
      <link>https://atomicdev.tistory.com/460</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;Flux 아키텍처 완벽 이해: React 애플리케이션 상태 관리의 기초&quot;&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1시간 분량 강의안 (Flux 기초)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강의 목표&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Flux 아키텍처의 개념과 필요성을 이해한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Flux의 주요 구성 요소(스토어, 디스패처, 액션, 뷰)를 학습한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Flux를 활용하여 React 애플리케이션의 상태 관리를 구현한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강의 목차&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. Flux란 무엇인가? (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Flux의 정의&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Flux는 Facebook에서 제안한 &lt;b&gt;React 애플리케이션을 위한 아키텍처 패턴&lt;/b&gt;으로, &lt;b&gt;단방향 데이터 흐름&lt;/b&gt;을 기반으로 설계되었습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Flux의 주요 특징&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;단방향 데이터 흐름&lt;/b&gt;: 데이터가 항상 한 방향으로 흐르며, 상태 관리가 예측 가능.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;컴포넌트 간 독립성&lt;/b&gt;: 컴포넌트가 상태 대신 데이터를 받기 때문에 독립적이고 재사용 가능.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;중앙 집중식 상태 관리&lt;/b&gt;: 상태가 중앙 저장소(Store)에 관리되어 상태 변경 추적이 용이.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Flux의 구성 요소&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Action&lt;/b&gt;: 상태 변경을 요청하는 명령.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Dispatcher&lt;/b&gt;: Action을 Store로 전달하는 중앙 허브.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Store&lt;/b&gt;: 상태와 로직을 관리하는 컨테이너.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;View&lt;/b&gt;: Store의 데이터를 기반으로 UI를 렌더링.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. Flux의 데이터 흐름 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Flux 데이터 흐름&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Action&lt;/b&gt;: 이벤트 발생 시 액션을 생성.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Dispatcher&lt;/b&gt;: 액션을 Store에 전달.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Store&lt;/b&gt;: 액션을 처리하고 상태를 업데이트.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;View&lt;/b&gt;: 상태 변경을 감지하여 UI를 업데이트.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Flux와 MVC의 차이점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;특징FluxMVC&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;데이터 흐름&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단방향 데이터 흐름&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;양방향 데이터 흐름&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;상태 관리&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Store에서 중앙 관리&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여러 Model에서 분산 관리&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;복잡도&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단순하고 예측 가능&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;복잡하고 의존성 증가&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. Flux의 주요 구성 요소 구현 (20분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: Action 생성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;액션은 상태 변경 요청을 나타내는 객체.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733742755075&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const Actions = {
  increment: () =&amp;gt; {
    Dispatcher.dispatch({
      type: 'INCREMENT',
    });
  },
  decrement: () =&amp;gt; {
    Dispatcher.dispatch({
      type: 'DECREMENT',
    });
  },
};&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: Dispatcher 설정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Dispatcher는 액션을 Store로 전달하는 역할.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733742762523&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { Dispatcher } from 'flux';

const AppDispatcher = new Dispatcher();
export default AppDispatcher;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3단계: Store 생성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Store는 상태를 관리하고 변경 사항을 View에 알림.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733742771906&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { EventEmitter } from 'events';
import AppDispatcher from './AppDispatcher';

const Store = Object.assign({}, EventEmitter.prototype, {
  count: 0,

  getCount() {
    return this.count;
  },

  handleAction(action) {
    switch (action.type) {
      case 'INCREMENT':
        this.count++;
        this.emit('change');
        break;
      case 'DECREMENT':
        this.count--;
        this.emit('change');
        break;
      default:
        break;
    }
  },
});

AppDispatcher.register(Store.handleAction.bind(Store));
export default Store;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4단계: View에서 Store 사용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;View는 Store 데이터를 구독하고 변경 시 UI를 업데이트.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733742779248&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useState, useEffect } from 'react';
import Store from './Store';
import Actions from './Actions';

function Counter() {
  const [count, setCount] = useState(Store.getCount());

  useEffect(() =&amp;gt; {
    const handleChange = () =&amp;gt; setCount(Store.getCount());
    Store.on('change', handleChange);

    return () =&amp;gt; {
      Store.removeListener('change', handleChange);
    };
  }, []);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={Actions.increment}&amp;gt;Increment&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={Actions.decrement}&amp;gt;Decrement&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Counter;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. Flux 활용 사례 및 비교 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Flux 활용 사례&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Flux는 단방향 데이터 흐름이 필요한 대규모 애플리케이션에서 주로 사용됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Redux와 MobX의 설계 철학에 영향을 미친 패턴입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Flux와 Redux 비교&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;특징FluxRedux&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Dispatcher 사용 여부&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사용&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사용하지 않음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Store&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여러 Store&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단일 Store&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;데이터 흐름&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단방향 데이터 흐름&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단방향 데이터 흐름&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Boilerplate 코드&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;상대적으로 많음&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;상대적으로 간결함&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 실습 과제 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;실습 과제&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Flux 패턴을 사용하여 Todo 애플리케이션을 구현하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Todo 항목을 추가, 완료 표시, 삭제하는 액션과 Store를 작성하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변경 사항을 View에서 반영하세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;액션 예제:&lt;/span&gt;&lt;/span&gt;
&lt;pre id=&quot;code_1733742792767&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;const Actions = {
  addTodo: (text) =&amp;gt; {
    Dispatcher.dispatch({
      type: 'ADD_TODO',
      text,
    });
  },
};&lt;/code&gt;&lt;/pre&gt;
&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Store 예제:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733742801126&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const Store = Object.assign({}, EventEmitter.prototype, {
  todos: [],

  handleAction(action) {
    switch (action.type) {
      case 'ADD_TODO':
        this.todos.push({ text: action.text, completed: false });
        this.emit('change');
        break;
      default:
        break;
    }
  },
});&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. Q&amp;amp;A 및 정리 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Q&amp;amp;A:&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Flux와 Redux의 주요 차이점은 무엇인가요?&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Flux는 어떤 규모의 애플리케이션에서 적합한가요?&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;요약:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Flux는 React 애플리케이션에서 단방향 데이터 흐름을 관리하기 위한 강력한 패턴입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Action, Dispatcher, Store, View의 구성 요소를 이해하고 활용하면 상태 관리를 효율적으로 구현할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Redux와 같은 현대적인 상태 관리 도구의 기초가 되는 개념입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>React/React Core</category>
      <category>Flux</category>
      <category>flux구현</category>
      <category>flux기초</category>
      <category>React</category>
      <category>reactflux</category>
      <category>react상태관리</category>
      <category>단방향데이터흐름</category>
      <category>상태관리</category>
      <category>웹개발</category>
      <category>프론트엔드개발</category>
      <author>코딩쉐프</author>
      <guid isPermaLink="true">https://atomicdev.tistory.com/460</guid>
      <comments>https://atomicdev.tistory.com/460#entry460comment</comments>
      <pubDate>Mon, 9 Dec 2024 20:13:48 +0900</pubDate>
    </item>
    <item>
      <title>17.React Context API로 상태 관리하기: Props Drilling 없이 데이터 공유</title>
      <link>https://atomicdev.tistory.com/459</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;React Context API로 상태 관리하기: Props Drilling 없이 데이터 공유&quot;&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1시간 분량 강의안 (Context API 상태 관리)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강의 목표&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Context API를 상태 관리 목적으로 사용하는 방법을 이해한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Props Drilling 문제를 해결하는 Context API의 기본 개념을 학습한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Context API를 사용하여 전역 상태 관리와 컴포넌트 간 데이터 공유를 구현한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강의 목차&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. Context API란 무엇인가? (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Context API의 정의&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Context API는 컴포넌트 계층 구조를 통해 데이터를 전달할 때 &lt;b&gt;Props Drilling&lt;/b&gt; 문제를 해결하기 위한 &lt;b&gt;전역 상태 관리 도구&lt;/b&gt;입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Context API의 주요 구성 요소&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Context&lt;/b&gt;: 전역 상태를 관리하는 객체를 생성.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Provider&lt;/b&gt;: 데이터를 하위 컴포넌트에 전달.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Consumer&lt;/b&gt;: 데이터를 소비하는 컴포넌트.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Context API의 동작 방식&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Provider에서 데이터를 제공하고, 하위 컴포넌트에서 Consumer 또는 useContext Hook으로 데이터를 소비.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Context API의 장점&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Props Drilling 없이 컴포넌트 간 데이터를 공유.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React의 내장 기능으로 추가 설치 불필요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. Context API를 사용한 상태 관리 설정 (15분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: Context 생성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Context를 생성하여 데이터 관리.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733742621941&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { createContext } from 'react';

const CounterContext = createContext();
export default CounterContext;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: Provider로 상태 관리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Provider 컴포넌트를 사용해 상태와 업데이트 함수를 공유.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733742628420&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useState } from 'react';
import CounterContext from './CounterContext';

function CounterProvider({ children }) {
  const [count, setCount] = useState(0);

  const increment = () =&amp;gt; setCount((prev) =&amp;gt; prev + 1);
  const decrement = () =&amp;gt; setCount((prev) =&amp;gt; prev - 1);

  return (
    &amp;lt;CounterContext.Provider value={{ count, increment, decrement }}&amp;gt;
      {children}
    &amp;lt;/CounterContext.Provider&amp;gt;
  );
}

export default CounterProvider;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3단계: Provider로 감싸기&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;최상위 컴포넌트를 Provider로 감싸 데이터 공유.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733742635868&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import CounterProvider from './CounterProvider';
import App from './App';

function Root() {
  return (
    &amp;lt;CounterProvider&amp;gt;
      &amp;lt;App /&amp;gt;
    &amp;lt;/CounterProvider&amp;gt;
  );
}

export default Root;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. Context 데이터 소비하기 (15분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: useContext Hook 사용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;useContext로 데이터를 직접 소비.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733742642403&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useContext } from 'react';
import CounterContext from './CounterContext';

function Counter() {
  const { count, increment, decrement } = useContext(CounterContext);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={increment}&amp;gt;Increment&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={decrement}&amp;gt;Decrement&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Counter;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: Consumer 사용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Consumer를 사용하여 데이터 소비(구식 방식).&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733742649825&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import CounterContext from './CounterContext';

function Counter() {
  return (
    &amp;lt;CounterContext.Consumer&amp;gt;
      {({ count, increment, decrement }) =&amp;gt; (
        &amp;lt;div&amp;gt;
          &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
          &amp;lt;button onClick={increment}&amp;gt;Increment&amp;lt;/button&amp;gt;
          &amp;lt;button onClick={decrement}&amp;gt;Decrement&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      )}
    &amp;lt;/CounterContext.Consumer&amp;gt;
  );
}

export default Counter;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. Context API로 상태 관리 구현 (15분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: 다중 Context 관리&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여러 Context를 조합하여 사용.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733742656929&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const ThemeContext = createContext();
const CounterContext = createContext();

function App() {
  return (
    &amp;lt;ThemeContext.Provider value={{ theme: 'dark' }}&amp;gt;
      &amp;lt;CounterContext.Provider value={{ count: 10 }}&amp;gt;
        &amp;lt;ChildComponent /&amp;gt;
      &amp;lt;/CounterContext.Provider&amp;gt;
    &amp;lt;/ThemeContext.Provider&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: 중첩된 Context 소비&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여러 Context를 동시에 소비.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733742663491&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function ChildComponent() {
  const { theme } = useContext(ThemeContext);
  const { count } = useContext(CounterContext);

  return (
    &amp;lt;div style={{ color: theme === 'dark' ? 'white' : 'black' }}&amp;gt;
      Count: {count}
    &amp;lt;/div&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 실습 과제 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;실습 과제&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Context API를 사용하여 사용자 이름과 나이를 관리하고 화면에 표시하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;테마(Context)를 추가하여 배경색을 변경할 수 있는 버튼을 구현하세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733742670668&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function ThemeToggler() {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    &amp;lt;button onClick={toggleTheme}&amp;gt;
      현재 테마: {theme === 'dark' ? '다크' : '라이트'}
    &amp;lt;/button&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. Q&amp;amp;A 및 정리 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Q&amp;amp;A:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Context API와 Redux의 차이점은 무엇인가요?&lt;/li&gt;
&lt;li&gt;Context API는 어떤 규모의 애플리케이션에 적합한가요?&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;요약:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Context API는 Props Drilling 문제를 해결하며, 간단한 전역 상태 관리에 유용합니다.&lt;/li&gt;
&lt;li&gt;Provider로 상태를 제공하고, useContext로 데이터를 소비합니다.&lt;/li&gt;
&lt;li&gt;Redux와 달리 복잡한 상태 관리는 적합하지 않을 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>React/React Core</category>
      <category>contextapi</category>
      <category>propsdrilling해결</category>
      <category>React</category>
      <category>react기초</category>
      <category>react상태관리</category>
      <category>react전역상태관리</category>
      <category>useContext</category>
      <category>상태관리</category>
      <category>웹개발</category>
      <category>프론트앤드</category>
      <author>코딩쉐프</author>
      <guid isPermaLink="true">https://atomicdev.tistory.com/459</guid>
      <comments>https://atomicdev.tistory.com/459#entry459comment</comments>
      <pubDate>Mon, 9 Dec 2024 20:11:57 +0900</pubDate>
    </item>
    <item>
      <title>16.Jotai로 배우는 React 상태 관리: 최소화된 경량 상태 관리 솔루션</title>
      <link>https://atomicdev.tistory.com/458</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;Jotai로 배우는 React 상태 관리: 최소화된 경량 상태 관리 솔루션&quot;&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1시간 분량 강의안 (Jotai 기초)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강의 목표&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Jotai의 개념과 필요성을 이해한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Jotai의 주요 기능(Atoms, Selectors)을 학습한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Jotai를 활용하여 React 애플리케이션에서 효율적으로 상태를 관리하는 방법을 익힌다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강의 목차&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvvBUv/btsK4v1KaXh/zhRlzxrMk9B7DtNUeGDZkk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvvBUv/btsK4v1KaXh/zhRlzxrMk9B7DtNUeGDZkk/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvvBUv/btsK4v1KaXh/zhRlzxrMk9B7DtNUeGDZkk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvvBUv%2FbtsK4v1KaXh%2FzhRlzxrMk9B7DtNUeGDZkk%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;372&quot; height=&quot;372&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. Jotai란 무엇인가? (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Jotai의 정의&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Jotai는 &lt;b&gt;React를 위한 최소화된 상태 관리 라이브러리&lt;/b&gt;로, 상태를 단일 객체 대신 여러 Atom으로 분리하여 관리할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;Jotai&quot;는 일본어로 &quot;원자(atom)&quot;를 의미하며, &lt;b&gt;Atomic 상태 관리&lt;/b&gt;를 목표로 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Jotai의 주요 특징&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;간결한 API&lt;/b&gt;: 상태 정의와 사용이 간단.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Atomic 상태 관리&lt;/b&gt;: 필요한 상태만 구독하여 성능 최적화.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;React 친화적&lt;/b&gt;: React의 useState와 유사한 방식으로 상태 관리.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;모듈화&lt;/b&gt;: 상태를 독립적으로 관리하고 재사용 가능.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Jotai의 주요 구성 요소&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Atom&lt;/b&gt;: 상태의 최소 단위.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Derived Atom&lt;/b&gt;: 기존 Atom의 값을 기반으로 생성된 파생 상태.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. Jotai 설치 및 기본 설정 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: Jotai 설치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Jotai 설치:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151366810&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install jotai&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: 기본 Atom 생성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;상태를 정의하는 Atom 작성:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151391575&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { atom } from 'jotai';

export const countAtom = atom(0); // 초기값 0&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. Jotai 주요 개념 및 구현 (20분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: Atom 사용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React 컴포넌트에서 Atom의 상태를 가져와 사용:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151404295&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { useAtom } from 'jotai';
import { countAtom } from './atoms';

const Counter = () =&amp;gt; {
  const [count, setCount] = useAtom(countAtom);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;Increment&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count - 1)}&amp;gt;Decrement&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Counter;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: Derived Atom 생성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존 Atom을 기반으로 파생 상태 생성:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151426668&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { atom } from 'jotai';
import { countAtom } from './atoms';

export const doubleCountAtom = atom((get) =&amp;gt; get(countAtom) * 2);&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3단계: Derived Atom 사용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React 컴포넌트에서 Derived Atom 값 사용:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151436433&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { useAtom } from 'jotai';
import { doubleCountAtom } from './atoms';

const DoubleCounter = () =&amp;gt; {
  const [doubleCount] = useAtom(doubleCountAtom);

  return &amp;lt;p&amp;gt;Double Count: {doubleCount}&amp;lt;/p&amp;gt;;
};

export default DoubleCounter;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4단계: 비동기 Atom 생성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;비동기 데이터를 관리하는 Atom:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151455821&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { atom } from 'jotai';

export const asyncDataAtom = atom(async () =&amp;gt; {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
  return response.json();
});&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. 고급 Jotai 기능 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: Atom의 상태 조작&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Atom의 상태를 직접 설정하는 함수 작성:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151463173&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const incrementAtom = atom(
  (get) =&amp;gt; get(countAtom),
  (get, set) =&amp;gt; set(countAtom, get(countAtom) + 1)
);&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: Atom Family&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;비슷한 역할을 가진 여러 Atom을 동적으로 생성:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151491409&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { atomFamily } from 'jotai/utils';

const itemAtomFamily = atomFamily((id) =&amp;gt; atom({ id, value: 0 }));&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3단계: Jotai Devtools&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;상태 디버깅을 위한 Devtools 설치:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;pre id=&quot;code_1733151537860&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;npm install jotai-devtools&lt;/code&gt;&lt;/pre&gt;
&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사용:&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151546911&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { useAtomsDebugValue } from 'jotai-devtools';

function DebugComponent() {
  useAtomsDebugValue();
  return null;
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 실습 과제 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;실습 과제&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Jotai를 사용하여 카운터 애플리케이션을 구현하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Derived Atom을 사용하여 카운터 값을 두 배로 계산하여 화면에 표시하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;비동기 Atom을 생성하여 API 데이터를 화면에 표시하세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;비동기 데이터 컴포넌트:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151556308&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { useAtom } from 'jotai';
import { asyncDataAtom } from './atoms';

const AsyncData = () =&amp;gt; {
  const [data] = useAtom(asyncDataAtom);

  if (!data) return &amp;lt;p&amp;gt;Loading...&amp;lt;/p&amp;gt;;

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;{data.title}&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;{data.body}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default AsyncData;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. Q&amp;amp;A 및 정리 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Q&amp;amp;A:&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Jotai는 어떤 상황에서 적합한 상태 관리 도구인가요?&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Jotai와 Zustand의 차이점은 무엇인가요?&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;요약:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Jotai는 최소화된 상태 관리 라이브러리로, 간단한 API를 통해 효율적으로 상태를 관리할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Atom과 Derived Atom을 사용해 상태와 파생 데이터를 관리합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React와 자연스럽게 통합되며, 비동기 데이터를 쉽게 관리할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>React/React Core</category>
      <category>jotai</category>
      <category>jotai기초</category>
      <category>React</category>
      <category>reactjotai</category>
      <category>react상태관리</category>
      <category>경량상태관리</category>
      <category>상태관리</category>
      <category>웹개발</category>
      <category>컴포넌트상태관리</category>
      <category>프론트엔드개발</category>
      <author>코딩쉐프</author>
      <guid isPermaLink="true">https://atomicdev.tistory.com/458</guid>
      <comments>https://atomicdev.tistory.com/458#entry458comment</comments>
      <pubDate>Tue, 3 Dec 2024 00:00:44 +0900</pubDate>
    </item>
    <item>
      <title>15.React Query로 서버 상태 관리하기: 효율적인 데이터 페칭과 캐싱</title>
      <link>https://atomicdev.tistory.com/457</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;React Query로 서버 상태 관리하기: 효율적인 데이터 페칭과 캐싱&quot;&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1시간 분량 강의안 (React Query 기초)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강의 목표&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Query의 개념과 필요성을 이해한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Query의 주요 기능(데이터 페칭, 캐싱, 뮤테이션)을 학습한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Query를 활용한 서버 상태 관리 방법을 실습한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강의 목차&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/19APZ/btsK3leCCTB/9nVneBa0pvJStknqvBtRB0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/19APZ/btsK3leCCTB/9nVneBa0pvJStknqvBtRB0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/19APZ/btsK3leCCTB/9nVneBa0pvJStknqvBtRB0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F19APZ%2FbtsK3leCCTB%2F9nVneBa0pvJStknqvBtRB0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;398&quot; height=&quot;398&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. React Query란 무엇인가? (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;React Query의 정의&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Query는 &lt;b&gt;React 애플리케이션에서 서버 상태를 관리하고 데이터 페칭과 캐싱&lt;/b&gt;을 간단하게 만들어주는 라이브러리입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;React Query의 주요 특징&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;데이터 동기화&lt;/b&gt;: 클라이언트와 서버 간의 데이터를 동기화.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;자동 캐싱&lt;/b&gt;: 데이터가 변경되지 않으면 캐시된 데이터를 사용하여 네트워크 요청 감소.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;리트라이와 리페치&lt;/b&gt;: 실패한 요청을 자동으로 재시도하거나, 데이터가 오래된 경우 자동으로 새로고침.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;개발자 도구&lt;/b&gt;: 상태 디버깅을 위한 React Query Devtools 제공.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;React Query의 주요 구성 요소&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Query&lt;/b&gt;: 데이터를 가져오는 작업.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Mutation&lt;/b&gt;: 데이터를 생성, 수정, 삭제하는 작업.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Query Client&lt;/b&gt;: React Query의 중앙 관리 객체.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. React Query 설치 및 기본 설정 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: React Query 설치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733151071139&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install @tanstack/react-query&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: Query Client 설정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;애플리케이션의 최상위 컴포넌트에 Query Client를 설정합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733151095229&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import App from './App';

const queryClient = new QueryClient();

function Root() {
  return (
    &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
      &amp;lt;App /&amp;gt;
    &amp;lt;/QueryClientProvider&amp;gt;
  );
}

export default Root;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. React Query 주요 기능 및 구현 (20분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: 데이터 페칭(Query)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;서버에서 데이터를 가져오는 기본 예제:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733151108865&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { useQuery } from '@tanstack/react-query';

function fetchPosts() {
  return fetch('https://jsonplaceholder.typicode.com/posts').then((res) =&amp;gt;
    res.json()
  );
}

function Posts() {
  // 수정된 useQuery 형태 (단일 객체 사용)
  const { data, isLoading, isError } = useQuery({
    queryKey: ['posts'],
    queryFn: fetchPosts,
  });

  if (isLoading) return &amp;lt;p&amp;gt;Loading...&amp;lt;/p&amp;gt;;
  if (isError) return &amp;lt;p&amp;gt;Error fetching data.&amp;lt;/p&amp;gt;;

  return (
    &amp;lt;ul&amp;gt;
      {data.map((post) =&amp;gt; (
        &amp;lt;li key={post.id}&amp;gt;{post.title}&amp;lt;/li&amp;gt;
      ))}
    &amp;lt;/ul&amp;gt;
  );
}

export default Posts;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App.js&lt;/p&gt;
&lt;pre id=&quot;code_1734480445435&quot; class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;import React from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import Posts from './Posts'; // default export 확인

const queryClient = new QueryClient();

function App() {
  return (
    &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;React Query Example - Posts&amp;lt;/h1&amp;gt;
        &amp;lt;Posts /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/QueryClientProvider&amp;gt;
  );
}

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: 데이터 뮤테이션(Mutation)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;데이터를 생성, 수정, 삭제하는 작업:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151130674&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//CreatePost.js
import React from 'react';
import { useMutation } from '@tanstack/react-query';

function createPost(newPost) {
  return fetch('https://jsonplaceholder.typicode.com/posts', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(newPost),
  }).then((res) =&amp;gt; res.json());
}

function CreatePost() {
  // 수정된 useMutation 형태 (단일 객체 사용)
  const mutation = useMutation({
    mutationFn: createPost,
  });

  const handleCreate = () =&amp;gt; {
    mutation.mutate({ title: 'New Post', body: 'This is a new post.' });
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;button onClick={handleCreate}&amp;gt;Create Post&amp;lt;/button&amp;gt;
      {mutation.isLoading &amp;amp;&amp;amp; &amp;lt;p&amp;gt;Creating post...&amp;lt;/p&amp;gt;}
      {mutation.isSuccess &amp;amp;&amp;amp; &amp;lt;p&amp;gt;Post created!&amp;lt;/p&amp;gt;}
      {mutation.isError &amp;amp;&amp;amp; &amp;lt;p&amp;gt;Error creating post!&amp;lt;/p&amp;gt;}
    &amp;lt;/div&amp;gt;
  );
}

export default CreatePost;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3단계: 캐싱 및 리페치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;캐싱된 데이터를 사용하는 경우:&lt;/span&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733151138077&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const { data } = useQuery(['posts'], fetchPosts, {
  staleTime: 5000, // 데이터가 5초 동안 신선한 상태로 유지
});&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. React Query Devtools 사용 (5분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;설치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1733151156928&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install @tanstack/react-query-devtools&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;사용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1733151165236&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

function Root() {
  return (
    &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
      &amp;lt;App /&amp;gt;
      &amp;lt;ReactQueryDevtools initialIsOpen={false} /&amp;gt;
    &amp;lt;/QueryClientProvider&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 실습 과제 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;실습 과제&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;서버에서 데이터를 페칭하여 화면에 표시하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;데이터를 생성하거나 수정하는 버튼을 구현하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Query Devtools를 사용하여 상태를 확인하세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. Q&amp;amp;A 및 정리 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Q&amp;amp;A:&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Query와 Redux의 차이점은 무엇인가요?&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Query는 어떤 상황에서 적합한 상태 관리 도구인가요?&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;요약:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Query는 서버 상태를 간단하게 관리하고, 데이터 페칭 및 캐싱을 효율적으로 처리할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Query와 Mutation을 활용하여 다양한 서버 작업을 처리할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Query Devtools로 상태를 시각적으로 디버깅할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>React/React Core</category>
      <category>React</category>
      <category>reactQuery</category>
      <category>ReactQueryDevtools</category>
      <category>reactquery기초</category>
      <category>react서버상태관리</category>
      <category>개발</category>
      <category>데이터페칭</category>
      <category>상태관리</category>
      <category>캐싱</category>
      <category>프론트엔드</category>
      <author>코딩쉐프</author>
      <guid isPermaLink="true">https://atomicdev.tistory.com/457</guid>
      <comments>https://atomicdev.tistory.com/457#entry457comment</comments>
      <pubDate>Mon, 2 Dec 2024 23:54:06 +0900</pubDate>
    </item>
    <item>
      <title>14.Zustand로 배우는 경량 상태 관리: 간단하고 빠른 React 상태 관리 솔루션</title>
      <link>https://atomicdev.tistory.com/456</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Zustand로 배우는 경량 상태 관리: 간단하고 빠른 React 상태 관리 솔루션&quot;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1시간 분량 강의안 (Zustand 기초)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;강의 목표&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Zustand의 개념과 장점을 이해한다.&lt;/li&gt;
&lt;li&gt;Zustand의 주요 기능(상태 생성, 업데이트, 구독)을 학습한다.&lt;/li&gt;
&lt;li&gt;Zustand를 활용하여 React 애플리케이션에서 상태를 관리하는 방법을 익힌다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;강의 목차&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VQ5YN/btsK3uoYj1A/0IrMT4uwGRl049MsqI8As0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VQ5YN/btsK3uoYj1A/0IrMT4uwGRl049MsqI8As0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VQ5YN/btsK3uoYj1A/0IrMT4uwGRl049MsqI8As0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVQ5YN%2FbtsK3uoYj1A%2F0IrMT4uwGRl049MsqI8As0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;454&quot; height=&quot;454&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. Zustand란 무엇인가? (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Zustand의 정의&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Zustand는 React 애플리케이션에서 사용되는 &lt;b&gt;간단하고 경량화된 상태 관리 라이브러리&lt;/b&gt;입니다.&lt;/li&gt;
&lt;li&gt;독일어로 &quot;상태&quot;라는 뜻이며, 직관적이고 선언적인 상태 관리를 제공합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Zustand의 주요 특징&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;간결한 API&lt;/b&gt;: 상태 생성과 사용이 간단.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;퍼포먼스 최적화&lt;/b&gt;: 필요한 컴포넌트만 렌더링.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;React와 독립적&lt;/b&gt;: React 외부에서도 사용 가능.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;미들웨어 확장&lt;/b&gt;: 로깅, 지속성, Devtools와 같은 기능 확장 지원.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Zustand의 주요 구성 요소&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Store&lt;/b&gt;: 상태를 정의하고 관리하는 중앙 저장소.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Actions&lt;/b&gt;: 상태를 변경하는 함수.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Selectors&lt;/b&gt;: 필요한 상태만 선택적으로 구독.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. Zustand 설치 및 기본 설정 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1단계: Zustand 설치&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Zustand 설치:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150782166&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install zustand&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2단계: 기본 Store 생성&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태를 정의하는 Store 작성:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150808049&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import create from 'zustand';

const useStore = create((set) =&amp;gt; ({
  count: 0,
  increment: () =&amp;gt; set((state) =&amp;gt; ({ count: state.count + 1 })),
  decrement: () =&amp;gt; set((state) =&amp;gt; ({ count: state.count - 1 })),
}));

export default useStore;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. Zustand 주요 개념 및 구현 (20분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1단계: 상태 사용&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;React 컴포넌트에서 Store의 상태와 함수를 가져와 사용:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150828495&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import useStore from './store';

const Counter = () =&amp;gt; {
  const { count, increment, decrement } = useStore();

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={increment}&amp;gt;Increment&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={decrement}&amp;gt;Decrement&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Counter;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2단계: Selectors 활용&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필요한 상태만 구독하여 렌더링 최적화:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150837276&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const count = useStore((state) =&amp;gt; state.count);&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3단계: 상태 초기화&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Store 상태를 초기화하는 함수 추가:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150857707&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const useStore = create((set) =&amp;gt; ({
  count: 0,
  increment: () =&amp;gt; set((state) =&amp;gt; ({ count: state.count + 1 })),
  decrement: () =&amp;gt; set((state) =&amp;gt; ({ count: state.count - 1 })),
  reset: () =&amp;gt; set({ count: 0 }),
}));&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 고급 Zustand 기능 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1단계: 미들웨어 추가&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태를 로컬 스토리지에 저장:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150864974&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import create from 'zustand';
import { persist } from 'zustand/middleware';

const useStore = create(
  persist(
    (set) =&amp;gt; ({
      count: 0,
      increment: () =&amp;gt; set((state) =&amp;gt; ({ count: state.count + 1 })),
    }),
    { name: 'counter-storage' }
  )
);

export default useStore;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2단계: Zustand Devtools&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태 디버깅을 위한 Devtools 통합:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150884919&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import create from 'zustand';
import { devtools } from 'zustand/middleware';

const useStore = create(
  devtools((set) =&amp;gt; ({
    count: 0,
    increment: () =&amp;gt; set((state) =&amp;gt; ({ count: state.count + 1 })),
  }))
);

export default useStore;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 실습 과제 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실습 과제&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Zustand를 사용하여 카운터 애플리케이션을 구현하세요.&lt;/li&gt;
&lt;li&gt;카운터 값이 10 이상일 때 &quot;최대 값 도달&quot; 메시지를 표시하세요.&lt;/li&gt;
&lt;li&gt;Zustand Devtools와 로컬 스토리지 저장 기능을 추가하세요.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;카운터 상태 확인 컴포넌트:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150893512&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import useStore from './store';

const CounterInfo = () =&amp;gt; {
  const count = useStore((state) =&amp;gt; state.count);

  return &amp;lt;p&amp;gt;{count &amp;gt;= 10 ? '최대 값 도달' : `Count: ${count}`}&amp;lt;/p&amp;gt;;
};

export default CounterInfo;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. Q&amp;amp;A 및 정리 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Q&amp;amp;A:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Zustand와 Redux의 차이점은 무엇인가요?&lt;/li&gt;
&lt;li&gt;Zustand는 어떤 상황에서 적합한 상태 관리 도구인가요?&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;요약:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Zustand는 React와 독립적으로 작동하는 간단하고 경량화된 상태 관리 라이브러리입니다.&lt;/li&gt;
&lt;li&gt;상태 정의, 업데이트, 구독이 간단하며, Selectors를 사용해 성능을 최적화할 수 있습니다.&lt;/li&gt;
&lt;li&gt;미들웨어 확장을 통해 로컬 스토리지 저장 및 Devtools 디버깅이 가능합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>React/React Core</category>
      <category>React</category>
      <category>reactzustand기초</category>
      <category>react상태관리</category>
      <category>zustand</category>
      <category>zustand사용법</category>
      <category>개발</category>
      <category>경량상태관리</category>
      <category>상태관리</category>
      <category>웹개발</category>
      <category>프론트엔드</category>
      <author>코딩쉐프</author>
      <guid isPermaLink="true">https://atomicdev.tistory.com/456</guid>
      <comments>https://atomicdev.tistory.com/456#entry456comment</comments>
      <pubDate>Mon, 2 Dec 2024 23:49:36 +0900</pubDate>
    </item>
    <item>
      <title>13.Recoil로 배우는 React 상태 관리: 간단하고 강력한 최신 상태 관리 라이브러리</title>
      <link>https://atomicdev.tistory.com/455</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Recoil로 배우는 React 상태 관리: 간단하고 강력한 최신 상태 관리 라이브러리&quot;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1시간 분량 강의안 (Recoil 기초)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;강의 목표&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Recoil의 개념과 필요성을 이해한다.&lt;/li&gt;
&lt;li&gt;Recoil의 주요 구성 요소(Atoms, Selectors, RecoilRoot)를 학습한다.&lt;/li&gt;
&lt;li&gt;Recoil을 활용하여 React 애플리케이션에서 상태를 관리하는 방법을 익힌다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;강의 목차&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdjN6U/btsK3N23il2/aRw7XXfngqiZw9NXY9uVZ0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdjN6U/btsK3N23il2/aRw7XXfngqiZw9NXY9uVZ0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdjN6U/btsK3N23il2/aRw7XXfngqiZw9NXY9uVZ0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdjN6U%2FbtsK3N23il2%2FaRw7XXfngqiZw9NXY9uVZ0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;429&quot; height=&quot;429&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. Recoil이란 무엇인가? (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Recoil의 정의&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Recoil은 React를 위한 &lt;b&gt;친화적인 상태 관리 라이브러리&lt;/b&gt;로, 상태를 관리하고 컴포넌트 간의 상태 공유를 간단하게 만듭니다.&lt;/li&gt;
&lt;li&gt;Facebook에서 개발되었으며, React의 특성을 최대한 활용하도록 설계되었습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Recoil의 주요 특징&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;React 친화적&lt;/b&gt;: React의 상태 관리 방식과 자연스럽게 통합.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정확한 상태 구독&lt;/b&gt;: 상태가 필요한 컴포넌트만 다시 렌더링.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비동기 상태 관리&lt;/b&gt;: Selectors를 활용하여 비동기 데이터 로드 처리.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Recoil의 주요 구성 요소&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Atom&lt;/b&gt;: 상태의 최소 단위로, 상태를 저장하고 공유.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Selector&lt;/b&gt;: Atom을 기반으로 파생된 데이터를 생성.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;RecoilRoot&lt;/b&gt;: Recoil 상태를 사용할 수 있는 컨텍스트를 제공.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. Recoil 설치 및 기본 설정 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1단계: Recoil 설치&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Recoil 설치:
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733150351733&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;npm install recoil&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2단계: RecoilRoot 설정&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Recoil 상태를 애플리케이션에서 사용하려면 RecoilRoot로 감싸야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150362663&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { RecoilRoot } from 'recoil';
import App from './App';

const Root = () =&amp;gt; (
  &amp;lt;RecoilRoot&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/RecoilRoot&amp;gt;
);

export default Root;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. Recoil 주요 개념 및 구현 (20분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1단계: Atom 생성&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Atom은 상태의 최소 단위로, React 컴포넌트에서 공유 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150463409&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { atom } from 'recoil';

export const counterState = atom({
  key: 'counterState', // Atom의 고유 ID
  default: 0,         // 초기 상태 값
});&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2단계: Atom 사용&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;React 컴포넌트에서 Atom을 사용하려면 useRecoilState를 활용.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150471066&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { useRecoilState } from 'recoil';
import { counterState } from './atoms';

const Counter = () =&amp;gt; {
  const [count, setCount] = useRecoilState(counterState);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;Increment&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count - 1)}&amp;gt;Decrement&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Counter;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3단계: Selector 사용&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Selectors를 통해 Atom을 기반으로 파생된 데이터를 생성.
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150493679&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { selector } from 'recoil';
import { counterState } from './atoms';

export const doubleCounterState = selector({
  key: 'doubleCounterState',
  get: ({ get }) =&amp;gt; {
    const count = get(counterState);
    return count * 2;
  },
});&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4단계: Selector 값 사용&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;React 컴포넌트에서 Selector 값을 읽기.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150499012&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { useRecoilValue } from 'recoil';
import { doubleCounterState } from './selectors';

const DoubleCounter = () =&amp;gt; {
  const doubleCount = useRecoilValue(doubleCounterState);

  return &amp;lt;p&amp;gt;Double Count: {doubleCount}&amp;lt;/p&amp;gt;;
};

export default DoubleCounter;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 고급 Recoil 기능 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1단계: 비동기 Selector&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버에서 데이터를 로드하여 상태로 사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150522543&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { selector } from 'recoil';

export const asyncData = selector({
  key: 'asyncData',
  get: async () =&amp;gt; {
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    const data = await response.json();
    return data;
  },
});&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2단계: Atom Effects&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Atom에 추가적인 효과(예: 로컬 스토리지 저장) 적용.
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150531691&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { atom } from 'recoil';

export const localStorageState = atom({
  key: 'localStorageState',
  default: 0,
  effects: [
    ({ setSelf, onSet }) =&amp;gt; {
      const savedValue = localStorage.getItem('state');
      if (savedValue != null) {
        setSelf(JSON.parse(savedValue));
      }

      onSet((newValue) =&amp;gt; {
        localStorage.setItem('state', JSON.stringify(newValue));
      });
    },
  ],
});&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 실습 과제 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실습 과제&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Recoil을 사용하여 카운터 애플리케이션을 구현하세요.&lt;/li&gt;
&lt;li&gt;카운터 값을 Selector로 두 배로 계산하여 화면에 표시하세요.&lt;/li&gt;
&lt;li&gt;비동기 데이터를 로드하여 화면에 표시하세요.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비동기 데이터 컴포넌트:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733150552660&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { useRecoilValue } from 'recoil';
import { asyncData } from './selectors';

const AsyncComponent = () =&amp;gt; {
  const data = useRecoilValue(asyncData);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Async Data&amp;lt;/h1&amp;gt;
      &amp;lt;pre&amp;gt;{JSON.stringify(data, null, 2)}&amp;lt;/pre&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default AsyncComponent;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. Q&amp;amp;A 및 정리 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Q&amp;amp;A:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Recoil은 Redux와 비교했을 때 어떤 점에서 더 간단한가요?&lt;/li&gt;
&lt;li&gt;Recoil을 사용하면 Context API는 필요 없나요?&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;요약:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Recoil은 React 애플리케이션에서 상태 관리가 필요한 경우 간단하고 직관적인 해결책을 제공합니다.&lt;/li&gt;
&lt;li&gt;Atom과 Selector를 통해 상태와 파생 데이터를 쉽게 관리할 수 있습니다.&lt;/li&gt;
&lt;li&gt;RecoilRoot로 상태 관리의 범위를 지정하고, React Hooks로 상태를 간단히 사용할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>React/React Core</category>
      <category>React</category>
      <category>reactrecoil</category>
      <category>react상태관리</category>
      <category>recoil</category>
      <category>recoil기초</category>
      <category>recoil사용법</category>
      <category>상태관리</category>
      <category>웹개발</category>
      <category>컴포넌트상태관리</category>
      <category>프론트엔드</category>
      <author>코딩쉐프</author>
      <guid isPermaLink="true">https://atomicdev.tistory.com/455</guid>
      <comments>https://atomicdev.tistory.com/455#entry455comment</comments>
      <pubDate>Mon, 2 Dec 2024 23:44:46 +0900</pubDate>
    </item>
    <item>
      <title>React 함수와 JavaScript 함수의 차이</title>
      <link>https://atomicdev.tistory.com/454</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;React 함수와 JavaScript 함수는 근본적으로 JavaScript에서 실행되는 코드이지만, React에서 사용하는 함수는 React의 특정 개념이나 기능에 초점을 맞춥니다. 아래는 React 함수와 JavaScript 함수의 차이점과 용도에 대한 설명입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. &lt;b&gt;JavaScript 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript 함수는 코드의 재사용성을 높이고 특정 작업을 수행하기 위해 정의된 일반적인 함수입니다. React와 관계없이 순수하게 JavaScript 언어 자체에서 사용하는 함수입니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;특징:&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;목적&lt;/b&gt;: 특정 작업을 수행하거나 값을 반환.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;종류&lt;/b&gt;: 일반 함수, 화살표 함수, 익명 함수 등.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;호출 방법&lt;/b&gt;: 직접 호출하거나 이벤트에 의해 호출.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;유형&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;일반 함수&lt;/b&gt;:
&lt;pre id=&quot;code_1733096865972&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;function add(a, b) {
  return a + b;
}
console.log(add(2, 3)); // 5&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;화살표 함수&lt;/b&gt;:
&lt;pre id=&quot;code_1733096875888&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const multiply = (a, b) =&amp;gt; a * b;
console.log(multiply(2, 3)); // 6&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;사용 예:&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 계산하거나 처리할 때.&lt;/li&gt;
&lt;li&gt;이벤트 핸들러를 정의할 때.&lt;/li&gt;
&lt;li&gt;모듈화된 로직을 구현할 때.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. &lt;b&gt;React 함수&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React에서 사용하는 함수는 &lt;b&gt;컴포넌트 함수&lt;/b&gt; 또는 &lt;b&gt;Hooks&lt;/b&gt;가 포함됩니다. React는 JavaScript의 라이브러리이므로 React 함수도 JavaScript 함수지만, React 애플리케이션을 구성하기 위해 특별한 규칙과 사용 목적이 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(1) &lt;b&gt;React 컴포넌트 함수&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React에서는 컴포넌트를 정의할 때 함수형 컴포넌트를 사용할 수 있습니다. 이는 UI를 렌더링하기 위한 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특징:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;React의 상태와 생명주기를 다룰 수 있음.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JSX를 반환&lt;/b&gt;하여 UI를 정의.&lt;/li&gt;
&lt;li&gt;반드시 첫 글자를 대문자로 작성해야 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예:&lt;/p&gt;
&lt;pre id=&quot;code_1733096897423&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;function Greeting(props) {
  return &amp;lt;h1&amp;gt;Hello, {props.name}!&amp;lt;/h1&amp;gt;;
}

// 사용
&amp;lt;Greeting name=&quot;Alice&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(2) &lt;b&gt;React Hook 함수&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React Hook은 React 16.8 이후 추가된 기능으로, 함수형 컴포넌트에서 상태와 생명주기를 사용할 수 있도록 도와주는 특수 함수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요 Hook:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;useState&lt;/b&gt;: 상태 관리
&lt;pre id=&quot;code_1733096919932&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;You clicked {count} times&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;Click me&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;useEffect&lt;/b&gt;: 사이드 이펙트 관리
&lt;pre id=&quot;code_1733096946039&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;import React, { useEffect } from 'react';

function Timer() {
  useEffect(() =&amp;gt; {
    console.log('Component mounted or updated');
    return () =&amp;gt; {
      console.log('Component unmounted');
    };
  });

  return &amp;lt;div&amp;gt;Check the console&amp;lt;/div&amp;gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;커스텀 Hook&lt;/b&gt;: 로직을 재사용하기 위해 사용자 정의 가능
&lt;pre id=&quot;code_1733096972614&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() =&amp;gt; {
    const handleResize = () =&amp;gt; setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () =&amp;gt; window.removeEventListener('resize', handleResize);
  }, []);

  return width;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. &lt;b&gt;React 함수와 JavaScript 함수의 주요 차이점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 101.047%; height: 197px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; width: 9.30233%;&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt; 항목 &lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; width: 34.095%;&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt; JavaScript 함수 &lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; width: 57.5329%;&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt; React 함수 &lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; width: 9.30233%;&quot;&gt;&lt;b&gt;목적&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 34.095%;&quot;&gt;일반적인 작업 수행&lt;/td&gt;
&lt;td style=&quot;height: 20px; width: 57.5329%;&quot;&gt;UI 렌더링 및 React 상태/생명주기 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;height: 40px; width: 9.30233%;&quot;&gt;&lt;b&gt;리턴값&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 40px; width: 34.095%;&quot;&gt;어떤 값이든 반환 가능 (문자열, 숫자, 객체 등)&lt;/td&gt;
&lt;td style=&quot;height: 40px; width: 57.5329%;&quot;&gt;JSX 또는 null&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;height: 40px; width: 9.30233%;&quot;&gt;&lt;b&gt;호출 방식&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 40px; width: 34.095%;&quot;&gt;직접 호출&lt;/td&gt;
&lt;td style=&quot;height: 40px; width: 57.5329%;&quot;&gt;React에서 렌더링 중 호출 (컴포넌트 함수)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;height: 40px; width: 9.30233%;&quot;&gt;&lt;b&gt;특수 기능&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 40px; width: 34.095%;&quot;&gt;없음&lt;/td&gt;
&lt;td style=&quot;height: 40px; width: 57.5329%;&quot;&gt;Hook을 통해 상태와 생명주기 관리 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;height: 40px; width: 9.30233%;&quot;&gt;&lt;b&gt;사용 규칙&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 40px; width: 34.095%;&quot;&gt;제한 없음&lt;/td&gt;
&lt;td style=&quot;height: 40px; width: 57.5329%;&quot;&gt;컴포넌트 이름은 대문자로 시작, Hook은 특정 규칙 준수 (use로 시작)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결론&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JavaScript 함수는 범용적이며 React 외부에서도 사용 가능한 일반적인 함수입니다.&lt;/li&gt;
&lt;li&gt;React 함수는 React 애플리케이션 내에서 상태 관리, 생명주기 처리, UI 렌더링 등 React와 밀접하게 연관된 작업을 수행하기 위해 사용됩니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>React/React Core</category>
      <category>JSX</category>
      <category>리액트</category>
      <category>리액트초보팁</category>
      <category>리액트함수</category>
      <category>리액트훅</category>
      <category>웹개발</category>
      <category>자바스크립트</category>
      <category>자바스크립트함수</category>
      <category>프로그래밍팁</category>
      <category>프론트엔드개발</category>
      <author>atomicdev</author>
      <guid isPermaLink="true">https://atomicdev.tistory.com/454</guid>
      <comments>https://atomicdev.tistory.com/454#entry454comment</comments>
      <pubDate>Mon, 2 Dec 2024 08:52:01 +0900</pubDate>
    </item>
    <item>
      <title>12.MobX로 배우는 간단한 상태 관리: 직관적이고 강력한 React 상태 관리 도구</title>
      <link>https://atomicdev.tistory.com/453</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;MobX로 배우는 간단한 상태 관리: 직관적이고 강력한 React 상태 관리 도구&quot;&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1시간 분량 강의안 (MobX 기초)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강의 목표&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MobX의 개념과 장점을 이해한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MobX의 주요 개념(Observable, Action, Computed, Observer)을 학습한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MobX를 활용하여 React 애플리케이션에서 상태를 관리하는 방법을 익힌다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강의 목차&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3CEN4/btsKZuOFB3R/beqshLtVPjrGSym2aO7G40/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3CEN4/btsKZuOFB3R/beqshLtVPjrGSym2aO7G40/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3CEN4/btsKZuOFB3R/beqshLtVPjrGSym2aO7G40/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3CEN4%2FbtsKZuOFB3R%2FbeqshLtVPjrGSym2aO7G40%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;433&quot; height=&quot;433&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. MobX란 무엇인가? (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;MobX의 정의&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MobX는 &lt;b&gt;간단하고 직관적인 상태 관리 라이브러리&lt;/b&gt;입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React 애플리케이션에서 &lt;b&gt;상태를 관리하고 UI를 자동으로 업데이트&lt;/b&gt;합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;MobX의 주요 특징&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;반응성(Reactivity)&lt;/b&gt;: 상태가 변경되면 자동으로 관련된 UI를 업데이트.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;직관적 API&lt;/b&gt;: 상태를 관리하는 방법이 간단하며 코드가 읽기 쉽다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;유연성&lt;/b&gt;: Redux와 달리 불변성을 강제하지 않아 상태를 자유롭게 수정 가능.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;MobX의 주요 구성 요소&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Observable&lt;/b&gt;: 상태를 반응형 데이터로 정의.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Action&lt;/b&gt;: 상태를 변경하는 함수.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Computed&lt;/b&gt;: 상태에서 파생된 값을 생성.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Observer&lt;/b&gt;: 상태 변경을 감지하여 UI를 업데이트하는 React 컴포넌트.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. MobX 설치 및 기본 설정 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: MobX 설치&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MobX와 React 통합 패키지 설치:&lt;/span&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1732689606673&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install mobx mobx-react-lite&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: 프로젝트 구조&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기본 폴더 구조:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1732689632645&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;src/
├── stores/
│   └── counterStore.js
├── components/
│   └── Counter.js
└── App.js&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. MobX 주요 개념 및 구현 (20분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: Observable&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;상태를 관찰 가능한 데이터로 정의:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1732689641189&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { makeAutoObservable } from 'mobx';

class CounterStore {
  count = 0;

  constructor() {
    makeAutoObservable(this); // 상태를 자동으로 관찰 가능하도록 설정
  }

  increment() {
    this.count++;
  }

  decrement() {
    this.count--;
  }
}

const counterStore = new CounterStore();
export default counterStore;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: Observer&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React 컴포넌트를 상태 변경에 반응하도록 설정:&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1732689663261&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import { observer } from 'mobx-react-lite';
import counterStore from '../stores/counterStore';

const Counter = observer(() =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {counterStore.count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; counterStore.increment()}&amp;gt;Increment&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; counterStore.decrement()}&amp;gt;Decrement&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
});

export default Counter;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3단계: App 컴포넌트에서 사용&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1732689671654&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';
import Counter from './components/Counter';

function App() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;MobX Counter&amp;lt;/h1&amp;gt;
      &amp;lt;Counter /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. 고급 MobX 기능 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: Computed&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;상태에서 파생된 값을 생성:&lt;/span&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1732689704630&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;get isPositive() {
  return this.count &amp;gt; 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React 컴포넌트에서 사용:&lt;/span&gt;
&lt;div&gt;
&lt;div id=&quot;SE-1d0d19c3-740a-4c3d-b6a8-0125aee636fe&quot; data-a11y-title=&quot;코드&quot; data-compid=&quot;SE-1d0d19c3-740a-4c3d-b6a8-0125aee636fe&quot;&gt;
&lt;div&gt;
&lt;div data-direction=&quot;top&quot; data-compid=&quot;SE-1d0d19c3-740a-4c3d-b6a8-0125aee636fe&quot; data-unitid=&quot;&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;&amp;lt;p&amp;gt;{counterStore.isPositive ? &quot;Positive&quot; : &quot;Negative or Zero&quot;}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: Action&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;상태를 변경하는 메서드에 Action을 명시적으로 추가:&lt;/span&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1732689943714&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { action, makeObservable, observable } from 'mobx';

class CounterStore {
  count = 0;

  constructor() {
    makeObservable(this, {
      count: observable,
      increment: action,
      decrement: action,
    });
  }

  increment() {
    this.count++;
  }

  decrement() {
    this.count--;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 실습 과제 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;실습 과제&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MobX를 사용하여 카운터 애플리케이션을 구현하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;버튼 클릭으로 숫자를 증가/감소하고, 숫자가 0보다 작아지지 않도록 제한하세요.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;isPositive를 Computed로 구현하여 상태가 양수인지 여부를 화면에 표시하세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1732689966492&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;decrement() {
  if (this.count &amp;gt; 0) {
    this.count--;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. Q&amp;amp;A 및 정리 (10분)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Q&amp;amp;A:&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MobX와 Redux의 차이점은 무엇인가요?&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;작은 프로젝트에서 MobX는 적합한 선택인가요?&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;요약:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MobX는 React 애플리케이션에서 간단하고 직관적인 상태 관리를 제공합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Observable, Action, Computed, Observer는 MobX의 핵심 개념입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MobX는 상태를 효율적으로 관리하며, 작은 프로젝트에서 특히 유용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>React/React Core</category>
      <category>mobx</category>
      <category>mobx기초</category>
      <category>React</category>
      <category>reactmobx</category>
      <category>react상태관리</category>
      <category>상태관리</category>
      <category>웹개발</category>
      <category>컴포넌트상태관리</category>
      <category>프론트엔드</category>
      <category>프론트엔드개발</category>
      <author>코딩쉐프</author>
      <guid isPermaLink="true">https://atomicdev.tistory.com/453</guid>
      <comments>https://atomicdev.tistory.com/453#entry453comment</comments>
      <pubDate>Wed, 27 Nov 2024 15:47:25 +0900</pubDate>
    </item>
    <item>
      <title>11.Redux 완전 정복: 중앙 집중식 상태 관리의 기본</title>
      <link>https://atomicdev.tistory.com/452</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;Redux 완전 정복: 중앙 집중식 상태 관리의 기본&quot;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1시간 분량 강의안 (Redux 기초)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;강의 목표&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Redux의 개념과 필요성을 이해한다.&lt;/li&gt;
&lt;li&gt;Redux의 주요 개념(스토어, 액션, 리듀서)을 학습한다.&lt;/li&gt;
&lt;li&gt;Redux를 활용한 간단한 상태 관리 애플리케이션을 구현한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;강의 목차&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBdc1O/btsKYiO4OMM/1K739fQRZymSoLYibYRNYk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBdc1O/btsKYiO4OMM/1K739fQRZymSoLYibYRNYk/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBdc1O/btsKYiO4OMM/1K739fQRZymSoLYibYRNYk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBdc1O%2FbtsKYiO4OMM%2F1K739fQRZymSoLYibYRNYk%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;357&quot; height=&quot;357&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. Redux란 무엇인가? (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Redux의 정의&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Redux는 JavaScript 애플리케이션을 위한 &lt;b&gt;상태 관리 라이브러리&lt;/b&gt;입니다.&lt;/li&gt;
&lt;li&gt;애플리케이션의 상태를 &lt;b&gt;중앙 집중식 스토어&lt;/b&gt;에 저장하여, 상태 관리의 일관성을 유지합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Redux의 필요성&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;React 컴포넌트 간 Props Drilling을 해결.&lt;/li&gt;
&lt;li&gt;상태 관리가 복잡한 대규모 애플리케이션에서 데이터를 효율적으로 관리.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Redux의 3가지 핵심 원칙&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Single Source of Truth&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 상태는 &lt;b&gt;하나의 스토어&lt;/b&gt;에 저장됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;State is Read-Only&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태는 불변하며, 오직 **액션(Action)**을 통해 변경됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Changes are Made with Pure Functions&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태 변경은 **순수 함수(Pure Function)**인 리듀서(Reducer)를 통해 이루어집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. Redux 주요 구성 요소 (15분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1단계: 스토어(Store)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태가 저장되는 &lt;b&gt;중앙 데이터 저장소&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;스토어 생성:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1732689170143&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { createStore } from 'redux';

const store = createStore(reducer);&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2단계: 액션(Action)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상태를 변경하기 위해 디스패치되는 &lt;b&gt;순수 JavaScript 객체&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;액션 생성:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1732689199827&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const incrementAction = { type: 'INCREMENT' };&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3단계: 리듀서(Reducer)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 상태와 액션을 받아 새로운 상태를 반환하는 &lt;b&gt;순수 함수&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;리듀서 예제:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1732689210777&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function counterReducer(state = { count: 0 }, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Redux 데이터 흐름&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;UI에서 액션을 디스패치.&lt;/li&gt;
&lt;li&gt;리듀서가 액션을 처리하여 새로운 상태를 반환.&lt;/li&gt;
&lt;li&gt;스토어가 상태를 업데이트하고, UI가 다시 렌더링.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. Redux 기본 구현 (20분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1단계: 프로젝트 설정&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Redux 설치:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1732689238520&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install redux react-redux&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2단계: 스토어 생성 및 리듀서 연결&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;스토어 생성:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1732689247566&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { createStore } from 'redux';

const initialState = { count: 0 };

function counterReducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
}

const store = createStore(counterReducer);

export default store;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3단계: React 컴포넌트에서 Redux 사용&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Provider 설정:
&lt;pre id=&quot;code_1732689287981&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';

const root = createRoot(document.getElementById(&quot;root&quot;));

root.render(
  &amp;lt;Provider store={store}&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/Provider&amp;gt;
);&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;상태 사용 및 디스패치:
&lt;pre id=&quot;code_1732689298970&quot; class=&quot;javascript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;import React from 'react';
import { useSelector, useDispatch } from 'react-redux';

function Counter() {
  const count = useSelector((state) =&amp;gt; state.count);
  const dispatch = useDispatch();

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; dispatch({ type: 'INCREMENT' })}&amp;gt;Increment&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; dispatch({ type: 'DECREMENT' })}&amp;gt;Decrement&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Counter;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 실습 과제 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;실습 과제&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Redux를 사용하여 카운터 애플리케이션을 구현하세요.&lt;/li&gt;
&lt;li&gt;버튼 클릭으로 숫자를 증가/감소하고, 숫자가 0보다 작아지지 않도록 제한하세요.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1732689327607&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function counterReducer(state = { count: 0 }, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: Math.max(0, state.count - 1) }; // 최소값 제한
    default:
      return state;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. Q&amp;amp;A 및 정리 (10분)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Q&amp;amp;A:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Redux는 어떤 상황에서 사용하는 것이 적합한가요?&lt;/li&gt;
&lt;li&gt;Context API와 Redux의 차이는 무엇인가요?&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;요약:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Redux는 대규모 애플리케이션에서 상태 관리를 일관되게 처리하기 위한 강력한 도구입니다.&lt;/li&gt;
&lt;li&gt;스토어, 액션, 리듀서의 개념을 이해하고, React와의 연동을 통해 효율적인 상태 관리를 구현할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>React/React Core</category>
      <category>React</category>
      <category>ReactRedux</category>
      <category>react상태관리</category>
      <category>Redux</category>
      <category>reduxreducer</category>
      <category>redux기초</category>
      <category>redux사용법</category>
      <category>상태관리</category>
      <category>웹개발</category>
      <category>프론트엔드개발</category>
      <author>코딩쉐프</author>
      <guid isPermaLink="true">https://atomicdev.tistory.com/452</guid>
      <comments>https://atomicdev.tistory.com/452#entry452comment</comments>
      <pubDate>Wed, 27 Nov 2024 15:37:59 +0900</pubDate>
    </item>
  </channel>
</rss>