本教程案例github:https://github.com/axel10/dva_demo-Counter-and-list/tree/master 這次主要通過線上獲取用戶數據並且渲染成列表這個案例來演示dva.js。 整個開發流程概括下來應該是: 編寫用戶列表model(數據模型)-> 編寫修 ...
本教程案例github:https://github.com/axel10/dva_demo-Counter-and-list/tree/master
這次主要通過線上獲取用戶數據並且渲染成列表這個案例來演示dva.js。
整個開發流程概括下來應該是:
編寫用戶列表model(數據模型)-> 編寫修改model的方法 -> 編寫服務介面 -> 編寫組件 -> 將組件與dva.js連接 -> 將dva.js提供的介面(dispatch)和數據模型通過props傳入組件 -> 渲染。
我們先從第一步開始。
編寫用戶列表model及修改方法:(src/models/users.js)
import * as userService from '../services/userService' export default { namespace: "users", state: { list:[] }, reducers: { //用來修改數據模型的state。 save(state, {payload:{data}}) { //涉及到es6的拆包寫法。 state.list = data; return {...state} }, removeItem(state, {item}) { state.list = state.list.filter(function (lItem) { return item.id !== lItem.id }); return{...state} } }, effects: { //effects指的是涉及到非同步請求的方法。通常用來調用服務獲取數據。這裡要註意如果effects的方法名與reducers中存在重覆的話容易造成死迴圈。 * 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: { //觸發器。setup表示初始化即調用。其他用法見官方文檔。https://github.com/sorrycc/blog/issues/62 setup({dispatch}) { dispatch({type: 'fetch'}) } } }
編寫完畢後不要忘了在src/index.js中註冊數據模型:
app.model(require('./models/users').default);
編寫服務介面:(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 }
這裡涉及到mock數據。方法為修改根目錄下的.webpackrc文件:
{ "proxy": { "/api": { "target": "http://jsonplaceholder.typicode.com/", "changeOrigin": true, "pathRewrite": { "^/api": "" } } } }
接下來編寫組件:
先從路由組件開始:
import {connect} from 'dva' import ListBody from "../components/ListBody" import React from "react"; class List extends React.Component { render() { return ( <ListBody {...this.props} /> //將自身的props傳給子組件。連接之後的組件可以擁有dispatch、索引後的數據模型。 ) } } function mapStateToProps(state) { //將數據模型索引到props。 return {users:state.users} } export default connect(mapStateToProps)(List) //將組件與數據模型相連接。
這裡要重點說明:dispatch就是在connect的時候傳入的,用來做組件與數據模型之間的交互。
之後是ListBody組件:
import React from 'react'; import {Link} from 'dva/router' class ListBody extends React.Component{ removeUserItem(item){ this.props.dispatch({type:"users/fetchRemoveItem",item}) //通過props獲取dispatch方法,users表示數據模型(namespace),fetchRemoveItem表示reducers或者effects。 } render(){ const that = this; let userList = []; let userData = this.props.users.list; //users:數據模型,list:數據模型中的state
if (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>請嘗試點擊條目。</h2> {userList} </div> ) } } export default ListBody;
完畢後添加路由。
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;