npm package: @rdshah/react-hooks
Description: Useful & commonly used hooks for React
Author: rdshah
Latest version: 2.0.2

# react-hooks

## useEventListener
Params:
* eventName: `"mouseup" | "keydown" | "wheel" | ...`
* handler: `(evt) => void`
* identifier?: `string | React.RefObject<HTMLElement> | HTMLElement;` (leave blank to bind listener to `window`)

```
function MyComponent() {
    const ref = React.useRef();

    function handler(event) {
        console.log(event);
        // do stuff
    }

    // all three of the below options are valid
    useEventListener("mouseup", handler, "myId");
    useEventListener("mouseup", handler, ref);
    useEventListener("mouseup", handler, ref.current);

    return <div ref={ref} id="myId">Hello, World!</div>
}
```

## useDebouncedValue<T>
Params:
* value: `T`
* wait: `number`
* serializer: `(value: T) => any`

Whenver `wait`ms go by without any changes to the value of `serializer(value)`, then the return value of this hook is updated to `value`.

```
function MyComponent() {
    const [value, setValue] = React.useState("");
    const debouncedValue = useDebouncedValue(value);
    const [expensiveResult, setExpensiveResult] = React.useState();

    React.useEffect(() => {
        (async () => {
            const val = await computeExpensiveFunction(debouncedValue);
            setExpensiveResult(val);
        })();
    }, [debouncedValue]);

    return <>
        <input value={value} onChange={evt => setValue(evt.target.value)}/>
        <span>{expensiveResult}</span>
    </>
}
```

## useDebouncedCallback<T>
Params:
* callback: `(arg?: T) => void`
* wait: `number`

Returns a function which, when invoked, sets a timeout to call `callback` after `wait`ms.  If the returned function is called again within `wait`ms, then the first call is cancelled and a new timeout is set.
```
function sendValueToServerOrSomething(value) {
    // ...
}

function MyComponent() {
    const [value, setValue] = React.useState("");
    const debounced = useDebouncedCallback(sendValueToServerOrSomething);

    React.useEffect(() => {
        debounced(value);
    }, [value]);

    return <input value={value} onChange={evt => setValue(evt.target.value)}/>
}
```

## useLocalControl<T>
Params:
* value: `T`
* setValue: `React.Dispatch<React.SetStateAction<T>>`
* wait: `number`

Sometimes a child has the ability to edit state which results in an expensive rerender.  This hook allows one to debounce the updates while simultaneously listening for updates from the parent.
```
function Parent() {
    const [value, setValue] = React.useState("");

    return <>
        <SomeDisplayComponent value={value} />
        <Child value={value} setValue={setValue} num="1" />
        <Child value={value} setValue={setValue} num="2" />
    </>
}

function Child({value, setValue, num}) {
    const [local, setLocal] = useLocalControl(value, setValue);
    return <>
        <span>{num}: </span>
        <input value={local} onChange={e => setLocal(e.target.value)} />
    </>
}
```


## usePrevious<T>
Params:
* value: `T`
* count?: `number` (default is `Infinity`)

Returns an array of the past (at most) `count` distinct values of `value`.  Initially returns a empty list `[]`.

## useForceUpdate
Returns a function which, when invoked, triggers a re-render of the component.  Similar to this.forceUpdate() in a class component.