Right before the rise of GraphQL, there is a use case to develop a react client with sequential APIs to feed data on a single page app, with Redux as central state management. This article tries to explain merits of Redux.
Dealing with some of the haste in a progressive app, namely mutation and asynchronicity, React UI has already have a well defined life cycle method to define the steps in data logic and rendering view components. However, as stated in the Redux documentation, we are facing more challenges than ever, the three keys factors are that first, our code must manage more state than ever before, second, could lose control over the when, why, and how of its state, and ,third, new requirements becoming common in front-end product development.
Difference to backend development,
While running a sequentially asynchronous function, in which there are several factors affecting the speed of function output, like internet connection, data size, we have to take special care of the lifecycle of the framework, we need view components to notify the end user the rendering state and results. These singals are usually synchronous calls to update the frontend and in sandwich of other methods.
That’s why Redux attempts to make state mutations predictable
The mainstream approach people use for interacting with an information system is to treat it as a CRUD datastore.
However, when we are considering do this actions, we face the great constraints of this original data store structure. When we would like to 1. collapsing multiple records into one, 2. forming virtual records by combining information for different places, and 3. validation rules that only allow certain combinations of data to be stored.
Three Principles of Redux
Redux can be described in three fundamental principles, they are:
Single source of truth
The state of your whole application is stored in an object tree within a single store.
State is read-only
The only way to change the state is to emit an action, an object describing what happened.
Changes are made with pure functions
To specify how the state tree is transformed by actions, you write pure reducers.
Programming in the large with async action
When you call an aynchrous API, there are two crucial moments in time: ::the moment you start the call::, and ::the moment when you receive an answer ( or a timeout )::.
Each of these two moments usually require a change in the application state, so we have to dispatch normal actions that will be processed by reducers synchronously.
For each API request, we may dispatch at least three different of actions to the reducers:
- The request began.
- The request finished successfully.
- The request failed.
{ type: 'FETCH_POSTS_REQUEST' }
{ type: 'FETCH_POSTS_FAILURE', error: 'Oops' }
{ type: 'FETCH_POSTS_SUCCESS', response: { ... } }
Define synchronous action types and action creator
Develop basic elementery actions creator and pure reducers, as suggested by the thrid principle. These actions creators are builing blocks.
Design the state shape
There are challenges
- describe the state of an asynchronous application
- how to organise state in a single tree
we store each chartWidget’s info separately so we can cache every chart.
For every list of items, we will want to storeisFetching
to show a spinner,didInvalidate
so we can later toggle it when the data is stale
If we want to edited single received info?
duplicated in several places in the state tree, this would be painful to implement
-> keep them separately in the state as if a database
high order component dispatching reducer function at the same time
Challenge
Different combination leads to different data structure and workflow
New formats keep coming up, promise,
Leave a Reply