github: https://github.com/axel10/dva_demo-Counter-and-list/tree/master
This time, we use the case of getting user data online and rendering it into a list to demonstrate dva.js.
The whole development process should be summarized as follows:
Write user list model - > write method to modify model - > write service interface - > write component - > connect component with dva.js - > transfer interface and data model provided by dva.js into component through props - > render.
Let's start with the first step.
Write user list model and modification method: (src/models)
import * as userService from '../services/userService' export default { namespace: "users", state: { list:[] }, reducers: { //Used to modify the data model state. save(state, {payload:{data}}) { //Relate to es6 The method of unpacking. state.list = data; return {...state} }, removeItem(state, {item}) { state.list = state.list.filter(function (lItem) { return item.id !== lItem.id }); return{...state} } }, effects: { //effects Refers to methods that involve asynchronous requests. Usually used to call a service to get data. Notice here if effects Method name and reducers If there is repetition in, it is easy to cause a dead cycle. * fetch(payload,{put, call}) { const data = yield call(userService.fatchData); yield put({type: "save", payload: data}) }, * fetchRemoveItem({item},{put,call}){ const result = yield call(userService.fetchRemoveItem,item.id); if (result){ console.log(true); yield put({type:"removeItem",item}) }else{ console.log(false); } } }, subscriptions: { //Trigger. setup Indicates that initialization is called. See official documents for other usage. https://github.com/sorrycc/blog/issues/62 setup({dispatch}) { dispatch({type: 'fetch'}) } } }
Don't forget to register the data model in src/index.js after writing:
app.model(require('./models/users').default);
Write service interface: (src/services/userService.js)
import request from "../utils/request"; export function fatchData() { return request("/api/users") } export function fetchRemoveItem(query) { console.log(query); return true }
This involves mock data. The method is to modify the. Webbackrc file in the root directory:
{ "proxy": { "/api": { "target": "http://jsonplaceholder.typicode.com/", "changeOrigin": true, "pathRewrite": { "^/api": "" } } } }
Next, write the components:
Start with the routing component:
import {connect} from 'dva' import ListBody from "../components/ListBody" import React from "react"; class List extends React.Component { render() { return ( <ListBody {...this.props} /> //Pass its props to the subcomponent. The connected components can have the data model after dispatch and index. ) } } function mapStateToProps(state) { //Index data model to props. return {users:state.users} } export default connect(mapStateToProps)(List) //Connect components to the data model.
Here is the key point: dispatch is passed in when connect ing, which is used for interaction between components and data model.
Then the ListBody component:
import React from 'react'; import {Link} from 'dva/router' class ListBody extends React.Component{ removeUserItem(item){ this.props.dispatch({type:"users/fetchRemoveItem",item}) //Use props to get the dispatch method, users for the data model (namespace), fetchRemoveItem for the reducers or effects. } render(){ const that = this; let userList = []; let userData = this.props.users.list; //users: Data model, list: In the data model stateif (userData.length>=1){ userData.forEach(function (item, index) { userList.push(<li key={index} onClick={that.removeUserItem.bind(that,item)}>{item.name}</li>) }) }return( <div> <h2>Please try clicking on the entry.</h2> {userList} </div> ) } } export default ListBody;
Add route when finished.
import React from 'react'; import { Router, Route, Switch,Redirect } from 'dva/router'; import list from './routes/list' function RouterConfig({ history }) { return ( <Router history={history}> <Switch> <Route path="/list" exact component={list} /> <Redirect to="/list"/> </Switch> </Router> ); } export default RouterConfig;