React Haiku Hooks & Utilities
React Haiku is a lightweight utility library offering a comprehensive collection of React Hooks and utility components designed to streamline development and enhance efficiency. Currently at version 2.4.1, the library maintains an active release cadence, frequently adding new hooks and improving existing ones, as evidenced by multiple minor releases and updates in recent months. Its primary goal is to provide developers with ready-to-use solutions for common React patterns, such as state management, DOM manipulation, and browser API interactions, thereby saving development time. Key differentiators include its focus on being a "clean & lightweight" collection, providing a wide array of specialized hooks like `useHover`, `useBatteryStatus`, `useCookie`, and utility components like `<For />` and `<Switch />`, all while shipping with TypeScript types for improved developer experience. It requires React version 16.8.0 or newer.
Common errors
-
Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
cause Attempting to call a `react-haiku` hook (e.g., `useHover`, `useToggle`) outside of a React function component or a custom hook.fixEnsure all calls to `react-haiku` hooks are made directly within the body of a React function component, or within another custom hook which itself is called from a function component. -
TypeError: Cannot read properties of undefined (reading 'name')
cause The `each` prop passed to the `<For />` utility component is `undefined` or `null`, when it expects an iterable array.fixEnsure that the `each` prop provided to the `<For />` component is always an array, even if empty. Initialize `list` variables with `[]` to prevent `undefined` values, e.g., `<For each={list || []} ... />`. -
TS2345: Argument of type 'string | null' is not assignable to parameter of type 'string'. Type 'null' is not assignable to type 'string'.
cause Using a hook like `useCookie` which returns `string | null` (if the cookie isn't found) where a `string` is strictly expected by another function or component without handling the `null` case.fixCheck for `null` values explicitly before using the returned cookie value, or provide a default fallback. For example: `const [value] = useCookie('my_cookie'); const displayValue = value ?? 'Default';`
Warnings
- gotcha Many hooks in `react-haiku` (e.g., `useBatteryStatus`, `useNetwork`, `usePreventBodyScroll`, `useCookie`) directly interact with browser-specific APIs. These hooks will likely cause issues or fail silently when used in Server-Side Rendering (SSR) environments like Next.js or Remix without proper client-side checks.
- gotcha When using hooks like `useEventListener` or `useInterval`, ensure that any callback functions passed to them are stable. If a callback function is recreated on every render and included in the hook's dependencies, it can lead to unnecessary re-registrations or unexpected behavior.
- gotcha The `useInputValue` hook, as noted in `v2.3.0`, uses an `as const` assertion on its return type. While this improves type inference for TypeScript users, it means the tuple elements are strictly typed and cannot be reassigned or modified in ways that deviate from their inferred literal types without explicit casting, which might be a surprise for some.
Install
-
npm install react-haiku -
yarn add react-haiku -
pnpm add react-haiku
Imports
- useHover
const { useHover } = require('react-haiku');import { useHover } from 'react-haiku'; - For
import For from 'react-haiku';
import { For } from 'react-haiku'; - useToggle
import { useToggle } from 'react-haiku';
Quickstart
import React from 'react';
import { useHover, useTitle, useCookie } from 'react-haiku';
// Example 1: useHover hook
const HoverComponent = () => {
const { hovered, ref } = useHover();
return (
<div ref={ref} style={{ padding: '20px', border: '1px solid gray', marginBottom: '20px' }}>
<p>{hovered ? 'Mouse is hovering over me!' : 'Hover over me'}</p>
</div>
);
};
// Example 2: useTitle hook
const TitleUpdater = () => {
const [currentTitle, setTitle] = React.useState('Haiku App');
useTitle(currentTitle);
return (
<button onClick={() => setTitle(`Haiku Title: ${Math.random().toFixed(2)}`)}>
Change Page Title
</button>
);
};
// Example 3: useCookie hook
const CookieManager = () => {
const [value, updateCookie, deleteCookie] = useCookie('my_haiku_cookie', 'initial_value');
return (
<div style={{ marginTop: '20px' }}>
<p>Cookie "my_haiku_cookie": {value ?? 'Not set'}</p>
<button onClick={() => updateCookie(`new_value_${Date.now()}`)}>Update Cookie</button>
<button onClick={deleteCookie} style={{ marginLeft: '10px' }}>Delete Cookie</button>
</div>
);
};
const App = () => {
return (
<div>
<h1>React Haiku Examples</h1>
<HoverComponent />
<TitleUpdater />
<CookieManager />
</div>
);
};
export default App;