Front-End Architecture¶
Introduction¶
Mataara uses the ReactJS framework to provide a front-end user interface, built on top of Django REST Framework APIs. The React frontend also uses Redux to store the state of the app in a single state tree.
What does Redux do, and how does it work?¶
Redux is a predictable state container for JavaScript apps. It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test.
Redux only has a single store that holds no logic by itself. Actions are dispatched and handled directly by the store, eliminating the need for a standalone dispatcher. In turn, the store passes the actions to state-changing functions called reducers. API or client-side middleware may also be included to add authentication, or to stop, modify or add more actions.
Redux Components¶
Redux features four major system components:
- Store:
- Controls the state.
- Actions:
- Describe the changes we want to make.
- Reducers:
- Services that state change based on the requested action.
- Middleware:
- Handles housekeeping tasks of the app.
N.B.: Reducers never change their state; they are immutable. An entire application state is kept in a single location, the store- This provides enormous benefits during debugging, serialization and development.
Redux Principles¶
Redux has three major principles to be aware of:
- State Principle:
- The state of an application is stored in an object tree within a single store, meaning everything that changes in an app is contained in a single object called state or state tree.
- Action Principle:
- A state tree cannot be modified or written to. To change a state, an action has to be dispatched. An action ensures that views nor the network callbacks will ever write directly to the state. Actions must be plain JS objects, that can be logged, serialized, stored and later replayed for debugging or testing purposes.
- Reducer Principle:
- Reducers exists to specify how the state tree is transformed by actions. Reducers are pure functions that takes the previous state and an action then return the next state. Using the default switch, it must return current state for undefined actions.
Further description can be found here: https://redux.js.org/introduction/three-principles
Basic Requirements¶
- NodeJS 5.0.0 or higher, plus npm
- React + Redux
- Babel 6
- Webpack
- ESLint
- Redux DevTools + Logger middleware (easily removable/replaceable if you need something else)
- Jest to run unit tests
Directory / File Structure¶
├── devServer.js
├── README.md
├── webpack-stats.json
├── src
│ ├── index.js
│ ├── actions
│ ├── store
│ ├── components
│ ├── constants
│ ├── containers
│ ├── api.js
│ └── reducers
├── setupJest.js
├── webpack.config.prod.js
├── index_frontend.html
├── package.json
└── webpack.config.dev.js
Actions Directory¶
Actions are payloads of information that send data from the application to the store. They are the only source of information for the store. We put all our action files in this directory.
Constants Directory¶
All types of action that are performed within the app are defined in the
ActionsTypes.js file. The date.js file contains a standard date
formatting string.
Reducers Directory¶
Actions describe events that have happened, but don’t specify how the
application’s state changes in response. This is the job of reducers. Because we
are using Redux, we combine reducers using the Redux tool combineReducers.
Containers Directory¶
Container components are a React pattern used to separate data fetching from rendering concerns. The idea is simple: A container does data fetching, and then renders that data using its corresponding sub-component.
Store Directory¶
The Store is the object that brings actions and reducers together. We only have a single store in our Redux application. The store has the following responsibilities:
- Holds the application state
- Allows access to that state via
getState()- Allows it to be updated via
dispatch(action)- Registers listeners via
subscribe(listener)- Handles unregistering of listeners via the function returned by
subscribe(listener)
api.js File¶
This file is responsible for building the query strings, fetching data from Django REST API and parsing the JSON responses. Every action uses API file functions to fetch data.
Components Directory¶
Components in ReactJS are like LEGO pieces. Every part of the application’s visuals should be wrapped inside a self-contained component module. Our components use Material UI, a set of React components that implement Google’s Material design.