The three ‘R’s, Refactoring, React and Redux for robust async JS

The three ‘R’s, Refactoring, #ReactJS and #Redux for robust async #JavaScript:

  • The beauty of Redux Saga (or more generally generator functions) is that ‘forking’ to another saga still maintains unidirectional flow.
  • The solution was to split the saga into smaller, more functional blocks (which live in the same file), as in general they are concerned with a single user interaction (for example creating an invoice) and are only exported for testing purposes.
  • Both contain API calls and varied logic themselves, which made the single saga long, less readable, and involved a large amount of boilerplate code in each test.
  • Applying our thinking on modularizing large sagas we can fork sagas, doPolling , and bankSecurityChallenge , which were originally part of the single extended saga.
  • The first uses of sagas we implemented were simple API fetch calls, such as the example below.

The previous two articles in this series highlighted how frontend development practices at Xero have evolved over the past decade, and how we have resorted to building complex applications using…

@ReactiveConf: The three ‘R’s, Refactoring, #ReactJS and #Redux for robust async #JavaScript:

The previous two articles in this series highlighted how frontend development practices at Xero have evolved over the past decade, and how we have resorted to building complex applications using React and Redux. With building any application at scale, user-interactions that lead to a number of side-effects are unavoidable. This article will focus specifically on how we have come to use Redux Saga to manage these side-effects.

. While code in this form is not necessarily incorrect, it has the potential to make components more complex than they should be. This has a flow-on effect to the testability and maintainability of the component in-hand, where business logic is tied to the view/render layer.

Therefore if components are only concerned with rendering and dispatching actions while reducers are pure functions that calculate a new state, then where can impure business logic live? A code review from some Xero developers with more React and Redux experience led to a strong recommendation that instance lifecycle methods were not the place to call APIs, and we should look at middleware for Redux. We settled on using Redux Saga to encapsulate all of our business logic and haven’t looked back since.

The first uses of sagas we implemented were simple API fetch calls, such as the example below.

, which kicks off the saga chain, only really needs to test ‘can create’ logic, and that appropriate sagas are run in each case.

functions, side-effects can be controlled and dealt with whilst maintaining a logical unidirectional flow.

At this point we had another opportunity to share our work with other teams, and get another perspective. This was a rewarding process, which highlighted that perhaps modularization of sagas detracted from the developer’s way of looking at them — as a function representing a single user interaction with a unidirectional flow to match.

Conversely, this conversation highlighted that there certainly are cases for more modular sagas, as we gained exposure to other team’s implementations. The examples below shows the end result of a discussion we had with the Xero Dashboard project team, who created the complex saga we covered back in article one.

, which were originally part of the single extended saga. Both contain API calls and varied logic themselves, which made the single saga long, less readable, and involved a large amount of boilerplate code in each test. By breaking these apart, we can now also test each saga function separately.

As you can see, feedback and discussion in this way was extremely rewarding, as it brought to light limitations in different team’s implementation of the Redux Saga library. Even more so, it helped get the ball rolling towards a more cohesive, cross-team concept of saga best practice, which should ultimately improve company-wide understanding and implementation of sagas, among other frontend tools and modules.

Throughout the three articles in this series, we have covered a decade worth of frontend practices at Xero. The past year has seen the most significant change in frontend in our nearly 10 year history. From rebuilding old parts such as the Xero Dashboard, to completely new projects such as Xero HQ, and the introduction of a common pattern library, we are moving toward a more cohesive experience for not only our developers, but also our users. As a team, we have great confidence in our current stack of tools and how it has made developing complex user-interfaces easier and quicker. As the state of frontend evolves, we aim to evolve with it. The saga continues.

The three ‘R’s, Refactoring, React and Redux for robust async JS