mirror of
https://github.com/zhigang1992/react.git
synced 2026-04-22 19:48:49 +08:00
feat(utils): export use-current-state
test(utils): add testcase
This commit is contained in:
36
components/utils-shared/__tests__/current-state.test.tsx
Normal file
36
components/utils-shared/__tests__/current-state.test.tsx
Normal 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()
|
||||
})
|
||||
})
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
23
components/utils-shared/use-current-state.ts
Normal file
23
components/utils-shared/use-current-state.ts
Normal 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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user