<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yulong Ruan</title>
    <description>The latest articles on DEV Community by Yulong Ruan (@ruanyl).</description>
    <link>https://dev.to/ruanyl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F291287%2Fa59ad304-7da1-47db-92de-89cc45c7316b.png</url>
      <title>DEV Community: Yulong Ruan</title>
      <link>https://dev.to/ruanyl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ruanyl"/>
    <language>en</language>
    <item>
      <title>Better development experience with Redux</title>
      <dc:creator>Yulong Ruan</dc:creator>
      <pubDate>Thu, 12 Dec 2019 21:39:58 +0000</pubDate>
      <link>https://dev.to/ruanyl/better-development-experience-with-redux-2oe7</link>
      <guid>https://dev.to/ruanyl/better-development-experience-with-redux-2oe7</guid>
      <description>&lt;h3&gt;
  
  
  Introduction to Reapex
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://reapex.lili.li/"&gt;Reapex&lt;/a&gt; is a lightweight framework to build pluggable and extendable redux/react application. &lt;/p&gt;

&lt;p&gt;Reapex offers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Strong-typed state, selectors, actions out of the box.&lt;/li&gt;
&lt;li&gt;Writing Redux code with NO action creators, NO action type constants, less maintenance headache.&lt;/li&gt;
&lt;li&gt;Making code-splitting easier.&lt;/li&gt;
&lt;li&gt;Support plugins, create reusable plugins and share them with others.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Motivation
&lt;/h3&gt;

&lt;p&gt;As a frontend developer who uses React &amp;amp; Redux extensively on a daily basis, I found I got tired of writing Redux boilerplates at some point, all those action creators, action types make me boring.&lt;/p&gt;

&lt;p&gt;Every time when I got excited to develop a new feature, the boilerplate makes me down because I have to repeat those similar codes again and again. It's also a lot of headaches to maintain them in a large codebase.&lt;/p&gt;

&lt;p&gt;There are libraries out there that can solve my problem partially, but they all missed something. Especially if I'd like to have everything strong-typed with TypeScript, for example, strong-typed state, selector and action.&lt;/p&gt;

&lt;p&gt;I came up with the idea of writing something for myself, then &lt;a href="https://reapex.lili.li/"&gt;Reapex&lt;/a&gt; was born. I introduced it to my friends and the people on my team. They like the idea and start to use it and I get positive feedback from them. Now &lt;a href="https://reapex.lili.li/"&gt;Reapex&lt;/a&gt; is used in an enterprise application at PROD.&lt;/p&gt;

&lt;p&gt;So I'd like to introduce it to more people and I wish it could help people who have a similar problem. &lt;/p&gt;

&lt;h3&gt;
  
  
  Get started
&lt;/h3&gt;

&lt;p&gt;Installing Reapex and peer dependencies. If you add Reapex to an existing React application, you may already have all of them in your existing application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Install reapex&lt;/span&gt;
yarn add reapex

&lt;span class="c"&gt;# 2. Install peer dependencies if you don't have them&lt;/span&gt;
yarn add react react-dom redux react-redux redux-saga immutable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Create a model
&lt;/h3&gt;

&lt;p&gt;A model can be simply a slice of the redux global state, Reapex creates an Immutable Record from the initialValue. Think about it as the initial state of a reducer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reapex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CounterModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create Mutations
&lt;/h3&gt;

&lt;p&gt;The mutations describe how the model data will be updated.&lt;/p&gt;

&lt;p&gt;The mutations function accepts an object as the first parameter in which the key describes the operation and value is a function that describes the mutation input and output. This is similar to the reducers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;CounterModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;total&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;decrease&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;total&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: typescript will infer the type of initialState and create the strong-typed immutable Record with it. In this case, the state we used here will be &lt;em&gt;Record&amp;lt;{total: number}&amp;gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The return value of mutations function is a tuple: &lt;em&gt;[actionCreators, actionTypes]&lt;/em&gt;, the first value in the tuple is action creators. The second value is the action types.&lt;/p&gt;

&lt;p&gt;With Reapex, there will be no Redux boilerplates of action creators and action types. You will get them from Reapex and they are strong-typed with TS out of the box.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Connect with Component
&lt;/h3&gt;

&lt;p&gt;Reapex only helps you to create the store &amp;amp; state. Connecting with components is just like any other React &amp;amp; Redux applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CounterModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useDispatch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;decrease&lt;/span&gt;&lt;span class="p"&gt;())}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;-&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mutations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;+&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NOTE: the &lt;em&gt;CounterModel.selectors&lt;/em&gt; is strong type and the &lt;em&gt;total&lt;/em&gt; here will be  a &lt;em&gt;number&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's it! You can find the live example here: &lt;a href="https://codesandbox.io/s/reapex-example-counter-9pyy6"&gt;counter example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Found it interesting and want to learn more? Check out the &lt;a href="https://reapex.lili.li/"&gt;reapex website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found it useful, please give it a star at &lt;a href="https://github.com/ruanyl/reapex"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>redux</category>
      <category>react</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
