在 Ant Design Pro 中,一个完整的前端 UI 交互到服务端处理流程是这样的:
- UI 组件交互操作;
- 调用 model 的 effect;
- 调用统一管理的 service 请求函数;
- 使用封装的 request.js 发送请求;
- 获取服务端返回;
- 然后调用 reducer 改变 state;
- 更新 model。
从上面的流程可以看出,为了方便管理维护,统一的请求处理都放在 services 文件夹中,并且一般按照 model 维度进行拆分文件
其中,utils/request.js
是基于 fetch 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。具体可以参看 request.js。
例如在 一个请求用户信息的例子中:
// services/user.js
import request from '../utils/request';
export async function query() {
return request('/api/users');
}
export async function queryCurrent() {
return request('/api/currentUser');
}
// models/user.js
import { queryCurrent } from '../services/user';
...
effects: {
*fetch(_, { call, put }) {
const response = yield call(queryUsers);
yield put({
type: 'save',
payload: response,
});
},
*insertUser({ payload, callback }, { call }) {
const response = yield call(insertUser, payload);
if (callback && typeof callback === 'function') {
callback(response); // 返回结果
}
},
}
reducers: {
save(state, action) {
return {
...state,
list: action.payload,
};
},
}
// views.js
const { dispatch} = this.props;
dispatch({
type: 'user/fetch'
});
dispatch({
type: 'user/insertUser',
payload: target,
callback: res => {
if (res) {
data[0].id = res.id;
onChange(data); // 请求完成后返回的结果
}
},
});
可以看到,我们在services中统一定义了请求request的函数,然后在model中导入service中的函数,通过fetch进行具体的封装,然后根据具体场景进行处理
通过payload传入参数,通过callback指定回调函数,通过call调用service中的异步函数,通过put将response传入reducers进行数据处理保存等操作。