Subscriptions
是一种从 源 获取数据的方法,它来自于 elm。 语义是订阅,用于订阅一个数据源,然后根据条件 dispatch
需要的 action
。数据源可以是当前的时间、服务器的 websocket
连接、keyboard 输入、geolocation
变化、history
路由变化等等。
简单点说,就是在里面写的方法,在页面一加载的时候就会执行。
- 方法是普通函数,不能是getor函数
- 实参有
dispatch/history
两个属性 - history:包含路由跳转监听的history对象
- dispatch: 派发reducer里面的同步方法
实现效果
代码分析
import key from "keymaster";
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
export default {
namespace: "products",
state: {
count: 0,
lists: [
{
name: "dva", id: 1 },
{
name: "antd", id: 2 },
],
},
// 同步更新的方法
reducers: {
delete(state, {
id }) {
return {
...state,
lists: state.lists.filter((item) => item.id !== id),
};
},
addCount(state) {
return {
...state, count: state.count + 1 };
},
minusCount(state) {
return {
...state, count: state.count - 1 };
},
},
effects: {
// *addCountAsync(action, effects) {
// const { put, select, call } = effects;
// const data = yield select();
// console.log("我被点击了");
// yield call(delay, 2000);
// yield put({ type: "addCount" });
// },
// 设置不同类型的监听器,监听器类型有takeLatest, takeEvery, throttle, debounce
addCountAsync: [
function* (action, effects) {
const {
put, call } = effects;
yield call(delay, 2000);
yield put({
type: "addCount" });
},
{
type: "takeLatest",
},
],
*minusCountAsync(action, effects) {
const {
put, call } = effects;
yield call(delay, 2000);
yield put({
type: "minusCount" });
},
},
subscriptions: {
async init(params) {
const {
dispatch } = params;
console.log("初始化被执行了", params);
await delay(2000);
dispatch({
type: "addCount" });
},
setup(params) {
console.log("订阅被执行了", params);
},
keyEvent({
dispatch }) {
key("⌘+up, ctrl+up", () => {
dispatch({
type: "addCount" });
});
key("⌘+down, ctrl+down", () => {
dispatch({
type: "minusCount" });
});
},
},
};
页面初始化后,自动diapatch
了addCount
方法。数据+1。
另外我们也注册了键盘事件keyEvent
- 注意点
- init及setup都只会初始化执行一次,后续不会再执行
- 要做路由监听,需要使用history.listen,第一次会执行,之后每次路由切换的时候都会调用。
可以在这里做针对页面切换时的业务处理。对location
进行结构,获取pathname
,对具体的路由进行监测即可。
async init(params) {
const {
dispatch, history } = params;
console.log("初始化被执行了", params);
await delay(2000);
dispatch({
type: "addCount" });
// 返回一个函数,用于在组件卸载时取消监听
const unListen = history.listen((location) => {
if (location.pathname === "/product") {
dispatch({
type: "addCount" });
// 移除监听
unListen();
}
console.log("监听被执行了", location);
});
}