项目主体结构基于第20号笔记
基本与第20号笔记相同,不再累述
定义模拟数据文件
mock\productMockData.js
import Mock from "mockjs"
export default {
// 要以斜杠号开头
"GET /api/productStaticData" : {
status : true,
msg: "",
data : [
{ name : "name1"} ,
{ name : "name2"} ,
{ name : "name3"} ,
{ name : "name4"} ,
{ name : "name5"} ,
]},
//这种写法,本质上还是静态数据,只是静态数据是由mock动态生成的
//即是说,mock执行一次后则不在执行
//具体的mock函数用法,参考mockjs相关文档
"GET /api/productMockData2" : Mock.mock({
'status': true,
'msg': "",
'data|10-25' : [{
name : "@cname"
}]
}),
//这种写法,每次都执行了回调函数,因此每一次请求,都会生成不同的数据
"GET /api/productMockData" : (req, res) => {
res.status(200).json(Mock.mock({
'status': true,
'msg': "",
'data|10-25' : [{
name : "@cname"
}]
}))
}
}
注册模拟数据文件到模拟数据容器中
.roadhogrc.mock.js
import * as productData from "./mock/productMockData"
export default {
...productData
};
src\models\productModel.js
import request from "../utils/request"
import * as serviceApi from "../services/productService"
export default {
namespace: "porductModel",
state: {
dataSource: [
{ name: "defalut" }
]
},
reducers: {
//向state的dataSouce列表中添加一个元素
addProduct(state, action) {
let newState = {...state} //注意深拷贝
newState.dataSource.push(action.payload)
return newState
},
//整个更新state
reBuildProductList(state, action) {
return { dataSource: action.payload }
}
},
effects:
{
//异步形式接收传来的action
*addProductAsync({ payload }, { call, put }) {
//数据更新过程通过put函数,推迟到reducers的addProduct方法执行
yield put({type:"addProduct", payload});
},
//加载静态模拟数据
*loadStaticProductList({ payload }, { call, put }) {
//直接调用utils包中的工具函数request,获得响应的response对象
//再从response中获得返回数据体
//注意异步函数调用方法,利用call函数实现类似反射调用request
const response = yield call(request, "/api/productStaticData")
if (response.data) {
const datalist = response.data.data
//state的修改,推迟到reducers中进行
yield put({ type: "reBuildProductList", payload: datalist })
}
//异常处理
else{
console.error(response.err)
}
},
//加载mock生成的动态数据
*loadMockProductList({ payload }, { call, put }) {
//假如异步请求过程中还存在其他业务逻辑,则可以将逻辑推迟到serviceAPI中进行
const response = yield call(serviceApi.loadmockdata)
if (response.data) {
const datalist = response.data.data
//state的修改,推迟到reducers中进行
yield put({ type: "reBuildProductList", payload: datalist })
}
//异常处理
else{
console.error(response.err)
}
}
}
}
src\services\productService.js
import request from '../utils/request';
export function loadmockdata() {
//此处可以进行其他业务逻辑处理
return request('/api/productMockData');
}
src\routes\ProductPage\ProductPage.jsx
import React from 'react'
import ProductContext from '../../components/ProductContext/ProductContext'
import ProductTool from '../../components/ProductTool/ProductTool'
export default function ProductPage() {
return (
)
}
src\components\ProductTool\ProductTool.jsx
import { Button } from 'antd'
import { connect } from 'dva'
import React, { Fragment } from 'react'
import * as actions from "../../action/ProductModelAction"
function ProductTool(props) {
//发送添加事件
const onBtnAppendProductItemClick = () => {
props.dispatch(actions.addProductAsync({name : Date.now().toString()}))
}
//发送加载静态列表事件
const onBtnLoadStaticListClick = () => {
props.dispatch(actions.loadStaticProductList())
}
//发送添加动态模拟列表事件
const onBtnLoadMockListClick = () => {
props.dispatch(actions.loadMockProductList())
}
return (
)
}
export default connect()(ProductTool)
src\components\ProductContext\ProductContext.jsx
import { connect } from 'dva'
import React from 'react'
function ProductContext({data}) {
return (
{data.dataSource.map((value,index)=>{
return - {`name : ${value.name}`}
})}
)
}
//从redux空间中,提取出productModel的数据,并名为data,传入当前组件的props属性中
const maps = (reduxState) => {
return { data : reduxState.porductModel}
}
export default connect(maps)(ProductContext)
模拟数据文件基本格式要求如下:
export default {
//返回静态数据
"[method] /url" : { 返回数据 },
//返回特定的response对象,
"[method] /url" : (req,res)=> {
res.status(200).json(返回数据)
}
}
其中:
模拟数据的特点
异步action执行流程
effect中reducer函数的说明
effects:
{
*loadStaticProductList({ payload }, { call, put }) {
//直接调用工具函数request,获得响应的response对象
//再从response中获得返回数据体
//注意异步函数调用方法
const response = yield call(request, "/api/productStaticData")
if (response.data) {
const datalist = response.data.data
//state的修改,推迟到reducers中进行
yield put({ type: "reBuildProductList", payload: datalist })
}
//异常处理
else{
}
}
}
语法糖带来的效果