Skip to content

Instantly share code, notes, and snippets.

View freddi301's full-sized avatar

Frederik Batuna freddi301

View GitHub Profile
@freddi301
freddi301 / useMemoizedCallbacks.tsx
Created October 11, 2019 09:57
useMemoizedCallbacks #react #hook
import { useMemo } from "react";
import { memoize } from "lodash";
/**
* @description useful for callback that are passed to repeated component
* @example
* const makeRemove=useMemoizedCallback((date:Date)=>()=>{},String,[]);
* ...
* <ol>calendarEvents.map(calendarEvent => <li onClick={makeRemove(calendarEvent)}>{calendarEvent.toLocaleString()}</li>)</ol>
*/
@freddi301
freddi301 / useMediaQuery.tsx
Created October 11, 2019 09:56
useMediaQuery #react #hook
import React from "react";
/**
* Matches mediaquery, rerenders only when match changes
* @param query media query
*/
export function useMediaQuery(
query: string | null | false,
defValue: boolean = false,
) {
@freddi301
freddi301 / useInterval.tsx
Created October 11, 2019 09:56
useInterval #react #hook
/**
* This is an implementation of javascript's imperative setInterval API
* combined with React hooks' declarative approach.
*
* It is actually a replica of Dan Abramov's implementation described here:
* https://overreacted.io/making-setinterval-declarative-with-react-hooks/
*/
import { useEffect, useRef } from "react";
@freddi301
freddi301 / useExpiration.tsx
Created October 11, 2019 09:55
useExpiration: returns true if given timestamp is in the future #react #hook
import { useState, useEffect } from "react";
/** @description hook: returns true if given timestamp is in the future */
export function useExpiration(
timestamp: number | null | undefined,
): boolean {
const visible = timestamp != null && Date.now() <= timestamp;
const [, forceRerender] = useState(0);
useEffect(() => {
if (visible && timestamp != null) {
@freddi301
freddi301 / useDebubPropChanges.tsx
Created October 11, 2019 09:53
useDebugPropChanges #react #hook
import { useRef } from "react";
/**
* @description used for identify changes between re-renders
* @example
* const changedProps = useChanges(props)
* @example
* useChanges(props, changes => console.log(changes))
*/
export function useDebugPropsChanges<T extends Record<any, any>>(
@freddi301
freddi301 / useDebounce.tsx
Last active July 1, 2020 08:59
Debounced value #react #hook
import React from "react";
export default function useDebounce<T>(value: T, delay: number) {
const [debouncedValue, setDebouncedValue] = React.useState(value);
React.useEffect(() => {
const timeout = setTimeout(() => {
setDebouncedValue(value);
}, delay);
@freddi301
freddi301 / useUndoReducer.ts
Last active October 26, 2019 17:10
Undoable Reducer react hooks #react #hook
function useUndoReducer<State, Action>(
reducer: (state: State, action: Action) => State,
initial: () => State[]
) {
const [index, setIndex] = useState(0);
const [history, setHistory] = useState(initial);
const state = history[index];
const dispatch = useCallback(
(action: Action) => {
const updated = history.slice(0, index + 1);
@freddi301
freddi301 / useUndoState.ts
Last active October 11, 2019 09:52
Unduoable state react hook #react #hook
function useUndoState<T>(initial: T) {
const [index, setIndex] = useState(0);
const [history, setHistory] = useState([initial]);
const state = history[index];
const setState = useCallback(
(update: (s: T) => T) => {
const updated = history.slice(0, index + 1);
updated.push(update(state));
setHistory(updated);
setIndex(index + 1);
@freddi301
freddi301 / fiber.ts
Created August 20, 2019 22:27
Fiber (react fibers outside react) immutable version
type FiberFunction<Args extends any[], Return> = (
cell: CellFunction
) => (...args: Args) => Return;
type FiberInstance<Args extends any[], Return> = (
...args: Args
) => [Return, FiberInstance<Args, Return>];
type FiberFactory = <Args extends any[], Return>(
fiber: FiberFunction<Args, Return>,
@freddi301
freddi301 / AsyncNode.tsx
Last active August 26, 2019 09:59
React component and hook for rendering promises
export function AsyncNode({ children }: { children: Promise<ReactNode> }) {
return useLatestResolvedValue<ReactNode>(children, () => null) as any;
// as any assertion needed for issue https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20356#issuecomment-336384210
}
export function useLatestResolvedValue<Value>(
promise: Promise<Value>,
initial: () => Value
) {
const [[value], dispatch] = useReducer<