React practice is essential to note (11) - Redux basis

  Redux is a predictable state of the container, not only combines functional programming ideas, but also strictly abide by the concept of one-way data flow. Flux Redux inherited the idea of ​​architecture, and streamlined On this basis, optimization and expansion, and strive to complete the main function with a minimum of API, which is the core code short and lean, compressed only a few KB. Redux agreed on a set of specifications and standardized state (ie, data) update step, so that changing the state of the rapid growth of the large front-end applications tracked, not only conducive to reproduce the problem, but also to facilitate new demands integration. Note, Redux is an independent library that can be used with other libraries React, Ember or jQuery.

  In Redux, the state can not be modified directly, but through Action, Reducer Store and three parts done in collaboration. Specific operational processes can be simply summarized as three steps, first by Action describing the operation to be performed, and then let the arithmetic logic Reducer design state, and finally through the Store and the associated Action Reducer and trigger status update, use the following code demonstrates this process .

function caculate(previousState = {digit: 0}, action) {        //Reducer
  let state = Object.assign({}, previousState);
  switch (action.type) {
    case "ADD":
      state.digit += 1;
      break;
    case "MINUS":
      state.digit -= 1;
  }
  return state;
}
let store = createStore(caculate);        //Store
let action = { type: "ADD" };             //Action
store.dispatch(action);                  //Trigger update 
store.getState ();                       // read status

  Known by the code above, Action is a plain JavaScript object, Reducer is a pure function, Store is an object () function obtained by createStore, if you want to update the status of the trigger, you need to call its dispatch () method. To have a preliminary perceptions of Redux, and then in the next section, this code will be deployed around specific analysis.

First, the three principles

  Only by adhering to three principles Redux designed to make state becomes predictable.

  (1) a single data source (Single source of truth).

  All front-end applications in the state will form a tree of JavaScript objects, are saved to a Store. This will not only to avoid data redundancy, but also easier to debug and facilitates the monitoring state at any time, thereby reducing the probability of errors. Not only that, the past is difficult to achieve the function (such as instant save, undo redo, etc.), now also it becomes easy to implement the. Anywhere in the application, it can be () method to read the current status of the Store getState.

  (2) holding a read-only state (State is read-only).

  To change the state of Redux, you have to distribute an Action object, and then create a new function by the Reducer state object back to the Redux, in order to ensure the read-only state, so that the state can manage the orderly conduct.

  Change (3) is performed by a pure state function (Changes are made with pure functions).

  Here means pure Reducer function, it has no side effects (i.e., predictable output), whose function is to receive and process change in status Action, by Reducer history function that state becomes traceable.

Second, the major component

  Redux is mainly composed of three parts: Action, Reducer and Store, this section will explain them in turn.

1)Action

  Action essentially defined by the developer is a regular JavaScript object, the object must Redux agreed string type comprising a type attribute, which is a constant value, used to describe the intended operation. Action customizable structure, as far as possible with the state change comprises information relating to the object under Action increasing numerical example, in addition to the required type attribute, additionally it comes incremental step represents a property.

{ type: "ADD", step: 1 }

  If the increasing scale of the project, consider adding a unique number that identifies for the Action or dispersed to different files.

  Action is typically created using a function (Action Creator) Action generated object (i.e., returns an Action) as a function of better controllability, portability and testability, the following is a simple function to create Action.

function add() {
  return { type: "ADD", step: 1 };
}

2)Reducer

  Reducer function to count only memory state, the developer may be customized according to the current service. This function can receive two parameters: previousState and Action, expressed on a former state (i.e., the current state of the application), the Action which is a subject to be dispatched, the return value of the function body is generated based on these two parameters a treated the new state.

  Redux during the first execution, since the initial state is undefined, it is possible to set the initial value previousState, e.g. ES6 use syntax such as the following default parameters.

