@rennalabs/hooks
v1.4.0
Published
A library of useful hooks.
Downloads
4
Maintainers
Readme
Renna Labs' Hooks
A library of react hooks for state and UI management.
Install
Note: React 16.8+ is required for Hooks.
With npm
npm i @rennalabs/hooks --save
Or with yarn
yarn add @rennalabs/hooks
API
useNetworkStatus()
useWindowScrollPosition()
useWindowSize()
useLocalStorage()
useOnClickOutside()
useMediaQuery()
usePrefersReducedMotion()
useTimeout()
useInterval()
useRandomInterval()
useCounter()
useHover()
useOs()
useMousePosition()
useFullscreen()
useIdle()
useCookie()
useDocumentTitle()
useDocumentVisibility()
useGeolocation()
useIsomorphicEffect()
useWindowEvent()
useFavicon()
useDidUpdate()
useLogger()
Hooks
useNetworkStatus()
Retrieve network status from the browser.
Returns
Object containing:
isOnline: boolean
:true
if the browser has network access.false
otherwise.offlineAt?: Date
: Date when network connection was lost.
Example
import { useNetworkStatus } from '@rennalabs/hooks';
const Example = () => {
const { isOnline, offlineAt } = useNetworkStatus();
return (
<div style={{ background: isOnline ? 'green' : 'red' }}>
{`App went offline at ${offlineAt.toString()}`}
</div>
);
};
useWindowScrollPosition()
Returns
Object containing:
x: number
: Horizontal scroll in pixels (window.pageXOffset
).y: number
: Vertical scroll in pixels (window.pageYOffset
).
Example
import { useWindowScrollPosition } from '@rennalabs/hooks';
const Example = () => {
const { x, y } = useWindowScrollPosition();
return <div>{`Scroll position is { x: ${x}, y: ${y} }`}</div>;
};
useWindowSize()
Returns
Object containing:
width
: Width of browser viewport (window.innerWidth
)height
: Height of browser viewport (window.innerHeight
)
Example
import { useWindowSize } from '@rennalabs/hooks';
const Example = () => {
const { width, height } = useWindowSize();
return <div>{`window size is ${width}x${height}`}</div>;
};
useLocalStorage()
Allows you to use value from localStorage as react state. Hook works the same way as useState, but also writes the value to localStorage. Subscribes to the storage
event. When state changes in one tab, it automatically updates value in all other opened browser tabs.
Arguments
key: string
: Key to the value in local storagedefaultValue: string
: Default value for the provided key
Returns
Array containing:
value: string
: Value to the key in localStorage.setValue: function
: Setter function to the provided keyremoveValue: function
: Callback to remove key/value from localStorage
Example
import { useLocalStorage } from '@rennalabs/hooks';
const Example = () => {
// Similar to useState but first arg is key
// to the value in local storage.
const [value, setValue, removeValue] = useLocalStorage('keyName', 'keyValue');
return (
<div>
<h1>{`Saved value: ${value}`}</h1>
<input onChange={e => setValue(e.target.value)} />
<button onClick={removeValue}>Clear Storage</button>
</div>
);
};
useOnClickOutside()
Detects click and touch events outside of specified element and fires given callback function.
Arguments
handler: function
: function that will be called on outside click.events?: string[]
: optional list of events that indicate outside click.nodes?: HTMLElement[]
: optional list of nodes that should not trigger outside click event.
Returns
ref
: React ref object that should be passed to element on which outside clicks should be captured.
Example
import { useState } from 'react';
import { useOnClickOutside } from '@rennalabs/hooks';
function Demo() {
const [opened, setOpened] = useState(false);
const ref = useOnClickOutside(() => setOpened(false));
return (
<>
<button onClick={() => setOpened(true)}>Open dropdown</button>
{opened && (
<DropDown ref={ref}>
<span>Click outside to close</span>
</DropDown>
)}
</>
);
}
Example with Events
import { useState } from 'react';
import { useOnClickOutside } from '@rennalabs/hooks';
function Demo() {
const [opened, setOpened] = useState(false);
const ref = useClickOutside(() => setOpened(false), ['mouseup', 'touchend']);
return (
<>
<button onClick={() => setOpened(true)}>Open dropdown</button>
{opened && (
<DropDown ref={ref}>
<span>Click outside to close</span>
</DropDown>
)}
</>
);
}
Example with nodes
import { useState } from 'react';
import { useOnClickOutside } from '@rennalabs/hooks';
function Demo() {
const [dropdown, setDropdown] = useState(null);
const [control, setControl] = useState(null);
useClickOutside(() => console.log('clicked outside'), null, [control, dropdown]);
return (
<div>
<div ref={setControl}>Control</div>
<div>
<div ref={setDropdown}>Dropdown</div>
</div>
</div>
);
}
useMediaQuery()
Accepts a media query string then uses the matchMedia API to determine if it matches with the current document.
Arguments
mediaQuery: string
Returns
match: boolean
Example
import { useMediaQuery } from '@rennalabs/hooks';
const Example = () => {
const isSmall = useMediaQuery('(max-width: 48rem)');
const isLarge = useMediaQuery('(min-width: 48rem)');
return (
<Demo>
<p>Small view? {isSmall ? 'yes' : 'no'}</p>
<p>Large view? {isLarge ? 'yes' : 'no'}</p>
</Demo>
);
};
usePrefersReducedMotion()
A hook to allow access to the CSS media query prefers-reduced-motion
.
Returns
match: boolean
Example
import { usePrefersReducedMotion } from '@rennalabs/hooks';
const Example = ({ isBig }) => {
const prefersReducedMotion = usePrefersReducedMotion();
const styles = {
transform: isBig ? 'scale(2)' : 'scale(1)',
transition: prefersReducedMotion ? undefined : 'transform 300ms',
};
return <Demo styles={styles}>Stuff</Demo>;
};
useTimeout()
A declarative adaptation of setTimeout
based on Dan Abramov's blog post about setInterval
Arguments
callback: function
delay: number
Example
import { useTimeout } from '@rennalabs/hooks';
function Example() {
const [message, setMessage] = useState('changing in 2 seconds...');
useTimeout(() => setMessage('changed!'), 2000);
return <Demo>{message}</Demo>;
}
useInterval()
A hook wrapper around window.setInterval
Arguments
callback: function
delay: number
Returns
Object containing:
start: function
stop: function
toggle: function
active: boolean
Example
import { useState, useEffect } from 'react';
import { useInterval } from '@rennalabs/hooks';
function Demo() {
const [seconds, setSeconds] = useState(0);
const interval = useInterval(() => setSeconds(s => s + 1), 1000);
useEffect(() => {
interval.start();
return interval.stop;
}, []);
return (
<div>
<h1>
Page loaded <b>{seconds}</b> seconds ago
</h1>
<button onClick={interval.toggle} style={{ color: interval.active ? 'red' : 'green' }}>
{interval.active ? 'Stop' : 'Start'} counting
</button>
</div>
);
}
useRandomInterval()
A hook itended for animations and microinteractions that fire on a spontaneous interval.
Arguments
callback: function
minDelay?: number
maxDelay?: number
Returns
interval: number
: Randomized interval between given min and max delay.
Example
import { useState, useEffect } from 'react';
import { useRandomInterval } from '@rennalabs/hooks';
function LaggyTimer() {
// Update between every 1 and 4 seconds
const delay = [1000, 4000];
const [seconds, setSeconds] = useState(0);
const interval = useRandomInterval(() => setSeconds(s => s + 1), ...delay);
useEffect(() => {
interval.start();
return interval.stop;
}, []);
return (
<div>
<h1>It has been {seconds} seconds.</h1>
<button onClick={interval.toggle} style={{ color: interval.active ? 'red' : 'green' }}>
{interval.active ? 'Stop' : 'Start'} counting
</button>
</div>
);
}
useCounter()
Increment/decrement state within given boundaries.
Arguments
initialCount: number
clamp: { min: number; max: number; }
Returns
Array containing
count: number
handlers: object
: functions to increment, decrement, reset, and set counter.
Example
import { useCounter } from '@rennalabs/hooks';
function Demo() {
const [count, handlers] = useCounter(0, { min: 0, max: 10 });
return (
<>
<h1>Count: {count}</h1>
<div>
<button onClick={handlers.increment}>Increment</button>
<button onClick={handlers.decrement}>Decrement</button>
<button onClick={handlers.reset}>Reset</button>
<button onClick={() => handlers.set(5)}>Set 5</button>
</div>
</>
);
}
useHover()
Detect if mouse is over given element.
Returns
Object containing
hovered: boolean
: Element's hover state.ref: object
: React ref object to attach to element.
Example
import { useHover } from '@rennalabs/hooks';
function Demo() {
const { hovered, ref } = useHover();
return <div ref={ref}>{hovered ? 'I am hovered' : 'Hover over me please'}</div>;
}
useOs()
useOs detects user's operating system. Possible values are: undetermined, macos, ios, windows, android, linux. If os cannot be identified, for example, during server side rendering undetermined will be returned.
Returns
os: undetermined | macos | ios | windows | android | linux
Example
import { useOs } from '@rennalabs/hooks';
function Demo() {
const os = useOs();
return (
<>
Your operating system is <b>{os}</b>
</>
);
}
useMousePosition()
Get mouse position relative to viewport or given element.
Returns
Object containing
ref: object
: React ref object to attach to element.x: number
: X coordinate of element.y: number
: Y coordinate of element.
Example
import { useMousePosition } from '@rennalabs/hooks';
function Demo() {
const { ref, x, y } = useMousePosition();
return (
<>
Mouse coordinates are <b>{`{ x: ${x}, y: ${y} }`}</b>
</>
);
}
useFullscreen()
useFullscreen allows to enter/exit fullscreen for given element using the Fullscreen API. By default, if you don't provide ref, hook will target document.documentElement:
Returns
Object containing:
toggle: function
: Function to toggle fullscreen.fullscreen: boolean
: Fullscreen status.ref: object
: React ref object to attach to custom element to make fullscreen.
Example
import { useFullscreen } from '@rennalabs/hooks';
function Demo() {
const { toggle, fullscreen } = useFullscreen();
return (
<button onClick={toggle} style={{ color: fullscreen ? 'red' : 'green' }}>
{fullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'}
</button>
);
}
Example with custom element
import { useFullscreen } from '@rennalabs/hooks';
function Demo() {
const { ref, toggle, fullscreen } = useFullscreen();
return (
<>
<img
ref={ref}
src="https://unsplash.com/image.jpg"
alt="Unsplash Image to make Fullscreen"
width={200}
/>
<button onClick={toggle} style={{ color: fullscreen ? 'red' : 'green' }}>
{fullscreen ? 'Exit Fullscreen' : 'View Image Fullscreen'}
</button>
</>
);
}
useIdle()
Detects if user does nothing for given time in ms:
Arguments
idleCount: number
: number of ms to determine if user is idle.
Returns
idle: boolean
: Is user idle.
Example
import { useIdle } from '@rennalabs/hooks';
function Demo() {
const idle = useIdle(2000);
return <div>Current state: {idle ? 'idle' : 'not idle'}</div>;
}
useCookie()
React hook wrapper for js-cookie
Arguments
key: string
: Name of cookie.
Returns
Array containing
value: any
: Current value of cookie.updateCookie: function
: Callback to update the cookie.deleteCookie: function
: Callback to delete the cookie.
Example
import { useCookie } from '@rennalabs/hooks';
function Demo() {
const [value, updateCookie, deleteCookie] = useCookie('my-cookie');
const updateCookieHandler = () => {
updateCookie('new-cookie-value');
};
return (
<div>
<p>Value: {value}</p>
<button onClick={updateCookieHandler}>Update Cookie</button>
<button onClick={deleteCookie}>Delete Cookie</button>
</div>
);
}
useDocumentTitle()
Sets document.title property with React's useLayoutEffect hook. Hook is not called during server side rendering. Use this hook with client only applications. Call hook with string that should be set as document title inside any component. Hook is triggered every time value changes and value is not empty string (trailing whitespace is trimmed) or null.
Arguments
title: string
Example
import { useState } from 'react';
import { useDocumentTitle } from '@rennalabs/hooks';
function Demo() {
const [title, setTitle] = useState('');
useDocumentTitle(title);
return <button onClick={() => setTitle('new title')}>Set document title</button>;
}
useDocumentVisibility()
Returns current document.visibilityState – it allows to detect if current tab is active.
Returns
documentState: visible | hidden
Example
import { useDocumentTitle, useDocumentVisibility } from '@rennalabs/hooks';
function Demo() {
const documentState = useDocumentVisibility();
useDocumentTitle(`Document is ${documentState}`);
return <div>Switch to another tab to see document title change</div>;
}
useGeolocation()
Returns user's geographic location. This hook accepts position options.
Arguments
options?: PositionOptions
Returns
Object containing:
loading: boolean
accuracy: number | null
altitude: number | null
altitudeAccuracy: number | null
heading: number | null
latitude: number | null
longitude: number | null
speed: number | null
timestamp: number | null
error?: Error
Example
import { useGeolocation } from '@rennalabs/hooks';
function Demo() {
const { loading, error, latitude, longitude } = useGeolocation();
if (loading) return 'loading...';
if (error) return 'error';
return (
<div>
Your location is {latitude} x {longitude}
</div>
);
}
useIsomorphicEffect()
Allows you to switch between useEffect during server side rendering and useLayoutEffect after hydration. Use it wherever you would use useLayoutEffect to avoid warnings during ssr.
Arguments
callback: function
dependencies?: any[]
Example
import { useIsomorphicEffect } from '@rennalabs/hooks';
function Demo() {
useIsomorphicEffect(() => {
document.title = 'title';
});
return null;
}
useWindowEvent()
Adds an event listener to window
object on component mount and removes it on unmount:
Arguments
key: string
: Any type found in WindowEventMapcallback: function
: Handler function to pass to event listener.
Example
import { useEffect } from 'react';
import { useWindowEvent } from '@rennalabs/hooks';
const handler = event => console.log(event);
// regular way
useEffect(() => {
window.addEventListener('keydown', handler);
return () => window.removeEventListener('keydown', handler);
}, []);
// with useWindowEvent hook
useWindowEvent('keydown', handler);
useFavicon()
Appends a <link />
element to head component with given favicon in React.useLayoutEffect
hook. Hook is not called during server side rendering.
Arguments
url: string
: Favicon url (supported formats:.ico
,.png
,.svg
and.gif
). Hook is triggered every time url changes and value is not empty string (trailing whitespace is trimmed) or null.
Example
import { useState } from 'react';
import { useFavicon } from '@rennalabs/hooks';
function Demo() {
const [favicon, setFavicon] = useState('https://rennalabs.xyz/favicon.ico');
const setTwitterFavicon = () => setFavicon('https://twitter.com/favicon.ico');
const setRennaLabsFavicon = () => setFavicon('https://rennalabs.xyz/favicon.ico');
useFavicon(favicon);
return (
<div>
<button onClick={setTwitterFavicon}>Twitter favicon</button>
<button onClick={setRennaLabsFavicon}>Renna Labs favicon</button>
</div>
);
}
useDidUpdate()
Calls a given callback function when the component updates but not on the initial mount.
Arguments
fn: function
: Callback to be fired on updatedependencies: any[]
: useEffect dependencies to watch for updates
Example
useDidUpdate(() => console.log("Won't be called when mounted"), [value]);
useLogger()
Logs given values to console each time component renders, do not use in production.
Arguments
name: string
: Component nameprops: any[]
: Array of props to log on update
Example
import { useState } from 'react';
import { useLogger } from '@rennalabs/hooks';
function Demo() {
const [count, setCount] = useState(0);
useLogger('Demo', [{ count, hello: 'world' }]);
return <button onClick={() => setCount(c => c + 1)}>Update state ({count})</button>;
}
MIT License