put
// 用于触发 action
yield put({ type, payload });
put是一个非阻塞的方法,这里可以用到take来一次性监听dispatch过来的action的,effect 前后会额外触发 /@@start 和 /@@end 的 action,我们就可以通过监听/@@end,来监听effect的执行结束,代码如下
*fetchAllProducts({ payload }, { call, put }) {
const response = yield call(getAllProducts, payload);
if (response && response.code === SUCCESS) {
const products = response.data;
console.log("a",products);
yield put({
type: 'saveReportState',
payload: { products },
});
}
},
*fetchUserAddOverview({ payload }, { call, put, select,take }) {
yield put({ type: 'fetchAllProducts', payload: { clientType: 1 } });
yield take('fetchAllProducts/@@end')
const products = yield select(state => state.report.products)
console.log("b",products);
// 这里会先输出 a products b products
const response = yield call(queryNewUserOverview, payload);
if (response && response.code === SUCCESS) {
const userAddOverview = response.data;
yield put({
type: 'saveReportState',
payload: { userAddOverview },
});
}
},
call
// 用于调用异步逻辑,支持 promise 。
const result = yield call(fetch, '/todos');
select
// 用于从 state 里获取数据。
const todos = yield select(state => state.todos);
具体例子如下:
*fetchUserOverview({ payload }, { call, put, select }) {
// 这里通过 select 来获取整个 state
yield put({ type: 'fetchAllProducts', payload: { clientType: 1 } });
const products = yield select(state => state.report.products)
console.log(products);
const response = yield call(queryNewUserOverview, payload);
if (response && response.code === SUCCESS) {
console.log(response);
}
},
effects 本地错误处理
effects: {
*addRemote() {
try {
// Your Code Here
} catch(e) {
console.log(e.message);
}
},
}
effects 全局错误统一处理
Ant Design 中用了umi,dva。统一异常处理可以在umi中进行。官方文档 中说明如下
// 在 src 目录下新建 app.js,内容如下:
export const dva = {
config: {
onError(e) {
e.preventDefault();
console.error(e.message);
},
}
};
Subscription
subscriptions
用于订阅一个数据源,然后根据需需求 dispatch 相应的 action。格式为 ({ dispatch, history }) => unsubscribe
。
异步数据初始化
// 当用户进入 `/users` 页面时,触发 action `users/fetch` 加载用户数据。
subscriptions: {
setup({ dispatch, history }) {
history.listen(({ pathname }) => {
if (pathname === '/users') {
dispatch({
type: 'users/fetch',
});
}
});
},
}
如果 url 规则比较复杂, 可以使用插件path-to-regexp 简化这部分逻辑。 比如匹配 /users/:userId/search
时
import pathToRegexp from 'path-to-regexp';
// in subscription
const match = pathToRegexp('/users/:userId/search').exec(pathname);
if (match) {
const userId = match[1];
// dispatch action with userId
}