diff --git a/src/useOrientation.ts b/src/useOrientation.ts index b5365af90f..a7f2664664 100644 --- a/src/useOrientation.ts +++ b/src/useOrientation.ts @@ -16,6 +16,7 @@ const useOrientation = (initialState: OrientationState = defaultState) => { useEffect(() => { const screen = window.screen; + const orientation = screen.orientation as (ScreenOrientation & EventTarget) | undefined; let mounted = true; const onChange = () => { @@ -36,14 +37,22 @@ const useOrientation = (initialState: OrientationState = defaultState) => { } }; - on(window, 'orientationchange', onChange); + if (orientation?.addEventListener) { + on(orientation, 'change', onChange); + } else { + on(window, 'orientationchange', onChange); + } onChange(); return () => { mounted = false; - off(window, 'orientationchange', onChange); + if (orientation?.removeEventListener) { + off(orientation, 'change', onChange); + } else { + off(window, 'orientationchange', onChange); + } }; - }, []); + }, [initialState]); return state; }; diff --git a/tests/useOrientation.test.ts b/tests/useOrientation.test.ts index df45546263..68761800dd 100644 --- a/tests/useOrientation.test.ts +++ b/tests/useOrientation.test.ts @@ -13,10 +13,10 @@ describe('useOrientation', () => { }); beforeEach(() => { - (window.screen.orientation as object) = { + (window.screen.orientation as unknown) = Object.assign(new EventTarget(), { type: 'landscape-primary', angle: 0, - }; + }); (window.orientation as number) = 0; }); @@ -32,10 +32,16 @@ describe('useOrientation', () => { return renderHook(() => useOrientation(...args)); } - function triggerOrientation(type: string, angle: number) { + function triggerScreenOrientation(type: string, angle: number) { (window.screen.orientation.type as string) = type; (window.screen.orientation.angle as number) = angle; + (window.screen.orientation as EventTarget).dispatchEvent(new Event('change')); + } + + function triggerWindowOrientation(angle: number) { + (window.orientation as number) = angle; + window.dispatchEvent(new Event('orientationchange')); } @@ -55,10 +61,24 @@ describe('useOrientation', () => { }); it('should re-render after orientation change on closest RAF', () => { + (window.screen.orientation as unknown) = undefined; + + const hook = getHook(); + + act(() => { + triggerWindowOrientation(180); + requestAnimationFrame.step(); + }); + + expect(hook.result.current.type).toBe(''); + expect(hook.result.current.angle).toBe(180); + }); + + it('should re-render after screen.orientation change', () => { const hook = getHook(); act(() => { - triggerOrientation('portrait-secondary', 180); + triggerScreenOrientation('portrait-secondary', 180); requestAnimationFrame.step(); });