Writing Money Transfers in React — Part 2

Zac Tolley
Scropt
Published in
9 min readApr 23, 2018
Photo by rawpixel.com on Unsplash

So for this part, I’m going to assume that you are comfortable with Javascript and Sass and have some exposure to Gulp and have at least had a glance at React JS. The aim is to get the foundation of the page laid, at the end we will have a basic React JS app that ‘compiles’ and displays in the browser but doesn’t actually ‘do’ anything.

The hardest thing is always getting started and structuring your project, everybody has an opinion and every project is a little different. I miss the ‘convention over configuration’ that some frameworks give you but the idea should be relatively clear. The project is split into 2 halves, client and server. The server doesn’t do anything right now but serve static assets, but in time it will. The client is made up of static pieces such as the html and images, and ‘source code’ in the form of raw Javascript and Sass.

The part 2 code can be found at Github at https://github.com/ztolley/money-transfers/tree/Part2 . I’m not going to show all the code in this blog post, so head over there to grab a copy

You’ll need NodeJS and NPM installed. Everything here is Javascript or Sass. At the top level of the project we have a package.json file that also includes a few handy scripts for building and developing. In the server folder there is a single app.js file, which provides a NodeJS server, and in the client folder there is the following:

  • js Source JS files
  • sass Source Sass files
  • public Static files such as index.html and images, also the target for compiled JS and CSS
  • Gulpfile Build instructions to assemble styles and javascript

React JS

React is really good at taking state and rendering it into html and then handling events, which in turn change the state which triggers a re-render. The simplest example is you tell react that its initial state has x=1 and show that on the screen with a button. When you click on the button you change the state to x=2, this triggers react to re-render and now you see 2.

React lets you use composition in your components so one component can contain others.

This example shows that the component uses another component when it renders it’s HTML. The really nice thing is components just look like custom HTML tags, so your layout code is concise and easy to read.

React components have 2 important elements, state and properties. When I first started I was a bit confused but the simple rule of thumb seems to be, you pass properties to a sub component and in that sub component you cannot change them, they are fixed constants. State is something that lives within a component, it gives it behaviour and changes over time. So in this example the message is fixed and doesn’t change in the greeting component, you could have a state value of ‘visible’, which would dictate if something is displayed or not. If you are unsure of any of this then head over to the react is site and try out the tutorial.

React Component Structure

Take a look at the screen of what the page will look like, the layout needs to be broken down into components, each one should do one job and do it well. By breaking down your page into multiple components it makes them small and easy to maintain and test.

At the top level we need an application ‘thing’ that starts things off, so I’ve called it ‘money.js’. This script has the job of getting the top level component and putting it into the page.

For the components the top level is going to be called ‘MoneyTransfers’, it contains a list of ‘MoneyTransfer’ components. Each Money transfer has 3 parts, the account from, account to and the amount. The amount can be a simple text field but the to and from need to do a number of jobs:

  • Show an ‘add’ card if nothing is selected
  • Show the current selected account if there is one
  • Show a list of cards if you are picking one

I’ve called the component that does this ‘TransferAccount’ for want of a better name. This component needs to show one or more cards. The final component is ‘AccountCard’, this will show bank account details.

One more thing… ES6

Before I start to go into the code and build process, you may have noticed we are using ES6. If you look online you’ll find examples in ES5 and others using ES6. ES6 is actually now called ES2015, which was agreed on in 2015, surprise surprise (keeping track?).

Some parts of ES6 syntax are not at first glance obvious, and may even look like errors, so there is a learning curve for sure. I was sceptical at first, as many still are, but have grown to really like it plus the React community seems to have adopted it.

As no browsers out there really support ES6/2015 you have to use a tool like Babel to compile your code into ES5 (the version of Javascript that most browsers support).

You can write your code in ES5 if you want, but you still have to compile the ‘jsx’ for react into regular JavaScript and as ES6 gives you lots of nice things to make your code more concise, why not. And it looks good on your CV.

If you look closer at the code here you’ll see that it’s not just ES6 but actually ES6 + Stage-0. Stage-0 is a collection of new syntax and features that are not yet part of the official ES syntax, the main one being ‘fat arrow function class properties’, which form part of ES7.

// ES6
class Fred extends Component {
constructor(props) {
super(props)
this.handler = this.handler.bind(this);
}
handler(event) {
...
}
}
// ES6 + Stage-0
class Fred extends Component {
handler = (event) => {
...
}
}

In a class, if you want to create a function that is used to handle events or be called from a map function, it’s ‘this’ context is all wrong, so you have to bind it back to the class. The convention of making a property equal to itself bound to ‘this’ in a constructor just feels wrong and a workaround as bad as ‘var that = this;’

MoneyTransfers.js

import React, { Component } from 'react';
import MoneyTransfer from './money-transfer';
export default class MoneyTransfers extends Component { renderTransfer = (transfer, index) => {
return (
<MoneyTransfer transfer={transfer} key={index}/>
);
}
render() {
return (
<div>
<ul id="transfers" className="card-list" data-count={this.props.transferData.length}>
{this.props.transferData.map(this.renderTransfer)}
</ul>
</div>
);
}
}MoneyTransfers.propTypes = {
transferData: React.PropTypes.array,
};