function caculate(previousState = {digit: 0}, action) {
  let state = Object.assign({}, previousState);
  //省略更新逻辑
  return state;
}

  In preparing the Reducer function, there are three things to note:

  (1) to comply with specifications of a pure function, such as not to modify the parameters, the function is not performed and the like side effects.

  (2) create a state object () function in the first with Object.assign copy, and then to modify only the new object, note that the first parameter of the method to pass such a null object like the one above.

  (3) In the case where an abnormality occurs (e.g. Action not recognize incoming object), return to the original state.

  When the traffic becomes complicated, Reducer function logic state will also become unusually large. At this point, you can use the design idea of ​​divide and rule, which is split into a number of small independent sub-functions, which are only responsible for maintaining the Reducer function of the respective part of the state. If you need to merge them into a complete Reducer function, you can use combineReducers Redux provided () function. The function receives an object by the split function Reducer composition, and their results can be combined into a complete state of the object. The following is an example of usage, the first split before caculate () function to add () and minus () function is two, and then passed as a parameter combineReducers () function.

function add(previousState, action) {
  let state = Object.assign({}, previousState);
  state.digit = "digit" in state ? (state.digit + 1) : 0;
  return state;
}
function minus(previousState, action) {
  let state = Object.assign({}, previousState);
  state.number = "number" in state ? (state.number - 1) : 0;
  return state;
}
let reducers = combineReducers({add, minus});

  combineReducers () will be executed first time these two functions, that is to say reducers () function to calculate the initial state is no longer undefined, but below this object. Note, {add, minus} to use the new ES6 simple attribute syntax.

{ add: { digit: 0 }, minus: { number: 0 } }

3)Store

  Store Reducer for the Action and set up a bridge of communication, it is an object of Redux, played a role in the container, preserved state of the application, including four methods:

  (1) getState (): Get the current status.

  (2) dispatch (action): distributing an Action object, causing modified state.

  (3) subscribe (listener): registration status update listeners, the return value can cancel the listener.

  (4) replaceReducer (nextReducer): Updates Store in the Reducer function, when implementing Redux heat load may be used.

  In Redux applications, will contain only a Store, () function creates a createstore, its first parameter is the Reducer () function, the second parameter is optional in the initial state, as shown in the following code, for incoming the opening of caculate () function and an object containing properties digit.

let store = createStore(caculate, {digit: 1});

  caculate () function will increase or decrease the digit attribute state object, which is an increment or decrement. Store Next to register a listener (as shown in the following code), when the status update, it will print out up to date; and after the cancellation of the listener (ie calls unsubscribe () function), the console will not have any output.

= store.subscribe with unsubscribe the let (() =>      // Register listener 
  the console.log (store.getState ()) 
); 
store.dispatch ({type: "the ADD"});             // {digit for: 2} 
Store. dispatch ({type: "the ADD"});             // {digit for:. 3} 
with unsubscribe ();                          // logout listener 
store.dispatch ({type: "MINUS"});         // no output

Third, the binding React

  Although Redux and React can be used alone (ie not directly related), but the two will match up to play a greater role. React scale up the application once, then the maintenance of the state becomes even more difficult, but after the introduction of standardized Redux will be able to change the state to reverse this dilemma. Redux official library for the binding React: react-redux, it contains a connect () function and a Provider components can easily be fused Redux features to React assembly.

1) a container assembly and display assembly

  Due to react-redux library is based on container components and display components separate from the development and design ideas, so before the formal react-redux explain, we need to clarify the concept of these two types of components.

  The container assembly (Container Component), also known as intelligent component (Smart Component), is generated by the react-redux library, the processing is responsible for the application logic and the source data, the necessary transfer of props to display assembly, can be used with Redux, not only can listening Redux the change of state, but also to distribute Action Redux.

  Display assembly (Presentational Component), also called puppet assembly (Dumb Component), defined by the developer, responsible for rendering interface, receiving coming from the container assembly props, props can change the callback function synchronization source data.

  Container assembly and display assembly are divided according to functions, the two can be nested within each other, and they can include or omit the internal state, the container assembly is generally a state-based, and the display assembly is a stateless function.

