-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(hooks): add state hooks: useRef, useState, useSignal
- Loading branch information
1 parent
fdde679
commit 09f6464
Showing
2 changed files
with
82 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { ref } from 'vue'; | ||
import type { Ref } from 'vue'; | ||
|
||
/** | ||
* useRef | ||
* | ||
* it is a simple ref management hook wrapped by vue3's ref function. | ||
* | ||
* to resolve the ref type problem about `UnwrapRef` | ||
* | ||
* @param initValue | ||
*/ | ||
export function useRef<T>(initValue: T) { | ||
const refValue = ref(initValue) as Ref<T>; | ||
|
||
return refValue; | ||
} | ||
|
||
/** | ||
* useState | ||
* | ||
* define a state and a setState function | ||
* | ||
* @param initValue | ||
*/ | ||
export function useState<T>(initValue: T) { | ||
const state = useRef(initValue); | ||
|
||
function setState(value: T) { | ||
state.value = value; | ||
} | ||
|
||
return [state, setState] as const; | ||
} | ||
|
||
interface Signal<T> { | ||
(): T; | ||
/** | ||
* the ref object of the signal, but it is readonly | ||
* | ||
* equal to `const ref = ref(initValue);` | ||
*/ | ||
readonly ref: Readonly<Ref<T>>; | ||
/** | ||
* set the value of the signal | ||
* | ||
* @param value | ||
*/ | ||
set(value: T): void; | ||
/** | ||
* update the value of the signal | ||
* | ||
* @param fn update function | ||
*/ | ||
update(fn: (value: T) => T): void; | ||
} | ||
|
||
/** | ||
* useSignal | ||
* | ||
* @param initValue | ||
*/ | ||
export function useSignal<T>(initValue: T) { | ||
const [state, setState] = useState(initValue); | ||
|
||
function updateState(fn: (value: T) => T) { | ||
const updatedValue = fn(state.value); | ||
setState(updatedValue); | ||
} | ||
|
||
const signal = function signal() { | ||
return state.value; | ||
} as Signal<T>; | ||
|
||
(signal as any).ref = state; | ||
|
||
signal.set = setState; | ||
signal.update = updateState; | ||
|
||
return signal; | ||
} |