First, Reducer
Reducer is a function that accepts State and action, returning the old or new state. That(state, action) => state
Delete and change
Take Todos as an example.
App.Model ({Namespace:' Todos', state: [], reducers: {AddState, {payload: Todo}) {ReturnState.Concat (TODO); },RemoveState, {payload: ID}) {return state. Filter (todo => todo. ID !== ID); }, update (state, {payload: Updatedtodo}) {return state. Map (todo => {if (todo.id === updatedtodo. ID) {return {...todo, ...updatedtodo};} else {return todo;}); }, },};
Additions and deletions of nested data
It is recommended to nest at most one level to keep the state flat, deep nesting makes reducer difficult to write and difficult to maintain.
App.model ({ namespace' app', State: {todos: [], Loadingfalse,}, reducersAdd ( State, {payload state. Todos. ... state, todos}; }, },});
Below are examples of deep nesting, which should be avoided as much as possible.
App.Model ({Namespace:' App', state: {A: {b: {Todos: [], loadingfalse,},},}, Reducers: {add (state, {payload: Todo}) {const todos = state. A.b.todos. Concat (TODO); const b = { ... state. a.b, Todos}; const a = { ... state. a, B}; return {...state, A};},},});
Second, Effect
Example:
App.model ({ namespace' Todos', effects*addremote ({payloadput ({type' Add'), Payload: Todo}); }, },});
Effectsput
Used to trigger an action.
Put ({type' Todos/add', payload' learn Dva'});
Pager
Used to invoke asynchronous logic and support promise.
'/todos');
Select
Used to fetch data from the state.
Select (State. Todos);
Error handling global error handling
In DVA, the subscriptions of the effects and the errors will all be onError
hooks, so the error can be handled in a onError
unified way.
DVA ({ onError (console) . Log (E.message);});
Then the reject and promise of the effects will be captured.
Local error handling
If you need special treatment for some effects errors, you need to add them inside the effect try catch
.
App.model ({ effects: { *addremote () {*) { console. Log (E.message);},},});
Asynchronous request
Asynchronous requests are based on WHATWG-FETCH,API see: Https://github.com/github/fetch
GET and POST
‘.. /util/request'; GETRequest ('/api/todos'); Postrequest ('/api/todos', {method' post', BodyJSON. Stringify ({a1}),});
Unified error Handling
If the Convention returns the following format in the background, do a unified error handling.
{ status' Error', message',}
Edit utils/request.js
, add the following middleware:
Parseerrormessage ({data}) { ' ERRORreturn {data};}
Then, this kind of error will go into the onError
hook.
Third, Subscription
subscriptions
is a subscription that subscribes to a data source and then dispatch the corresponding action as needed. The data source can be the current time, the server's WebSocket connection, the keyboard input, the geolocation change, the history route change, and so on. Format is ({ dispatch, history }) => unsubscribe
.
Asynchronous data initialization
For example: When the user enters /users
the page, the action is triggered to users/fetch
load the user data.
App.Model { Subscriptions: { setup ({dispatch, history}) {history .' /usersDispatch ({type' Users/fetch',});}); }, },});
path-to-regexp
Package
If URL rules are complex, for example /users/:userId/search
, matching and userId fetching can be cumbersome. This is recommended to simplify this part of the logic with Path-to-regexp.
' Path-to-regexp'; In subscriptionpathtoregexp ('/users/:userid/search'). EXEC (pathname); = match[//Dispatch action with UserId}
Iv. routerconfig with JSX Element (router.js)
<route path="/" component={app}<route Path="Accounts" component={ Accounts}/<route path="statements" component={statements}/> </route>
See: React-router
Route components
The Route components refer ./src/routes/
to the files in the directory, they are the ./src/router.js
matching Component.
Bind data via Connect
Like what:
' Dva'; App () {}Mapstatetoprops (return {users state. Users,};} Connect (mapstatetoprops) (APP);
Then there are two attributes in the dispatch
App users
.
Injected Props (e.g. location)
Route Component will have additional props to get the routing information.
See more: React-router
Page jump based on action
Import {Routerredux}From' Dva/router//Inside effectsyield put (routerredux. push ( '/logout //Outside effectsdispatch (routerredux. Push ( '/logout //with Queryrouterredux. Push ({pathname '/logout ", query 2,},});
Besides push(location)
, there are more ways to see React-router-redux
Five, DVA configuration redux middleware
For example, to add Redux-logger middleware:
' Redux-logger'; DVA ({onActionCreatelogger (),});
Note: OnAction supports arrays and can pass in multiple middleware at the same time.
History switch History to Browserhistory
' Dva/router'; DVA ({history: Browserhistory,});
Removal of _k query parameters under Hashhistory
' Dva/router ';' History'; DVA ({userouterhistory (createhashhistory) ({Querykeyfalse}),});
VI. tools to create projects through DVA-CLI
Install DVA-CLI first.
$ NPM Install Dva-cli-g
Then create the project.
$ DVA new MyApp
Finally, enter the directory and start.
CD myapp$ NPM start
003-and design-dva.js Knowledge Map -01-reducer,effect,subscription,router,dva configuration, tools