So lets start off simple, the component shows a list of MoneyTransfer components. ES6 introduces classes to Javascript and ReactJS supports the idea of a user component inheriting from React.Component class. The ‘export default’ statement is part of ES6’s package system and is used in combination with the new ‘import’ functionality.

The ‘renderTransfer’ method is an ES7 fat arrow class property, so it has ‘this’ bound to the class, even when called from a map. Both ‘render’ and ‘renderTransfer’ use JSX syntax to make layout code readable.

Finally, it’s good practice to tell react what datatypes your properties should be, so when you call one it will verify that it’s the correct type.

MoneyTransfer.js

import React, { Component } from 'react';
import TransferAccount from './transfer-account';
export default class MoneyTransfer extends Component { render() {
const transfer = this.props.transfer;
let completed = true;
if (transfer.amount === null ||
transfer.amount === '' ||
transfer.amount === '0' ||
!transfer.accountFrom || !transfer.accountTo) {
completed = false;
}
return (
<li className='transfer'>
<div className="grid-row card-select-row">
<div className="column-one-half">
<div className="form-label">From:</div>
<TransferAccount account={transfer.accountFrom} />
</div>
<div className="column-one-half">
<div className="form-label">To:</div>
<TransferAccount account={transfer.accountTo} />
</div>
</div>
<div className="grid-row">
<div className="column-one-half">
<div className="form-group">
<label className="form-label" htmlFor="balance">Amount:</label>
<span className="input-group-prefix">£</span>
<input type="text"
id="balance"
name="account[balance]"
className="form-control form-control__number"
value={transfer.amount}
/>
</div>
</div>
<div className="column-one-half">
{completed && (
<a className="delete-button">Delete</a>
)}
</div>
</div>
</li>
);
}
}
MoneyTransfer.propTypes = {
transfer: React.PropTypes.object,
};

Ok, don’t worry. Now I know it looks bigger, but most of the bulk is plain old HTML. We have a little logic in there to check if the transfer we are looking at has all the data it needs, if it has then we can delete it, later. For now it just shows ‘Account from (TransferAccount)’, ‘Account to (TransferAccount)’ and the amount.

TransferAccount.js

import React, { Component } from 'react';
import AccountCard from './account-card';
export default class TransferAccount extends Component { render() {
if (this.props.account) {
return (
<ul className="card-list">
<li className="card-item">
<AccountCard account={this.props.account} />
</li>
</ul>
);
}
return (
<a className="card add">Select account</a>
);
}
}
TransferAccount.propTypes = {
account: React.PropTypes.object,
};

For now this class is really simple, because we aren’t doing anything complex in it but later this will grow. We do, however, introduce the idea that we can return different markup according to properties or state. In this if an account is passed in as a property we display it, otherwise we show a button that will be used late to select an account.

AccountCard.js

import React, { Component } from 'react';export default class AccountCard extends Component {  render() {
const account = this.props.account;
return (
<div className="card">
<div className="account card-title">{account.bank} {account.account_type}</div>
<dl className="labelvalue">
<dt className="label">Account number:</dt>
<dd className="value">0000{account.account_number}</dd>
<dt className="label">Sort code:</dt>
<dd className="value">{account.sort_code}</dd>
</dl>
</div>
);
}
}
AccountCard.propTypes = {
account: React.PropTypes.object,
};

The account card just displays things for now, and could be a simple react function component, but as we will add more later we’ll keep it as a regular component.

Build

So you have your react components written in jsx and ES6(stage-0), before they can run in a browser they need to be ‘transpiled’ into plain old Javascript. There are two popular approaches to this, the cool kids use WebPack, but because the build for the main site is a little more complex I use the other popular method Gulp combined with Browserify and plugins, including Babel, to do the compilation.

The Gulpfile is located in the client folder and has a target for building the styles we need and another for transpiling Javascript.

gulp.task('transpile', callback => {  return browserify({
entries: 'js/money.js',
extensions: ['.js'],
debug: true
})
.transform(babelify,{
"presets": ["es2015", "stage-0", "react"],
"plugins": ["transform-runtime"]
})
.bundle()
.on("error", function(error){
console.error( "\nError: ", error.message, "\n");
this.emit("end");
})
.pipe(source('money.js'))
.pipe(gulp.dest('./public/js'));
});

The gulp step uses browserify in combination with babelify. It looks a bit complicated, but it works The presets tell Babelify this is ES6 React code and that needs to support stage-0 features. The transform-runtime bit seems to produce smaller js files, feel free to Google it and find out why. This code creates a none minified debug version of the code that makes it easier to debug but is big. You can extend the build steps to not use debug and then use uglify to minimise the result. In addition to that, your production servers should zip your javascript assets so by the they are sent to the client they are much more manageable.

If you are using Chrome or Firefox, go find the React debugger plugin, this will not only let you see the properties and methods associated with a component, but also understands ES6 and JSX. It also finds your source and lets you step through it to make debugging a breeze (still don’t know how it does it).

So if want you to see all this working, goto the top of this project and type:

npm install
npm start

This will start up the node server, compile the components and you can see it in action at

http://localhost:3000

If you want to mess with the code then instead of ‘npm start’ use ‘npm run develop’, this will run the server and listen for changes to the code and compile them so you can just refresh the page and get the update.

Wrap up

OK so we have the structure for the project, we can build it and we can see it. In the next part we’ll add some behaviour to it.

--

--