feat(utils): export use-current-state

test(utils): add testcase
This commit is contained in:
unix
2020-05-01 18:43:42 +08:00
parent 6cfc87e917
commit 16c879ab3e
4 changed files with 62 additions and 21 deletions

View File

@@ -0,0 +1,36 @@
import React, { useEffect } from 'react'
import { mount } from 'enzyme'
import useCurrentState from '../use-current-state'
import { renderHook, act } from '@testing-library/react-hooks'
describe('UseCurrentState', () => {
it('should work correctly', () => {
const { result } = renderHook(() => useCurrentState(''))
expect(result.current[0]).toEqual('')
act(() => result.current[1]('test'))
expect(result.current[0]).toEqual('test')
expect(result.current[2].current).toEqual('test')
})
it('only ref should track latest value', () => {
const Mock: React.FC<{}> = () => {
const [state, setState, stateRef] = useCurrentState('')
useEffect(() => {
return () => {
setTimeout(() => {
expect(state).not.toEqual('test2')
expect(stateRef.current).toEqual('test2')
}, 0)
}
}, [])
useEffect(() => {
setState('test')
setState('test2')
}, [])
return <span />
}
const wrapper = mount(<Mock />)
expect(() => wrapper.unmount()).not.toThrow()
})
})

View File

@@ -1,7 +1,9 @@
import { default as useBodyScroll } from './use-body-scroll'
import { default as useClipboard } from './use-clipboard'
import { default as useCurrentState } from './use-current-state'
export default {
useBodyScroll,
useClipboard,
useCurrentState,
}

View File

@@ -0,0 +1,23 @@
import { Dispatch, MutableRefObject, SetStateAction, useEffect, useRef, useState } from 'react'
export type CurrentStateType<S> = [
S, Dispatch<SetStateAction<S>>, MutableRefObject<S>
]
const useCurrentState = <S,>(initialState: S): CurrentStateType<S> => {
const [state, setState] = useState<S>(initialState as S)
const ref = useRef<S>(initialState as S)
useEffect(() => {
ref.current = state
}, [state])
const setValue = (val: S) => {
ref.current = val
setState(val)
}
return [state, setValue, ref]
}
export default useCurrentState

View File

@@ -1,23 +1,3 @@
import { Dispatch, MutableRefObject, SetStateAction, useEffect, useRef, useState } from 'react'
export type CurrentStateType<S> = [
S, Dispatch<SetStateAction<S>>, MutableRefObject<S>
]
const useCurrentState = <S,>(initialState: S): CurrentStateType<S> => {
const [state, setState] = useState<S>(initialState as S)
const ref = useRef<S>(initialState as S)
useEffect(() => {
ref.current = state
}, [state])
const setValue = (val: S) => {
ref.current = val
setState(val)
}
return [state, setValue, ref]
}
import useCurrentState from '../utils-shared/use-current-state'
export default useCurrentState