Skip to content

useMediatedState

Works just like regular useState but with a mediation function being executed before the state changes.

Installation

npx rabbithook@latest add use-mediated-state

Usage

App.tsx
import useMediatedState from "@/hooks/use-mediated-state";
function Component() {
const [count, setCount] = useMediatedState(0, value => value * 2);
return (
<>
<div>Count: {count}</div> {/* 0, 2, 4, 8, ... */}
<button onClick={() => setCount(count + 1)}>Increment</button>
</>
);
}

Code

use-mediated-state.ts
import { useCallback, useState } from "react";
type IMediationFn<T> = (value: T) => T;
type IMediatedState<T> = T | IMediationFn<T>;
function useMediatedState<T>(initialState: IMediatedState<T>, mediationFn: (value: T) => T) {
const [state, setState] = useState(
typeof initialState === "function"
? (initialState as IMediationFn<T>)(undefined as T)
: initialState
);
const mediatedSetState = useCallback((value: IMediatedState<T>) => {
const resolvedValue = typeof value === "function" ? (value as IMediationFn<T>)(state) : value;
setState(mediationFn(resolvedValue));
}, [mediationFn]);
return [state, mediatedSetState] as const;
}
export default useMediatedState;