I. State and Props
State is a state machine.
It should include data that can be changed by the component’s event handler to trigger user interface updates, such as the need to respond to user input, server requests, or time changes.
Should not include: The React component (using props and state to create it in render()), the duplicate data based on props (keeping props as the only data source if possible, An effective scenario for saving props in state is to know when it was worth it before, because future props may change.
Props: How a parent passes data to its children.
Stateful components and Stateless Components (purely functional components)
Stateful component
Inherit components created by react.createclass or es6 classes from react.createclass. Features: Full life cycle and instantiation process, support for this and ref pointing.
Stateless components:
Statelesscomponent (Pure Function Component). A component that is created as a function return value. Features: No instantiation process or lifecycle, no reference to this or ref, and the function accepts props and context.
Practice patterns
A stateful component was created on top of a stateless component that was designed to render data, and its state was passed to its children via props. Stateful components encapsulate all user interaction logic, state handles state changes, and stateless components are only responsible for declaratively rendering data.
Controlled components, uncontrolled components and hybrid components
There are many Web components that can be changed by user interaction, such as <input>, <select>. These components can change the value of the component by entering something or setting the value attribute of the element. However, because React is bound to one-way data flows, these components can get out of control:
1. A <Input> component that maintains a value in its own state cannot be modified externally
2. An <Input> component that uses props to set value can only be updated by external controls.
Controlled components:
A controlled should have a value attribute. Rendering a controlled component displays the value of the value property. A controlled component does not maintain its own internal state; the rendering of the component simply depends on props. That is, if we have a component that sets value through props, no matter how you type it, it will just show props. Value. In other words, your component is read-only.
When working with a controlled component, always pass in a value property and register an onChange callback to make the component mutable.
Uncontrolled component
A <input> without a value attribute is an uncontrolled component. Any user input is immediately reflected through rendered elements. Uncontrolled <input> can only notify the upper layer of user-entered changes through the OnChange function.
mixins
Maintain both props. Value and state.value values. Value has higher priority on presentation, and state.value represents the actual value of the component.
Objective:
1. Support incoming values; 2. Controllable: External modification of the component props can change the real value and displayed value of the INPUT component; 3. Non-controllable: Input value in the input box can change the real value and display value of the input component at the same time.
Redux and DVA
Redux
1.Actions, Reducers and Stores
Action can be understood as data information (usually user interaction information) that an application passes to the Store. In practice, the information passed can agree on a fixed data format, such as Flux Standard Action. Dispatch (Action) is a synchronous process: Reducer update state -> call the store listening handler. If you need to fetch action data at dispatch, you can solve this by introducing Middleware.
Reducer is essentially a function (previousState, action) => newState. Used to perform logic that updates state based on the specified action. The Reducer does not store state. The reducer function logic should not directly change the state object, but return a new state object.
Store is a single object, and there is only one store instance in Redux. Main functions:
1. Manage the application state
2. Run store.getState() to obtain the state
3. Trigger the state update through store.dispatch(Action)
4. Register the state change listener with store.subscribe(listener)
b. Dva
The data flow
dispatch
Reducers
State
Effects
Reducers
State
Models
State
type State= any
State represents the Model’s State data, which is typically represented as a javascript object (it can be any value, of course); Treat the operation as immutabledata each time, ensuring that it is a new object each time, without reference relationships, so that the State is independent and easy to test and track changes.
In DVA you can see the state data at the top of the dVA instance property _store, but you rarely use it:
constapp=dva();
console.log(app._store); // State data at the top
Action
typeAsyncAction = any
Action is a plain javascript object that is the only way to change State. Whether the data is retrieved from a UI event, a network callback, or a data source such as WebSocket, an action is eventually called through the Dispatch function to change the corresponding data. Actions must have a type attribute to specify the specific behavior. Other fields can be customized. To initiate an action, use the Dispatch function. Note that dispatch is passed in via props after the component Connect Models.
dispatch({Copy the code
type: 'add',Copy the code
});Copy the code
The dispatch function
typedispatch = (a: Action) => Action
Dispatching Function is a function used to trigger action, which is the only way to change the State, but it only describes one behavior, and Dipatch can be regarded as the way of triggering this behavior. The Reducer describes how to change the data.
In DVA, the components of connect Model can access dispatch through props, and Reducer or Effects in the Model can be called. The common forms are as follows:
dispatch({
Type :'user/add', // If called outside model, need to add namespace
Payload: {}, // Information that needs to be transmitted
});
Reducer
typeReducer<S, A> = (state: S, action: A) => S
The Reducer (also known as Reducing Function) function takes two parameters: the result of a previously accumulated operation and the current value to be accumulated, and returns a new cumulative result. This function merges a set into a single value.
The Reducer concept comes from functional programming, and there are reduce apis in many languages. As in javascript:
[{x:1},{y:2},{z:3}].reduce(function(prev, next){
returnObject.assign(prev, next);
})
//return {x:1, y:2, z:3}
In DVA, the result of the reducers aggregation is the state object of the current model. The new value (i.e., the new state) is computed with the value in the current reducers from the values passed in the Actions. It should be noted that Reducer must be a pure function, so the same input must get the same output, and they should not have any side effects. Also, each calculation should use imMutableData, which simply means that each operation returns a new piece of data (independent, pure), so functions such as thermal overloading and time travel can be used.
Effect
An Effect is called a side Effect, and in our application, asynchronous operations are the most common. It comes from the concept of functional programming, and it’s called a side effect because it makes our function impure, the same input doesn’t necessarily get the same output.
In order to control the operation of side effects, DVA introduces Redux-Sagas as the asynchronous flow control at the bottom layer. As the related concept of generator is adopted, the asynchronous writing method is changed into synchronous writing method, and effects is turned into a pure function. For more on why we’re so obsessed with pure functions, read the Mostlyadequate Guide to FP, or its Chinese translation, THE JS Functional Programming Guide.
Subscription
Subscriptions is a method of obtaining data from sources, which came from ELM.
The Subscription semantics are subscriptions that are used to subscribe to a data source and then dispatch required actions based on conditions. The data sources can be the current time, the server’s Websocket connection, keyboard input, geolocation changes, history route changes, and so on.
importkeyfrom'keymaster';
.
app.model({
namespace:'count',
subscriptions: {
keyEvent(dispatch) {
The key (' ⌘ + up and CTRL + up, () = > {dispatch ({type: 'add'})});
},
}
});
Router
The routing here usually refers to the front-end routing. Since our application is now usually a single page application, the front-end code is needed to control the routing logic. HistoryAPI provided by the browser can monitor the changes of the browser URL to control the operations related to routing.
The DVA instance provides the router method to control routing, using the React-router.
import { Router, Route } from'dva/router';
app.router(({history}) =>
<Router history={history}>
<Route path="/" component={HomePage} />
</Router>
);
RouteComponents
In the component design approach, we mentioned Container Components, which in DVA we usually constrain to Route Components because in DVA we usually design Container Components in page dimensions.
Therefore, in DVA, normally connect Model Components are Route Components, organized in the /routes/ directory, and/Components/directory are pure Presentational Components.
5. Hoc
HOC(Higher- OrderComponent) is an advanced use of React, mainly for reuse of components. HOC is a way to take a component and return a higher-level component.
During React development, there were a number of situations where components needed to be “enhanced”, such as adding or modifying certain props, managing permissions, and other optimizations. If the functionality is for multiple components, and each component has the same set of code, it’s obviously not wise to use HOC.
The simplest implementation of HOC looks like this:
What can HOC do?
Code reuse, code modularization
Increases the censored props
Rendering hijacked
Increases the censored props
You can modify the props passed or add new props to achieve this effect.
For example, if you wanted to add props to the wrappedComponent, you could do this:
This way, you can use the message props in your component:
Rendering hijacked
The rendering hijack here is not that you can control the details of how it renders, but whether or not it renders. Because the details are controlled by the Render method inside the component, you have no control over the render details.
For example, a component can realistically load… , you can write:
In this case, if the parent does not pass in data, only loading… Does not display the specific contents of the component
Practice in the project
1. Rational use of stateful components and stateless components. In the scenario of using REdux or DVA, theoretically all components can be encapsulated as stateless components (except a few that require life cycle control or the hybrid components mentioned above). Encapsulated data, asynchronous effects and synchronous reducers in Model can be bound to corresponding components through connect.
Best practice: The components defined in the GetComponent of the Router are called routing components. Generally routing components are bound to the props of the component via Connect with the state defined in the Model and the methods defined in the component. Other methods are defined as non-routed components. Non-routed components try to avoid using CONNECT. Instead, routed components or other layers pass data through props for rendering.
Understand the functional responsibilities in Subscription, Effects, and Reducers.
3. Dependency defined in package.json needs to be studied in depth to avoid repeating the wheel.
4. Overall view and reasonable component planning.