Skip to content

Commit 3684d8e

Browse files
committed
[IMPL] useRaf hook
1 parent e50a95c commit 3684d8e

7 files changed

Lines changed: 98 additions & 8 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { useState } from "react"
2+
import { useRaf, useResizeObserver } from "../../../../../../packages/react-tools/src";
3+
4+
/**
5+
The component renders a textarea element and when it is resized, updates __state__ variable inside function __start__ returned from _useRaf_ hook.
6+
*/
7+
export const UseRaf = () => {
8+
const [state, setState] = useState({ width: 0, height: 0 });
9+
const [start] = useRaf((timer: number, dim: DOMRectReadOnly) => {
10+
setState({width:dim.width, height: dim.height})
11+
});
12+
const [refCb] = useResizeObserver<HTMLTextAreaElement>(
13+
(entries: ResizeObserverEntry[]) => {
14+
start(entries[0].contentRect);
15+
}
16+
);
17+
18+
return <div>
19+
<p>{"Textarea dimension: " + JSON.stringify(state)}</p>
20+
<textarea ref={refCb} rows={3}></textarea>
21+
</div>
22+
}

apps/react-tools-demo/src/constants/components.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export const COMPONENTS = [
3737
"useMemoDeepCompare",
3838
"useCallbackCompare",
3939
"useCallbackDeepCompare",
40+
"useRaf",
4041
"useLazyRef",
4142
"useId"
4243
],

apps/react-tools-demo/src/markdown/useRequestIdleCallback.md renamed to apps/react-tools-demo/src/markdown/useIdle.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
# useRequestIdleCallback
2-
Hook to use [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback) in React. The __options__ parameter differs from _IdleRequestOptions_ type: it adds the possibility to pass another property __unsupportedBehavior__ to specify what do if requestIdleCallback is not supported.
1+
# useIdle
2+
Hook to invoke a callback when the browser is idle. Refer to [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback) in React. The __options__ parameter differs from _IdleRequestOptions_ type: it adds the possibility to pass another property __unsupportedBehavior__ to specify what do if requestIdleCallback is not supported.
33

44
## Usage
55

66
```tsx
7-
export const UseRequestIdleCallback = () => {
7+
export const UseIdle = () => {
88
const [iterations, setIterations] = useState(0);
99
const [log, setLog] = useState("");
10-
const [invoke] = useRequestIdleCallback(() => setLog("RequestIdleCallback executed"));
10+
const [invoke] = useIdle(() => setLog("RequestIdleCallback executed"));
1111

1212
const start = async() => {
1313
invoke();
@@ -31,14 +31,14 @@ export const UseRequestIdleCallback = () => {
3131
> The component has:
3232
> - a __iterations__ variable of type string.
3333
> - a __log__ variable of type string.
34-
> - a function __invoke__ returned from _useRequestIdleCallback_ hook, initialized with a cb that update __log__ variable with message _"RequestIdleCallback executed"_.
34+
> - a function __invoke__ returned from _useIdle_ hook, initialized with a cb that update __log__ variable with message _"RequestIdleCallback executed"_.
3535
> - a button start that when clicked executes __start__ function that executes __invoke__ function and updates __iterations__ variable inside a loop with iteration index.
3636
3737

3838
## API
3939

4040
```tsx
41-
useRequestIdleCallback (cb: (deadline?: IdleDeadline | DOMHighResTimeStamp | void) => void, opts?: {timeout: number , unsupportedBehavior?: "animationFrame" | "timeout" | "immediatly" }): [() => void, () => void]
41+
useIdle (cb: (deadline?: IdleDeadline | DOMHighResTimeStamp | void) => void, opts?: {timeout: number , unsupportedBehavior?: "animationFrame" | "timeout" | "immediatly" }): [() => void, () => void]
4242
```
4343

4444
> ### Params
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# useRaf
2+
Hook to execute a callback function with _requestAnimationFrame_ to optimize performance. Refer to (requestAnimationFrame)[https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame].
3+
4+
## Usage
5+
6+
```tsx
7+
export const UseRaf = () => {
8+
const [state, setState] = useState({ width: 0, height: 0 });
9+
const [start] = useRaf((timer: number, dim: DOMRectReadOnly) => {
10+
setState({width:dim.width, height: dim.height})
11+
});
12+
const [refCb] = useResizeObserver<HTMLTextAreaElement>(
13+
(entries: ResizeObserverEntry[]) => {
14+
start(entries[0].contentRect);
15+
}
16+
);
17+
18+
return <div>
19+
<p>{"Textarea dimension: " + JSON.stringify(state)}</p>
20+
<textarea ref={refCb} rows={3}></textarea>
21+
</div>
22+
}
23+
```
24+
25+
> The component renders a textarea element and when it is resized, updates __state__ variable inside function __start__ returned from _useRaf_ hook.
26+
27+
28+
## API
29+
30+
```tsx
31+
useRaf <T extends unknown[]>(cb: (timer:number, ...args: T) => void): [(...args: T)=>void, ()=>void]
32+
```
33+
34+
> ### Params
35+
>
36+
> - __cb__: _(timer:number, ...args: T) => void_
37+
callback to execute prior to the next repaint.
38+
>
39+
40+
> ### Returns
41+
>
42+
> __results__: array with __start__ function to invoke _requestAnimationFrame_ and __cancel__ function to invoke _cancelAnimationFrame_.
43+
> - __Array__:
44+
> - _(...args: T)=>void_
45+
> - _()=>void_
46+
>

packages/react-tools/src/hooks/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ export { useIsOnline } from './useIsOnline';
5151
export { useResizeObserver } from './useResizeObserver';
5252
export { useIntersectionObserver } from './useIntersectionObserver';
5353
export { useMutationObserver } from './useMutationObserver';
54-
export { useIdle } from './useIdle';
54+
export { useIdle } from './useIdle';
55+
export { useRaf } from './useRaf';
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { useCallback, useRef } from "react"
2+
3+
/**
4+
* **`useRaf`**: Hook to execute a callback function with _requestAnimationFrame_ to optimize performance. Refer to (requestAnimationFrame)[https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame].
5+
* @param {(timer:number, ...args: T) => void} cb - callback to execute prior to the next repaint.
6+
* @returns {[(...args: T)=>void, ()=>void]} results - array with __start__ function to invoke _requestAnimationFrame_ and __cancel__ function to invoke _cancelAnimationFrame_.
7+
*/
8+
export const useRaf = <T extends unknown[]>(cb: (timer:number, ...args: T) => void): [(...args: T)=>void, ()=>void] => {
9+
const idRequest = useRef<number>();
10+
11+
return [
12+
useCallback((...args: T) => {
13+
idRequest.current = requestAnimationFrame((timer) => cb(timer, ...args));
14+
}, [cb]),
15+
useCallback(() => {
16+
!!idRequest.current && cancelAnimationFrame(idRequest.current)
17+
}, [])
18+
]
19+
}

packages/react-tools/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ export {
6565
useResizeObserver,
6666
useIntersectionObserver,
6767
useMutationObserver,
68-
useIdle
68+
useIdle,
69+
useRaf
6970
} from './hooks'
7071

7172
export {

0 commit comments

Comments
 (0)