mirror of
https://github.com/streamich/react-use.git
synced 2025-12-08 18:02:14 +00:00
feat: add onChange callback to useWindowSize
This commit is contained in:
parent
e1d0cd9f7f
commit
3eb531ac9e
@ -19,3 +19,18 @@ const Demo = () => {
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
```js
|
||||
useWindowSize(options);
|
||||
```
|
||||
|
||||
- `initialWidth` — Initial width value for non-browser environments.
|
||||
- `initialHeight` — Initial height value for non-browser environments.
|
||||
- `onChange` — Callback function triggered when the window size changes.
|
||||
|
||||
## Related hooks
|
||||
|
||||
- [useSize](./useSize.md)
|
||||
- [useMeasure](./useMeasure.md)
|
||||
@ -3,7 +3,17 @@ import { useEffect } from 'react';
|
||||
import useRafState from './useRafState';
|
||||
import { isBrowser, off, on } from './misc/util';
|
||||
|
||||
const useWindowSize = (initialWidth = Infinity, initialHeight = Infinity) => {
|
||||
interface Options {
|
||||
initialWidth?: number;
|
||||
initialHeight?: number;
|
||||
onChange?: (width: number, height: number) => void;
|
||||
}
|
||||
|
||||
const useWindowSize = ({
|
||||
initialWidth = Infinity,
|
||||
initialHeight = Infinity,
|
||||
onChange,
|
||||
}: Options = {}) => {
|
||||
const [state, setState] = useRafState<{ width: number; height: number }>({
|
||||
width: isBrowser ? window.innerWidth : initialWidth,
|
||||
height: isBrowser ? window.innerHeight : initialHeight,
|
||||
@ -12,10 +22,15 @@ const useWindowSize = (initialWidth = Infinity, initialHeight = Infinity) => {
|
||||
useEffect((): (() => void) | void => {
|
||||
if (isBrowser) {
|
||||
const handler = () => {
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
|
||||
setState({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
});
|
||||
|
||||
if (onChange) onChange(width, height);
|
||||
};
|
||||
|
||||
on(window, 'resize', handler);
|
||||
|
||||
@ -21,8 +21,8 @@ describe('useWindowSize', () => {
|
||||
expect(useWindowSize).toBeDefined();
|
||||
});
|
||||
|
||||
function getHook(...args) {
|
||||
return renderHook(() => useWindowSize(...args));
|
||||
function getHook(options?: any) {
|
||||
return renderHook(() => useWindowSize(options));
|
||||
}
|
||||
|
||||
function triggerResize(dimension: 'width' | 'height', value: number) {
|
||||
@ -44,7 +44,7 @@ describe('useWindowSize', () => {
|
||||
});
|
||||
|
||||
it('should use passed parameters as initial values in case of non-browser use', () => {
|
||||
const hook = getHook(1, 1);
|
||||
const hook = getHook({ initialWidth: 1, initialHeight: 1 });
|
||||
|
||||
expect(hook.result.current.height).toBe(isBrowser ? window.innerHeight : 1);
|
||||
expect(hook.result.current.width).toBe(isBrowser ? window.innerWidth : 1);
|
||||
@ -85,4 +85,27 @@ describe('useWindowSize', () => {
|
||||
|
||||
expect(hook.result.current.width).toBe(2048);
|
||||
});
|
||||
|
||||
it('should call onChange callback on window resize', () => {
|
||||
const onChange = jest.fn();
|
||||
getHook({ onChange });
|
||||
|
||||
act(() => {
|
||||
triggerResize('width', 720);
|
||||
triggerResize('height', 480);
|
||||
requestAnimationFrame.step();
|
||||
});
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith(720, 480);
|
||||
expect(onChange).toHaveBeenCalledTimes(2);
|
||||
|
||||
act(() => {
|
||||
triggerResize('width', 1920);
|
||||
triggerResize('height', 1080);
|
||||
requestAnimationFrame.step();
|
||||
});
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith(1920, 1080);
|
||||
expect(onChange).toHaveBeenCalledTimes(4);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user