hooks-for-react
v3.0.5
Published
A set of must use hooks necessary for daily work with react
Downloads
49
Readme
Hooks for React
A Set of Must use Hooks necessary for daily work with React
Table of contents
State
useSuperState
Use a state with super powers.
This hook is like a combination of useState
, useMemo
and useRef
hooks at once.
Performance savings: This hook gives you the ability to apply logic on the go, and saves you unnecessary component rendering by eliminating the need to use React
useEffect
to update the state in certain scenarios.
Returns a stateful value, and a function to update it + a ref to the state value.
Definition
<S>(factory: S | ((prev: S) => S), deps?: DependencyList): [S, Dispatch<SetStateAction<S>>, MutableRefObject<S>]
Usage
You can use it as you normally do with the useState
hook.
const [state, setState, stateRef] = useSuperState(/* Initial state */ 0)
const [state, setState, stateRef] = useSuperState(/* Initial state creator - run only once */ () => 0)
Or you can pass a factory function and a list of dependencies as you would do with the useMemo
hook.
The state will be changed either by using setState
or from outside when the list of dependencies changes.
Note: You have access to the previous state by the parameter passed to the factory function.
const [state, setState, stateRef] = useSuperState(
// State factory - run if the dependency list changed
prevState => (prevState || 0) + props.count,
// Dependency list
[props.count]
)
useBindState
Bind a state to an outside value.
When the outside value changes, the state will be updated with the new value.
Returns a stateful value and function to update it + ref to the state value.
Definition
<S>(value: S): [S, Dispatch<SetStateAction<S>>, MutableRefObject<S>]
usage
The outsideValue
will create the initial state, and will also update the state when it changes.
const [state, setState, stateRef] = useBindState(outsideValue)
Callback
useSameCallback
This hook is just like the useCallback
hook with an empty array. This means that the callback will not change during the life of the component.
Returns a reference to the initial passed callback.
Definition
<T extends (...args: any[]) => any>(callback: T): T
usage
const onClick = useSameCallback(() => console.log(exampleRef.current))
Ref
useSuperRef
Use a ref with super powers.
This hook is like a combination of useMemo
and useRef
hooks at once.
Returns a value, and a ref to the value.
Definition
<V>(factory: V | ((prev: V) => V), deps?: DependencyList): [V, MutableRefObject<V>]
Usage
You can use it as you normally do with the useRef
hook.
const [value, valueRef] = useSuperRef()
const [value, valueRef] = useSuperRef(/* Initial value */ 0)
Or you can pass an initializer function.
const [value, valueRef] = useSuperRef(/* Initial value creator - only runs once */ () => 0)
Or you can pass a factory function and a list of dependencies as you would do with the useMemo
hook.
The value will be changed either by using useRef.current
or from outside when the list of dependencies changes.
Note: You have access to the previous value by the parameter passed to the factory function.
const [value, valueRef] = useSuperRef(
// ref value factory - run if the dependency list changed
prevValue => (prevValue || 0) + props.count,
// Dependency list
[props.count]
)
useBindRef
Bind a ref to an outside value.
When the outside value changes, the ref value will be updated to the new value.
Returns the ref object.
Definition
<V>(value: V): MutableRefObject<V>
usage
The outsideValue
value will be the initial ref value and will also update the ref value when it changes.
const myRef = useBindRef(outsideValue)
useInnerRef
Convert forwardedRef
to a new regular React
ref object.
Useful when using forwardedRef
and you want to use the ref as a regular ref within the component as well.
Returns the ref object.
Definition
<T>(ref: ForwardedRef<T>): MutableRefObject<T>
usage
const ExampleComp = forwardedRef((props, ref)=> {
const innerRef = useInnerRef(ref)
useEffect(
()=> console.log(innerRef.current),
[innerRef.current]
)
return <div ref={innerRef}></div>
})
Lifecycles
useInitial
Use the initial value returned by the create function, which is invoked when the component initialized.
This hook is basically a substitute for the behavior of the constructor in the class components.
Returns the initial value.
Definition
<V>(create: () => V) => V
usage
const id = useInitial(() => Math.random())
useRun
This hook will run immediately if the dependency list changes.
The main difference between this hook and the React
lifecycles hooks is: this hook is called immediately but the useEffect
hook for example run after processing the component.
Returns an isFirstRun indicator.
Definition
(callback: () => void, deps: DependencyList): { isFirstRun: boolean, isFirstRunRef: MutableRefObject<boolean> }
usage
const ExampleComp = props => {
const myRef = useRef(5)
useRun(() => myRef.current += props.count, [props.count])
return myRef.current > 10 && <div>Hello World!</div>
}
You also have additional data returns that can be useful in some cases.
const { isFirstRun, isFirstRunRef } = useRun(() => console.log(`Dependencies change`), [...someDeps])
useAsyncEffect
This hook is a modified version of React
useEffect
hook that adds a nice support for async callback effect.
You can achieve the same cleanup behavior as the native useEffect
by accessing the effect argument and passing to it a callback. Note: You should call it above any async operation.
Note: Use useLayoutAsyncEffect
for the layout effect version.
Definition
(effect: (onCleanup: (execute: () => void | Promise<void>) => void) => Promise<void>, deps?: DependencyList): void
usage
useAsyncEffect(
async () => {
const user = await myApi.get('./user')
setData(user)
},
[]
)
With cleanup:
useAsyncEffect(
async (onCleanup)=> {
const ac = new AbortController()
// Call onCleanup above any async operation
onCleanup(
// cleanup callback
() => ac.abort()
)
const res = await fetch('./my-api', { signal: ac.signal })
const data = await res.json()
setData(data)
// onCleanup(() => ac.abort()) -> This is NOT OK!
},
[someDep]
)
useOrderedAsync
This hook is like useAsyncEffect
but it waits for the previous effect to end before the next effect starts.
Note: Use useLayoutOrderedAsync
for the layout effect version.
usage
useOrderedAsync(
async () => {
const users = await myApi.get(`./users?q=${searchValue}`)
setData(users)
},
[searchValue]
)
useBounceAsync
This hook is like useOrderedAsync
but it will skip the effect if a new effect arrives.
Note: Use useLayoutBounceAsync
for the layout effect version.
usage
useBounceAsync(
async () => {
const users = await myApi.get(`./users?q=${searchValue}`)
setData(users)
},
[searchValue]
)
useIf
Run a effect callback when the first parameter is truthy.
Note: The Effect Callback can have a React
useEffect
Callback signature, or a useAsyncEffect
Callback signature.
Note: Use useLayoutIf
for the layout effect version.
Definition
(condition: unknown, callback: EffectCallback): boolean
usage
Except a React
useEffect
callback.
useIf(someValue === otherValue, () => {
console.log(`It is equal`)
// Cleanup
return () => console.log(`Cleaned up`)
})
useAsyncEffect
callback also will work.
useIf(someValue === otherValue, async onCleanup => {
onCleanup(() => console.log(`Cleaned up`)) // Always put it above any async operation.
const data = await api.send(`It is equal`)
console.log(data)
})
useMount
Run a callback when the component is mounted.
Note: The Effect Callback can have a React
useEffect
Callback signature, or a useAsyncEffect
Callback signature.
Note: Use useLayoutMount
for the layout effect version.
Definition
(callback: EffectCallback): void
usage
Except a React
useEffect
callback.
useMount(() => {
console.log(`It is equal`)
// Cleanup
return () => console.log(`Cleaned up`)
})
Callback signature for useAsyncEffect
should also will work.
useMount(async onCleanup => {
onCleanup(() => console.log(`Cleaned up`)) // Always put it above any async operation.
const data = await api.send(`It is equal`)
console.log(data)
})
useIsMount
Get to know the component current mounted state.
Returns a boolean and a ref to the boolean.
Definition
(): [boolean, MutableRefObject<boolean>]
usage
const [isMount, isMountRef] = useIsMount()
useUnmount
Run a callback when the component is unmounted.
Returns the callback that get passed.
Definition
<C extends (()=> void | Promise<void>>)>(callback: C): C
usage
useUnmount(() => console.log(`Component unmounted`))
useUnmount(() => someSubscription.unsubscribe())
useRender
Give you a option to force the component to be render.
Returns a render function that can be invoked to render the component when you need so.
Definition
(): () => void
usage
const render = useRender()
useEffect(() => render(), [...someDeps]) // the component will render when the deps get changed.
Dom
useClassName
Join lists of dom element className to be one className string, and memoized it depending on dependency list.
Returns a string represents the combination of all className in the array list.
Definition
(factory: () => Array<string>, deps: DependencyList): string
usage
const myClassName = useClassName(
// Define a factory that returns array of classNames
() => [
`flex black`,
someCondition && `some-class other-class`,
secondCondition ? `new-class-list`: ``
],
// List of dependencies go here
[someCondition, secondCondition]
)
<div className={myClassName}>Hello world</div>
useStyle
Create style and memoized it depending on dependency list.
Returns the created style object, ready for use as a property of html element.
Definition
(factory: () => CSSProperties, deps: DependencyList): CSSProperties
usage
const myStyle = useStyle(
// Define a Factory that returns style object
() => ({
backgroundColor: someCondition && `black`,
color: someCondition ? `white`: `black`
}),
// List of dependencies go here
[someCondition]
)
<div style={myStyle}>Hello world</div>
useHover
Get a sense when a element dom get hovered.
Note: You can disabled the hook functionality by passing false
to the enabled option.
Note: If you don't pass ref to the element by using the ref option, an ref will be created for you.
Returns a boolean represents the truthiness of the element hover state, and a ref to the element.
Definition
<T extends HTMLElement>({ ref, enabled }?: { ref?: MutableRefObject<T>, enabled?: boolean }): [boolean, MutableRefObject<T>]
usage
const [isHover, btnRef] = useHover()
<button ref={btnRef}>Hover Me</button>
You have also some options you can pass to the hook.
Here is an example of using pre created ref.
const btnRef = useRef()
const [isHover] = useHover({ ref: btnRef })
Also you can disabled the hover functionality and logic if you don`t need it right now.
Note: The default value for the enabled option is true
.
const isMobile = true
const [isHover, btnRef] = useHover({ enabled: !isMobile })
Timer
useTimeout
Use a callback on amount of time after the dependency list changes.
Note: If you don't pass an dependency list, the effect will stop and rerun after every completed render.
Note: This hook used requestAnimationFrame
behind the scenes, for performance reason.
Note: Use useLayoutTimeout
for the layout effect version.
Returns a ref to the current result of requestAnimationFrame
call.
Definition
(callback: () => void, ms?: number, deps?: DependencyList): MutableRefObject<number>
usage
const handleRef = useTimeout(
/* callback */
() => console.log(`DependencyList changes`),
/* milliseconds */
1000,
/* Dependency List */
[...someDeps]
)
And you can cancel the requestAnimationFrame
like so.
cancelAnimationFrame(handleRef.current)
useInterval
Restart a interval on amount of time after the dependency list changes.
Note: If you don't pass an dependency list, the effect will rerun after every completed render.
Note: This hook used requestAnimationFrame
behind the scenes, for performance reason.
Note: Use useLayoutInterval
for the layout effect version.
Returns a ref to the current result of requestAnimationFrame
call.
Definition
(callback: () => void, ms?: number, deps?: DependencyList): MutableRefObject<number>
usage
const handleRef = useInterval(
/* callback */
() => console.log(`DependencyList changes`),
/* milliseconds */
1000,
/* DependencyList */
[...someDeps]
)
And you can cancel the requestAnimationFrame
like so.
cancelAnimationFrame(handleRef.current)
Logger
useLog
Log when parameters changed.
Returns a list holding the parameters that get passed.
Definition
<T>(...params: T): T
usage
useLog(props.count, props.className)
// Log to the console a list with the current value of the parameters
If you pass only one object parameter, it will compares the object deeply for tracking a changes and log the new object to the console.
useLog({ count: props.count, myState: state })
// Log the object when one of the properties changed.