[fix] Dimensions.get() should not call change listeners

Fixes a bug introduced by 59af091fdb

Fix #2394
This commit is contained in:
Nicolas Gallagher
2022-11-02 11:26:24 -07:00
parent dee258ae02
commit 0f692f2c2b
2 changed files with 38 additions and 32 deletions
@@ -9,6 +9,8 @@ import Dimensions from '..';
describe('apis/Dimensions', () => { describe('apis/Dimensions', () => {
test('get', () => { test('get', () => {
const handler = jest.fn();
Dimensions.addEventListener('change', handler);
expect(Dimensions.get('screen')).toMatchInlineSnapshot(` expect(Dimensions.get('screen')).toMatchInlineSnapshot(`
{ {
"fontScale": 1, "fontScale": 1,
@@ -25,6 +27,7 @@ describe('apis/Dimensions', () => {
"width": 1024, "width": 1024,
} }
`); `);
expect(handler).toHaveBeenCalledTimes(0);
}); });
test('set', () => { test('set', () => {
@@ -34,21 +37,21 @@ describe('apis/Dimensions', () => {
test('addEventListener', () => { test('addEventListener', () => {
const handler = jest.fn(); const handler = jest.fn();
const subscription = Dimensions.addEventListener('change', handler); const subscription = Dimensions.addEventListener('change', handler);
Dimensions._update(); window.dispatchEvent(new Event('resize'));
expect(handler).toHaveBeenCalledTimes(1); expect(handler).toHaveBeenCalledTimes(1);
expect(handler).toHaveBeenLastCalledWith({ expect(handler).toHaveBeenLastCalledWith({
window: Dimensions.get('window'), window: Dimensions.get('window'),
screen: Dimensions.get('screen') screen: Dimensions.get('screen')
}); });
subscription.remove(); subscription.remove();
Dimensions._update(); window.dispatchEvent(new Event('resize'));
expect(handler).toHaveBeenCalledTimes(1); expect(handler).toHaveBeenCalledTimes(1);
}); });
test('removeEventListener', () => { test('removeEventListener', () => {
const handler = jest.fn(); const handler = jest.fn();
Dimensions.removeEventListener('change', handler); Dimensions.removeEventListener('change', handler);
Dimensions._update(); window.dispatchEvent(new Event('resize'));
expect(handler).toHaveBeenCalledTimes(0); expect(handler).toHaveBeenCalledTimes(0);
}); });
}); });
+30 -27
View File
@@ -46,32 +46,7 @@ const listeners = {};
let shouldInit = canUseDOM; let shouldInit = canUseDOM;
export default class Dimensions { function update() {
static get(dimension: DimensionKey): DisplayMetrics {
if (shouldInit) {
shouldInit = false;
Dimensions._update();
}
invariant(dimensions[dimension], `No dimension set for key ${dimension}`);
return dimensions[dimension];
}
static set(initialDimensions: ?DimensionsValue): void {
if (initialDimensions) {
if (canUseDOM) {
invariant(false, 'Dimensions cannot be set in the browser');
} else {
if (initialDimensions.screen != null) {
dimensions.screen = initialDimensions.screen;
}
if (initialDimensions.window != null) {
dimensions.window = initialDimensions.window;
}
}
}
}
static _update() {
if (!canUseDOM) { if (!canUseDOM) {
return; return;
} }
@@ -92,10 +67,38 @@ export default class Dimensions {
scale: win.devicePixelRatio || 1, scale: win.devicePixelRatio || 1,
width: win.screen.width width: win.screen.width
}; };
}
function handleResize() {
update();
if (Array.isArray(listeners['change'])) { if (Array.isArray(listeners['change'])) {
listeners['change'].forEach((handler) => handler(dimensions)); listeners['change'].forEach((handler) => handler(dimensions));
} }
}
export default class Dimensions {
static get(dimension: DimensionKey): DisplayMetrics {
if (shouldInit) {
shouldInit = false;
update();
}
invariant(dimensions[dimension], `No dimension set for key ${dimension}`);
return dimensions[dimension];
}
static set(initialDimensions: ?DimensionsValue): void {
if (initialDimensions) {
if (canUseDOM) {
invariant(false, 'Dimensions cannot be set in the browser');
} else {
if (initialDimensions.screen != null) {
dimensions.screen = initialDimensions.screen;
}
if (initialDimensions.window != null) {
dimensions.window = initialDimensions.window;
}
}
}
} }
static addEventListener( static addEventListener(
@@ -125,5 +128,5 @@ export default class Dimensions {
} }
if (canUseDOM) { if (canUseDOM) {
window.addEventListener('resize', Dimensions._update, false); window.addEventListener('resize', handleResize, false);
} }