Last modified: Feb 26, 2024

React + Redux architecture

High-level description of React + Redux architecture used in app frontend

The app frontend uses the React and Redux frameworks for presenting a UI to the end user, together with redux-saga to handle side effects. Components are based on Material UI components.

The diagram below show the architecture:

React architecture
React architecture

Store

A store holds the whole state tree of your application. The only way to change the state inside it is to dispatch an action on it.

Read more.

Reducers

Reducers specify how the application’s state changes in response to actions sent to the store. Remember that actions only describe what happened, but don’t describe how the application’s state changes.

Read more.

Middleware

redux-saga is a library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage, more efficient to execute, easy to test, and better at handling failures.

Read more.

Best practices

We try to follow some best-practices for React architecture:

  • Small, function-specific components

    • UI components are “dumb”, this keeps the amount of logic to a minimum within the components.
  • Reusability

    • UI components are shared across apps.
    • Shared components between app frontend and receipt frontend .
    • Use Material UI components as much as possible instead of building our own components from scratch.
  • DRY code

    • Use shared resources across features to avoid duplication of code.
    • Share resources/utils between app frontend and receipt frontend.
  • Comments only where necessary

    • Function and component names should be self-explanatory.
    • Avoid clutter and having to update comments when things change.
  • Component names in capital

  • Keep complex data-loading logic separate from rendering of components

    • State is handled by redux as much as possible
    • Data should be passed as props to UI components where possible
  • Use a feature-based code structure

    • Code related to a feature should be grouped together, rather than grouping code by function (actions/reducers etc).
  • Follow linting rules

    • Use a code analyzer to make sure linting rules are followed, for clean readable code