fix: ResponsiveObserve unsubscribe (#25309) (#25319)

* fix: ResponsiveObserve unsubscribe (#25309)

* fix: ResponsiveObserve unsubscribe (#25309)

* fix: ResponsiveObserve unsubscribe

* test: add responsiveObserve.test.js
This commit is contained in:
zhangchen 2020-07-02 10:46:47 +08:00 committed by GitHub
parent e3982e94f8
commit 26fa36083e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 29 deletions

View File

@ -0,0 +1,14 @@
import ResponsiveObserve, { responsiveMap } from '../responsiveObserve';
describe('Test ResponsiveObserve', () => {
it('test ResponsiveObserve subscribe and unsubscribe', () => {
const { xs } = responsiveMap;
const subscribeFunc = jest.fn();
const token = ResponsiveObserve.subscribe(subscribeFunc);
expect(ResponsiveObserve.matchHandlers[xs].mql.matches).toBeTruthy();
expect(subscribeFunc).toBeCalledTimes(1);
ResponsiveObserve.unsubscribe(token);
expect(ResponsiveObserve.matchHandlers[xs].mql.removeListener).toBeCalled();
});
});

View File

@ -14,49 +14,40 @@ export const responsiveMap: BreakpointMap = {
};
type SubscribeFunc = (screens: ScreenMap) => void;
let subscribers: Array<{
token: string;
func: SubscribeFunc;
}> = [];
const subscribers = new Map<Number, SubscribeFunc>();
let subUid = -1;
let screens = {};
const responsiveObserve = {
matchHandlers: {},
matchHandlers: {} as {
[prop: string]: {
mql: MediaQueryList;
listener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null;
};
},
dispatch(pointMap: ScreenMap) {
screens = pointMap;
subscribers.forEach(item => {
item.func(screens);
});
return subscribers.length >= 1;
subscribers.forEach(func => func(screens));
return subscribers.size >= 1;
},
subscribe(func: SubscribeFunc) {
if (subscribers.length === 0) {
this.register();
}
const token = (++subUid).toString();
subscribers.push({
token,
func,
});
subscribe(func: SubscribeFunc): number {
if (!subscribers.size) this.register();
subUid += 1;
subscribers.set(subUid, func);
func(screens);
return token;
return subUid;
},
unsubscribe(token: string) {
subscribers = subscribers.filter(item => item.token !== token);
if (subscribers.length === 0) {
this.unregister();
}
unsubscribe(token: number) {
subscribers.delete(token);
if (!subscribers.size) this.unregister();
},
unregister() {
Object.keys(responsiveMap).forEach((screen: Breakpoint) => {
const matchMediaQuery = responsiveMap[screen]!;
const handler = this.matchHandlers[matchMediaQuery];
if (handler && handler.mql && handler.listener) {
handler.mql.removeListener(handler.listener);
}
handler?.mql.removeListener(handler?.listener);
});
subscribers.clear();
},
register() {
Object.keys(responsiveMap).forEach((screen: Breakpoint) => {

View File

@ -40,7 +40,7 @@ export default class Row extends React.Component<RowProps, RowState> {
},
};
token: string;
token: number;
componentDidMount() {
this.token = ResponsiveObserve.subscribe(screens => {