Skip to content

Instantly share code, notes, and snippets.

@mgtitimoli
Created January 21, 2021 02:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgtitimoli/cc2a20aa2d9748b5d59b773b68b359dd to your computer and use it in GitHub Desktop.
Save mgtitimoli/cc2a20aa2d9748b5d59b773b68b359dd to your computer and use it in GitHub Desktop.
StateAccessor (getter, setter) Hook => useStateAccessor
import React from "react";
import type {ReactStateAccessor} from "./useStateAccessor";
type State = {
count: number;
};
type StateAccessor = ReactStateAccessor<State>
const increaseCount = ({count}: State) => ({count: count + 1});
const render = (stateAccesor: StateAccessor) => (
<div>
<div>Count: {stateAccessor()}</div>
<button onClick={() => stateAccessor()}>Count: {stateAccessor(increaseCount)}</button>
<div>
)
const initialState = {
count: 0
};
const Test = () =>
render(useStateAccessor(initialState));
export default Test;
import {useRef, useState} from "react";
import type {SetStateAction} from "react";
type ReactStateAccessor<State> = (
...args: [] | [SetStateAction<State>]
) => State;
const useStateAccessors = <State>(
initialState: State
): ReactStateAccessor<State> => {
const [, setState] = useState(initialState);
const stateRef = useRef(initialState);
return (...args) => {
if (args.length === 1) {
const [newStateOrSetter] = args;
stateRef.current =
newStateOrSetter instanceof Function
? newStateOrSetter(stateRef.current)
: newStateOrSetter;
setState(stateRef.current);
}
return stateRef.current;
};
};
export default useStateAccessors;
export type {ReactStateAccessor};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment