Skip to content

Instantly share code, notes, and snippets.

@pomle
Last active December 20, 2022 17:54
Show Gist options
  • Save pomle/017cbb9c5eed66ace6261aee15c19327 to your computer and use it in GitHub Desktop.
Save pomle/017cbb9c5eed66ace6261aee15c19327 to your computer and use it in GitHub Desktop.
Captain Hook's Fabulous Hooks
/*
Creates a sticky block of rendered content.
Useful when you want to memoize part of the render tree and optionally rerender.
*/
import { useMemo, useRef } from "react";
export function useContentCache(
renderer: () => React.ReactElement | undefined,
deps: any[]
): React.ReactElement | null {
const cache = useRef<React.ReactElement>();
useMemo(() => {
const content = renderer();
if (content !== undefined) {
cache.current = content;
}
}, deps); // eslint-disable-line react-hooks/exhaustive-deps
return cache.current || null;
}
/*
Usage:
return (
<div className={classes.body}>
{useContentCache(() => {
if (!result) {
return; // Renders the last seen content, default null
}
return (
<ItemList>
{result.map(({ item }) => {
return (
<ExpensiveTree item={item}/>
);
})}
</ItemList>
);
}, [result])}
</div>
);
*/
import { useState, useEffect, useMemo } from "react";
import moment, { Moment, DurationInputArg2 as Unit } from "moment";
export const useLiveTime = (unit: Unit): Moment => {
const initial = useMemo(moment, []);
const [time, setTime] = useState<Moment>(initial);
useEffect(() => {
const nextTime = time
.clone()
.startOf(unit)
.add(1, unit);
const delay = nextTime.diff(time, "milliseconds");
const timer = setTimeout(setTime, delay, nextTime);
return () => clearTimeout(timer);
}, [unit, time, setTime]);
return time;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment