CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/app-framework/hooks.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
/* Gather together and export some common hooks for convenience. */
7
8
declare const window: any;
9
10
import {
11
useCallback,
12
useEffect,
13
useLayoutEffect,
14
useMemo,
15
useRef,
16
useState,
17
} from "react";
18
import { useSelector } from "react-redux";
19
import { useAsyncEffect } from "use-async-effect";
20
21
import { useFrameContext } from "@cocalc/frontend/frame-editors/frame-tree/frame-context";
22
import useCounter from "./counter-hook";
23
import useDelayedRender from "./delayed-render-hook";
24
import useIsMountedRef from "./is-mounted-hook";
25
import useToggle from "./toggle-hook";
26
27
export {
28
useAsyncEffect,
29
useCallback,
30
useCounter,
31
useDelayedRender,
32
useEffect,
33
useFrameContext,
34
useIsMountedRef,
35
useLayoutEffect,
36
useMemo,
37
useRef,
38
useSelector,
39
useState,
40
useToggle,
41
};
42
43
export function useForceUpdate() {
44
const counterRef = useRef<any>(0);
45
const [, setCounter] = useState<number>(0);
46
return () => {
47
setCounter((counterRef.current += 1));
48
};
49
}
50
51
/* Delay rendering for a certain number of milliseconds.
52
Use it like this at the top of your component to make it
53
so nothing gets rendered until after the delay:
54
55
const render = useDelayedRender(props.index);
56
// ...
57
// any other hooks
58
// ...
59
if (!render) {
60
return <></>;
61
}
62
63
*/
64
65
function getWindowDimensions() {
66
const { innerWidth: width, innerHeight: height } = window;
67
return { width, height };
68
}
69
70
export function useWindowDimensions() {
71
const [windowDimensions, setWindowDimensions] = useState(
72
getWindowDimensions(),
73
);
74
75
useEffect(() => {
76
function handleResize() {
77
setWindowDimensions(getWindowDimensions());
78
}
79
80
window.addEventListener("resize", handleResize);
81
return () => window.removeEventListener("resize", handleResize);
82
}, []);
83
84
return windowDimensions;
85
}
86
87
// if val changes, it updates the reference to the previous value.
88
// With that, from the component itself, you always have access to the previous value.
89
// Watch out, initially it's certainly undefined!
90
export function usePrevious<T>(val: T): T | null {
91
const prevRef = useRef<T | null>(null);
92
93
useEffect(() => {
94
prevRef.current = val;
95
}, [val]);
96
97
return prevRef.current;
98
}
99
100