Skip to content

Client side

Tom Richards edited this page Jun 26, 2020 · 14 revisions

manage-frontend client-side is primarily a single page React app, but with 'client-side routing' and some minimal 'server-side-rendering'.

It makes lots of AJAX/Async API calls to various different services (the vast majority of which are proxied via the node backend with the exception of the Identity tabs which go direct to identity APIs).

State Management

In manage-frontend we have so far managed to avoid the need for complex state management frameworks like Redux. Instead, getting by with a combination of...

TypeScript

As with the entire codebase we use TypeScript.

You will observe a convention for defining the shape of props and state with interfaces of the same name as the component plus Props or State respectively (e.g. MyStatefulComponent will have interfaces defined somewhere near called MyStatefulComponentProps and MyStatefulComponentState).

Notable TypeScript features that you will see used a fair bit are...

  • 'optional chaining'
  • the beautiful 'is predicate functions' which mean we can write functions which not only allow us define our own conditions to confirm if the parameter adheres to a particular type/interface but also performs an implicit cast on the variable(s) in question on subsequent usages, for example given this function...
    function hasContactId(
      productDetail: ProductDetail
    ): productDetail is ProductDetailWithContactId {
      return !!productDetail.subscription.contactId;
    }
    • notice the different types on before and after when using the above function (given productDetail:ProductDetail)...
      const before: string | undefined = productDetail.subscription.contactId;
      if( hasContactId(productDetail) ){
        const after: string = productDetail.subscription.contactId; // because productDetail has been cast to ProductDetailWithContactId
      }
    • this works really nicely with in-built functions like filter...
      const before: ProductDetail[] = []; // imagine this was full of ProductDetail (some of which had .subscription.contactId defined)
      const after: ProductDetailWithContactId[] = before.filter( hasContactId ) // notice the array is now an array of ProductDetailWithContactId

Emotion 💅 (styled components / CSS)

manage-frontend takes a 'styled components' approach to CSS achieved with Emotion.

Standard HTML react components all accept a css attribute, and we use a blend of 'object style' and 'literal style', see...

object style literal style
Example <div css={textAlign: "right"}></div> <div css={css`text-align: right`}></div>
Benefits
  • Type checked CSS 😍
  • more familiar if in a JS mindset, which the engineer will be
  • leveraging spread and destructing works really nicely to combine styles - useful for re-use
  • Standard CSS, so more familiar to everyone and more accessible to designers etc.
  • Copy/paste from designs or existing CSS is easier (although IDE plugins can do translation to/from 'object style'

... we've not yet found a need to standardise on one approach (as they're both straight-forward) so it's personal preference currently.

There is one exception to this styling approach; in the 'Holiday Stops Flow' where we had to use raw-loader to use the css file from the date picker library.

Clone this wiki locally