What's the problem redux to solve?
As JavaScript single-page application development becomes more complex,JavaScript needs to manage more state thanever. These states may include server responses, cached data, local build data that has not been persisted to the server, and UI state, such as the active route, the selected label, whether the load dynamic or pager is displayed, and so on.
Managing the changing state is very difficult. If the change of one model causes another model to change, then when the view changes, it may cause the corresponding model and another model to change, in turn, may cause another view to change. Until you can't figure out what's going on. when state is, for whatever reason, how changes are already uncontrolled. when the system becomes complex, it becomes difficult to reproduce the problem or add new features.
Redux's design draws on flux, ELM, and immutable, and it is designed to solve data problems in the state. The main difference between redux and flux is that redux is a single data source design, and flux (or reflux) has multiple data sources.
How does the redux work?
We know that in react, data flows in a single direction in a component. Data flows from One Direction parent component to a subassembly (via props), because of this feature, communication between two non-parent-child components (or sibling components) is not so clear.
React does not recommend the direct adoption of component-to-component communication, although it has some features that enable it (for example, to pass the value of a subcomponent to the parent component before being distributed by the parent component to the specified subassembly). This is considered by many to be a bad practice because it is prone to error and makes the code as difficult to understand as ramen.
Of course react does not directly suggest how to deal with this situation, the following is a description of this section in React's documentation:
For a component that is not a parent-child relationship, you can build a global event system yourself, and the flux pattern is a viable way.
The advent of redux made it easier to solve the problem. Redux provides a solution that stores the entire application state to one place (which can be understood as a unified state layer), called the "store", and the component forwards notifications (dispatch) of state changes to the store, rather than notifying other components directly. Changes to the state that are dependent on the component can be achieved by subscribing to the store.
With redux, all components get the state they depend on from the store, and they need to tell the store about the state change. Components do not need to focus on the changes in the state of other components in this store, redux makes data flow easier. This idea was originally derived from flux, which is a design pattern for the same unidirectional data flow as react.
Redux's core design concept
Redux has three main principles
- Single data source, the entire application state is stored in an object tree, and the object tree exists only in the only store
- State is read-only and the only way to change state is to trigger action,action is a normal object that describes an event that has occurred.
- Use a pure function to perform the modification, in order to describe how the action changes the state tree, you need to write reducers.
The design of a single data source makes communication between react components easier and facilitates unified management of the state.
According to Redux's documentation, the only way to change the state is to trigger an action (an object that can describe what happened), which means that we cannot directly modify the state, instead we can forward the action to tell the store that we have the intention to change the state. The store object provides very few APIs, only 4 methods:
store.dispatch(action)store.subscribe(listener)store.getState()replaceReducer(nextReducer)
With these APIs it is easy to see that the store does not directly provide the SetState () method.
In addition, because of its large use of concepts such as pure function and plain object (reducer and action creator are pure function,state and action is plain object) this Qualitative will be a very good guarantee.
Understand action, Reducer
An example of an action:
var action = { type: ‘ADD_USER‘, user: {name: ‘Dan‘}};// 假设store对象已经通过Redux.createStore()创建store.dispatch(action);
In this code, the action is passed to the store through the dispatch () method. Action is essentially a JavaScript generic object. We agreed that an action must use a Type field of type string to represent the action that will be performed. In most cases, the type is defined as a string constant. When your application is growing in size, it is recommended that you use a separate module or file to hold the action.
import { ADD_TODO, REMOVE_TODO } from ‘../actionTypes‘
As described earlier, Redux does not allow direct changes to the state, it must be forwarded by the action to tell the store that this is the intention to change the status. Reducer is the role that plays the intent of handling the forwarded action and can change the state of the function. A reducer accepts the current state as a parameter by returning the new state to change the original state:
var someReducer = function(state, action) { ... return state;}
Since reducer is a pure function, it is important to note:
- Do not allow network calls or database query operations inside the REDUCER function
- It can't change its parameters.
The advantage of this is that each time the same function is called, the same value can be passed to the same result. Other parts of the system do not have side effects.
First Redux Store
Use Redux.createstore () to create a store, and pass all the reducers as parameters to it, with a reducer as an example:
var userReducer = function(state=[], action) { if (action.type === ‘ADD_USER‘) { var newState = state.concat([action.user]); return newState; } return state;}// 创建一个store,并且将reducer作为参数传递给它var store = Redux.createStore(userReducer);// 将action传递给store,告诉store我们有改变状态的意向store.dispatch({ type: ‘ADD_USER‘, user: {name: ‘cpselvis‘}});
What happens after the above code is run:
- Store is created
- Reducer determines that the value of the initial state is an empty array
- Action is forwarded to store
- Reducer adds newuser to the state and returns it to the update store
With this code you can see that the reducer function was actually executed 2 times, once when the store was created, once the action was forwarded. Also note: Redux expects that the REDUCER function will always return a new state. At this point the result:
store.getState(); // => [{name: ‘cpselvis‘}]
With this example, you can summarize the workflow of Redux
Here, the problem with the one-way data flow for state, component-I, reducer, is finished. In a nutshell: After the react component gets the data (such as an AJAX request), then creates an action notification store I have this intention to change state, and then reducers (an action may correspond to multiple reducer, It can be understood that the action is the subject of the subscription, there may be multiple subscribers) to handle this intent and return the new state, and the store will then collect all the reducer state and finally update the state.
Understanding JavaScript's status Container redux