Skip to content

Instantly share code, notes, and snippets.

@joemaffei
Created July 25, 2022 18:07
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 joemaffei/dfc63040cfa3112972a8e3bf5cf75014 to your computer and use it in GitHub Desktop.
Save joemaffei/dfc63040cfa3112972a8e3bf5cf75014 to your computer and use it in GitHub Desktop.
React's useState in Vue
// inspired by https://markus.oberlehner.net/blog/usestate-and-usereducer-with-the-vue-3-composition-api/
import { readonly, ref, UnwrapRef } from "vue";
// "corporate" version
export function useState<T>(initialState: T | undefined) {
type InitialState = T | undefined;
type State = UnwrapRef<T> | undefined;
type StateFn = (currentState: State) => State;
const state = ref<InitialState>(initialState);
const setStateValue = (newState: State) => {
state.value = newState;
};
const setStateFunction = (fn: StateFn) => {
setStateValue(fn(state.value));
};
const setState = (stateOrFn: State | StateFn) => {
if (stateOrFn instanceof Function) {
setStateFunction(stateOrFn);
} else {
setStateValue(stateOrFn);
}
};
return [readonly(state), setState];
}
// "library" version
export function useState2<T>(initialState: T | undefined) {
const state = ref<T | undefined>(initialState);
const setState = (
arg:
| UnwrapRef<T>
| ((currentState: UnwrapRef<T> | undefined) => UnwrapRef<T> | undefined)
| undefined
) => {
state.value = arg instanceof Function ? arg(state.value) : arg;
};
return [readonly(state), setState];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment