React: Predictable, consistent

When developing any project, there are a few questions we are always asking.

Are we making good decisions for our clients?

Who’s going to be maintaining this?

Are we making something that will be easily maintainable in the future, and is open to extensibility?

Are we building the right thing?

Recently at Media Suite we’ve taken on a large project where we are working with a combination of technologies, using React as the core of our front end component.

React is a great component library, and lends itself to creating components that are easily reusable and extensible.

That being said, React is a component library, and does not mandate a specific file structure or method of designing components. In fact, most of the decisions around how to manage different aspects of the client – such as state management and routing – are left to the developer.

Engineering consistency

While the simplicity of React is great for rapid development, consistency is key when developing in any technology. Having consistent patterns and practices makes it quicker and easier for other developers to pick up and start working on a project – thus facilitating agile and rapid development.

To make it easier for new developers to join a project, there are a few things we try to emphasise and make as clean and clear as possible.

  • File structure
  • Reusable common components
  • Automated testing

These things are also important when taking a long term view of a project. When it comes to maintaining a project down the line, it’s often not the original developers maintaining said project. In this case, a project that makes predictable decisions and is consistent throughout is a major asset.

File structure

As we work with a library as flexible as React, we’ve drawn on our experience working in other systems and technologies to inform our process. A large part of this is our experience working with Ember. Ember is rather prescriptive, and in (almost) all things there is an ‘Ember Way’ to do things. One of the great things about this is that everything is always in the place you expect it to be.

React on the other hand has some sage advice when it comes to file structure:

> Avoid too much nesting

> Don’t overthink it

And a popular method as written by Dan Abramov (Co-author of Redux, and Create React App): move files around until it feels right.

When determining the file structure for our projects with React, our goal is to make things as predictable as possible. The guidelines for this being:

  • Direction should be able to be taken almost entirely from the URL. Anything else should be easy to infer.
  • All globally used pieces of code – services, common components, config files, utilities – should live in the root of the app, clearly visible and accessible.
  • Anything that is shared should live at the level closest to the places that require it. This means that if two sibling routes use the same component, but no other routes in the system do, that component should live adjacent to those routes.

We borrowed a lot from Ember here, in particular the module unification rfc, particularly around the structure of component hierarchy and the abstraction of common factors.

Example (with indicative files):

Reusing common components

No-one can be across all parts of the codebase at all times, and this is particularly true for developers just coming on to a project. We’ve found that creating a set of reusable components with documentation has been a great aid in increasing our developer velocity.

Our general approach in this area has been to create a generic component at the global level, and then create instances of that, specific to a particular route or purpose. If the component does not need to be reused, we simply use that component with specific props. This allows us to keep the styles consistent across the system, and provides extremely clear links to where particular logic is happening.

Most importantly, the vast majority of our top level components are functional. They don’t tend to deal with state, and they don’t deal with requests or API calls. This was a deliberate decision to allow us to create a truly reusable set of tools.

We’re currently using Storybook to curate our component library. Storybook is an environment for viewing components in isolation. There are some good add-ons for this too, including the Info add-on, which provides the source code for a particular story. This makes it easy for developers to, at a glance, figure out what component is required for a particular task and how to use this component.

Automated tests

Automated tests are a valuable resource, and the benefits have been endlessly documented.

Tests should ensure that common paths and edge cases in business logic are responding in the intended manner, and be open to change. This doesn’t mean test less, and in fact often means test more. Having a really robust set of automated tests around reusable components provides us with a rock-solid foundation on which to build, particularly since the rest of the system is (for the most part) composing those components into forms and screens.

One of the biggest benefits we get from automated tests is the insurance of stability and predictability. If a new developer starts working on the project, well documented tests give them vision of the parts of the system their changes are affecting, and help to ensure that their changes aren’t having any unexpected effects.

Outcomes

Having a stable and consistent approach to building web applications that is transferable across projects has been extremely valuable for our team, and has allowed us to more easily draw upon resource external to the project team when appropriate.

Our approach has been formed over the course of a number of projects, keeping the long game in mind. We’re always looking to ensure that our projects will be maintainable in future, and open to change. Ensuring predictability and consistency goes a long way towards making that happen.

As developers, we are always asking, are we building the right thing?

Ferrymead – a history of innovation

Ferrymead is a suburb with a story, and it’s one marked with human ingenuity and technological achievement. What better place then, for an innovative software company to set up base?

168 years ago in 1850, 790 people arrived at Lyttelton on four ships.  Their goal was to make a new life alongside local Maori and colonial settlers already established on the Canterbury Plains. It was no easy ask.  Just to get started, they had to navigate a decent sized hill and river to get to their new settlement location – all carrying their worldly possessions on their backs.

December 28, 1850: Four ships land at Lyttelton (Christchurch City Libraries)

This was just the first in a series of constant challenges that they, and those coming afterward, would face while trying to grow a new city in an untamed land. But they were tough and ingenious people not shy of hard work, and present Christchurch is a testament to that.

The journey to settlement was tough. That first river ferry crossing was near the mouth of the Heathcote, next to the Avon/Heathcote Estuary. That is where Ferrymead is now – although of course it wasn’t called that then. The simple ferry service that had been established was likely a large but fairly simple row boat, able to carry people and pets, but not yet horses. That service came the following year. On the bank there was no wharf or other infrastructure, just a small shingle bank. They likely had to navigate marsh and mud to make their way onto the rudimentary road, which they would walk to their final destination on the Plains.

Ferrymead Hotel and Station, 1863 (Heritage Canterbury)

Although there were other places where you could cross the Heathcote, Ferrymead continued to be the primary point of access to routes over and around the hills to Lyttelton and back.  The simple ferry used for the first crossing didn’t last long, as it was clearly not the most efficient solution for transiting people and goods.  In fact a number of alternative solutions were adopted over the course of the next two decades.  They demonstrate the propensity of resourceful people to answer challenging problems with a variety of robust solutions, a mindset that Media Suite holds dear.

The Old Ferry Bridge, 1909 (Christchurch City Libraries)

Enhancing the ferry itself was the first immediate sign of adaptation. The boat itself, it’s location and the infrastructure supporting it, evolved a lot over the fourteen years it was operating.  The first crossing was close to the river mouth where the Ferrymead Bridge is now.

However within a year it had been moved upstream a bit to a more sheltered location. This move also allowed for the future building of a bridge in the old spot.  It was also upgraded to a pontoon which could carry horses so that a daily packhorse service was able open between Christchurch and Lyttelton in 1851.

At the new location, the new operator James Townsend built himself a new house and platform on the riverbank to facilitate getting on and off the ferry.

Over the time the ferry operated, the province had plans to establish a much more efficient way to transport people and goods across the river and beyond.  A bridge was of course on the table, not just for getting to Lyttelton, but also to Sumner which was a growing settlement in itself. Rail too was well advanced elsewhere in the world, and also considered for the Christchurch to Lyttelton run.  However, the nature of rail meant that a tunnel through the hill would be required to get to Lyttelton and that would take some time.

In the meantime though, in 1861 the Provincial Council decided to build a partial rail service that would stop at Ferrymead.  It would use some of the planned Christchurch to Lyttelton line, but add a temporary diversion to Ferrymead and a good wharf at its end for the transfer of goods and people onto boats.  Because of its role in reducing costs and increasing the export/import capacity, it was considered worth the cost. However, it was expected to become obsolete fairly quickly.

So in 1863, New Zealand’s first public railway service opened between Christchurch and Ferrymead.  It was an exciting and significant development for the province.

The life of the Ferrymead line turned out to be even shorter than expected when in 1867 the Moorhouse Tunnel through the hill to Lyttelton was completed considerably ahead of schedule. A direct line between Christchurch and Lyttelton soon followed, and the Ferrymead line, the first public railway line in New Zealand, also became the first public railway line to close.

Simultaneously with rail developments, a road bridge was planned at the site of the very first ferry service.  This would give easy access by road to Sumner, as well as eventually Lyttelton, and the increasing number of smaller settlements appearing on the Port Hills side of the Heathcote River.

The opening of the first railway in New Zealand, Christchurch to Lyttelton via Ferrymead (National Library)

The road bridge was completed in 1864, about four years before the tunnel opened and fourteen years after the first ferry crossing.  At that point the ferry service became uneconomical and eventually disappeared. The bridge incorporated a swing component that allowed boats to access the Heathcote River, so river borne transport continued for some time.  

Just 14 years after the arrival of the First Ships, all of these transport technologies and solutions had appeared and developed in Ferrymead cementing the suburb’s character as a hive of technology and adaptability.  Nowadays in Ferrymead, you don’t have to look far to find businesses and activities operating in just the same way, but of course with quite different tools and materials.

Media Suite is one such company proud to be in Ferrymead.

For further reading on the history of Ferrymead, I can recommend the following books (available in the library) and sites:-

– Sumner to Ferrymead, A Christchurch History by Walter de Thier
– Illustrated History of Canterbury by Anna Rogers