Skip to content

Commit

Permalink
feat: useReducer
Browse files Browse the repository at this point in the history
  • Loading branch information
kalu5 committed Apr 12, 2024
1 parent 1d6893e commit ed39e50
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib"
}
28 changes: 28 additions & 0 deletions __test__/useReducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { expect, test } from 'vitest'
import type { Ref } from 'vue'
import type { ReturnDisptch } from '../libs/types'

import { useReducer } from '../libs/main'

function reducer(state, action) {
if (action.type === 'add')
return state.value + 1

return state.value - 1
}
test('useReducer', () => {
const [state, dispatch] = useReducer<number>(reducer, 1)
expect((state as Ref<number>).value).toBe(1);
(dispatch as ReturnDisptch) ({ type: 'add' })
expect((state as Ref<number>).value).toBe(2)
})

test('useReducer has init ', () => {
const init = (arg: number) => {
return arg + 1
}
const [state, dispatch] = useReducer<number>(reducer, 1, init)
expect((state as Ref<number>).value).toBe(2);
(dispatch as ReturnDisptch) ({ type: 'add' })
expect((state as Ref<number>).value).toBe(3)
})
2 changes: 2 additions & 0 deletions libs/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import useState from './useState'
import useReducer from './useReducer'

export {
useState,
useReducer,
}
22 changes: 22 additions & 0 deletions libs/hooks/useReducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Ref } from 'vue'
import type { Action, Init, Reducer, ReturnDisptch, SetStateSetter } from '../types/index'
import { isFunc } from '../utils/index'
import useState from './useState'

export default function useReducer<U>(reducer: Reducer<U>, initArg: U, init?: Init<U>) {
let lastInit: U = initArg
if (init && isFunc(init))
lastInit = init(lastInit)

const [_state, setState] = useState<U>(lastInit)

const _dispatch = createDispatch<U>(reducer, _state, setState)

return [_state, _dispatch]
}

function createDispatch<T>(reducer: Reducer<T>, _state: Ref<T>, setState: SetStateSetter<T>): ReturnDisptch {
return function (action: Action) {
setState (reducer (_state, action))
}
}
11 changes: 11 additions & 0 deletions libs/types/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
import type { Ref } from 'vue'

export type SetStateSetter<U> = (newState: U) => void
export interface Action {
type: string
}

export type Reducer<T> = (state: Ref<T>, action: Action) => T

export type Init<T> = (init: T) => T

export type ReturnDisptch = (action: Action) => void
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@kalu5/vue_hooks",
"type": "module",
"version": "1.0.5",
"version": "1.0.6",
"private": false,
"description": "This is vue3 hooks utils",
"author": "lujialong",
Expand Down
1 change: 1 addition & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
include: ['__test__/**'],
coverage: {
include: [
'libs/**',
Expand Down

0 comments on commit ed39e50

Please sign in to comment.