-
Notifications
You must be signed in to change notification settings - Fork 3
/
useRefState.ts
35 lines (31 loc) · 1.03 KB
/
useRefState.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { useCallback, useRef, useState, useEffect, MutableRefObject, Dispatch, SetStateAction } from 'react'
/**
* Determines if the given param is an object. {}
* @param obj
*/
export const isObject = (obj: any): obj is object => Object.prototype.toString.call(obj) === '[object Object]' // eslint-disable-line
const useMounted = () => {
const mounted = useRef(false)
useEffect(() => {
mounted.current = true
return () => {
mounted.current = false
}
}, [])
return mounted
}
export function useRefState<S>(
initialState: S | (() => S),
blockIfUnmounted: boolean = true
): [MutableRefObject<S>, Dispatch<SetStateAction<S>>] {
const mounted = useMounted()
const [reactState, setReactState] = useState(initialState)
const state = useRef(reactState)
const setState = useCallback(arg => {
if (!mounted.current && blockIfUnmounted) return
state.current = (typeof arg === 'function') ? arg(state.current) : arg
setReactState(state.current)
}, [])
return [state, setState]
}
export default useRefState