Free AI web copilot to create summaries, insights and extended knowledge, download it at here
2956
Abstract
ame></div></div></figure><p id="0522">I’ve added a hidden input called <i>action-creator</i>, which I’ll detail later.</p><h1 id="068c">The Action Creators</h1><p id="6a6c">We haven’t covered how we get the data yet, but assume we get an object with the keys <i>name, age, and gender</i> with corresponding values.</p><p id="32ca">Firstly, we’ll need to validate the input. Secondly, since this data came from a form, all values are strings. For validation and casting the strings to JavaScript types, I’ll be using the library <a href="https://github.com/jquense/yup">yup</a>, but there’s also Joi among others.</p>
<figure id="f688">
<div>
<div>
<iframe class="gist-iframe" src="/gist/jacobp100/e9fdd04500ac5f45360824076acef5ea.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="eebc">For the actual action creator, I like to split it into two parts: a bit that takes valid input and performs something like an AJAX call; and a bit that validates the input and calls the first action.</p>
<figure id="f53b">
<div>
<div>
<iframe class="gist-iframe" src="/gist/jacobp100/8f3455ca6b7b39d29d5a631cdcdbe0be.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="7bbe">In practise, both these can fail, so you’ll want to handle those cases.</p><p id="7869">Earlier, I said that I added an input called <i>action-creator</i> into the form. We’ll need to create a map of the value of these inputs to actions creators we want to dispatch when the form is submitted. In this case, we only have the <i>add-cat</i> action creator.</p>
<figure id="ca20">
<div>
<div>
<iframe class="gist-iframe" src="/gist/jacobp100/b0714382b5f99f8a2e8d2400fa9888bf.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><h1 id="600e">Putting it Together: Browser</h1><p id="50d7">We’ll use Redux’s <a href="https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options">mapDispatchToProps</a> to create <i>handleCatAddition</i> function from earlier. This function will be called event that contains the form element submitted. To read the data from this form element, I’m using <a href="https://www.npmjs.com/package/form-serialize">form-serialize</a>.</p><p id="8030">The data we get from this be an object keyed by the name of the form elements, and values with the corresponding form element values. This object will include the key <i>action-creator</i>, which when comb
Options
ined with the action creators map previously, will give us an actual action creator to call.</p><p id="35cd">Now we know what action creator to call, and we have the data for this action creator, it’s just a case of linking it all together. Since this method is generic to all form submissions, we’ll create a factory.</p>
<figure id="a336">
<div>
<div>
<iframe class="gist-iframe" src="/gist/jacobp100/6fb6b93f3431fe0dbfe75c9534beb9fd.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="d95d">This factory is then used when <i>connect</i>ing your components.</p>
<figure id="7556">
<div>
<div>
<iframe class="gist-iframe" src="/gist/jacobp100/b4c5c2c736390a75ac82922ac98bbd40.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><h1 id="0ea4">Putting it Together: Server</h1><p id="4704">The server is actually even simpler — the basic setup is over at <a href="https://github.com/reactjs/react-router/blob/master/docs/guides/ServerRendering.md">React Router’s documentation</a>. We just need to extend this to create a store and handle the form actions.</p>
<figure id="4a41">
<div>
<div>
<iframe class="gist-iframe" src="/gist/jacobp100/aab0c96d9762c87c649f183ecae76dc6.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
</div>
</div>
</figure></iframe></div></div></figure><p id="817a">When you create the store on the client, you’ll want to use the global variable <i>__INITIAL_STATE__</i>. There’s more information for this over at the <a href="http://redux.js.org/docs/recipes/ServerRendering.html">Redux documentation</a>.</p><h1 id="d1a4">Summary</h1><p id="be0a">This was a quick overview on how to handle user input in a uniform way between the server and client.</p><p id="3d2c">Because we handle data in a consistent way and perform actions in a consistent way, it became really easy to share code between the client and server.</p><p id="3f0c">Earlier, I said that submitting a form could fail validation — for example, if the age was not a number. It’s easy to add form errors to the store and then show these in the form. By putting the errors in the store, you’ll get consistent form validation between the server and client.</p><p id="2800">In the few next posts, I’ll be detailing a bit on data fetching and how to handle more complicated forms.</p><p id="9afd">You can view the code for the completed project at <a href="https://github.com/jacobp100/react-isomophic-demo">https://github.com/jacobp100/react-isomophic-demo</a></p></article></body>