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, debounceaddCountAsync: [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);});
}