2)connect()

  react-redux provide a curried function: connect (), which contains four selectable parameters (as shown in the following code) for connecting React Store Redux assembly (i.e., so that the associated display assembly Redux), generates a The container assembly.

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

  Function will be performed when a connect () twice, as shown in the following code, the first acquisition state is kept in the Store to be used, connect () function returns a function; the second is a Dumb spread function display assembly just returned, then the assembly into a decorative container assembly Smart.

const Smart = connect()(Dumb);

  Next, the first two will focus on explaining the function parameters: mapStateToProps and mapDispatchToProps, two other parameters (mergeProps and options) can be explained with reference to official documents.

3)mapStateToProps

  This is a function of two parameters (code shown below) comprising, whose role is extracted from the Store Redux out to calculate the required state and the display assembly props. If the connect () function this parameter is omitted, then the show will not be able to listen components of change Store.

mapStateToProps(state, [ownProps])

  The first parameter is a stored state Store state, the second optional parameter passed to ownProps props object container assembly. In general, mapStateToProps () function returns when an object, but the need to control rendering performance, a function may return. The following is a simple example, the opening or follow caculate () function, the Provider assembly will explain later.

let store = createStore(caculate);
function Btn(props) {           //展示组件
  return <button>{props.txt}</button>;
}
function mapStateToProps(state, ownProps) {
  console.log(state);            //{digit: 0}
  console.log(ownProps);         //{txt: "提交"}
  return state;
}
let Smart = connect(mapStateToProps)(Btn);        //生成容器组件
ReactDOM.render(
  <Provider store={store}>
    <Smart txt="提交" />
  </Provider>,
  document.getElementById("container")
);

  Btn is a stateless display assembly, in the initial state stored in Store is not undefined, the container assembly receives a Smart txt attribute () function printing out two parameters in mapStateToProps.

  Store in the state when changes or new component receives props, mapStateToProps () function is called automatically.

4)mapDispatchToProps

  It may be an object, it may be a function, as shown in the following code. Its role is to bind Action function to create and dispatch examples provided Store () method, the method then tied props mapped to the display assembly.

function add() {            //Action创建函数
  return {type: "ADD"};
}
var mapDispatchToProps = { add };                      //对象
var mapDispatchToProps = (dispatch, ownProps) => {        //函数
  return {add: bindActionCreators(add, dispatch)};
}

  When mapDispatchToProps is an object, the method comprising the Action created as a function of automatically passed to Redux built bindActionCreators () method, a new method of generating a merged into props, the method name attribute name followed before.

  When mapDispatchToProps is a function, it contains two parameters, a first parameter is the dispatch dispatch Store instance () method; mapStateToProps same meaning as the second parameter in ownProps, and also optional. Function return value is an object by the process consisting of (merged into props), the process will be distributed in an Action object, and using bindActionCreators () method can be simplified flow distribution, its source code shown below.

function bindActionCreator(actionCreator, dispatch) {
  return function () {
    return dispatch(actionCreator.apply(this, arguments));
  };
}

  The method can read the attribute display assembly props to pass over the call, for example, performed in the click event Btn assembly props.add (), triggered update state, as shown in FIG.

function Btn(props) {
  return <button onClick={props.add}>{props.txt}</button>;
}

  By the above analysis shows, the input mapStateToProps responsible display assembly, i.e. the required application state mapped to the props; display update operation mapDispatchToProps responsible output assembly, i.e. to the props need to perform the mapping.

5)Provider

  react-redux provides Provider component, it will be saved in your Store Context (in the first nine did explain) in. If you want the proper use of container components, then it was allowed to become the offspring Provider component, and the only way to received Store passed over. Provider component shown as common usage.

<Provider store={store}>
  <Smart />
</Provider>

  Provider components at the top position, it will store a received attribute, the attribute value is createstore () function returns the value, Smart a container assembly, the assembly is nested in the Provider.

 

Guess you like

Origin www.cnblogs.com/strick/p/10775503.html