{"id":11714,"library":"react-haiku","title":"React Haiku Hooks & Utilities","description":"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.","status":"active","version":"2.4.1","language":"javascript","source_language":"en","source_url":"https://github.com/DavidHDev/react-haiku","tags":["javascript","reactjs","react","utility","components","hooks","state","frontend","typescript"],"install":[{"cmd":"npm install react-haiku","lang":"bash","label":"npm"},{"cmd":"yarn add react-haiku","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-haiku","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"react-haiku provides custom hooks and components that depend on React's core functionalities, requiring React to be installed as a peer dependency.","package":"react","optional":false}],"imports":[{"note":"Most modern React libraries, including react-haiku, are designed for ESM imports. CommonJS `require` is not officially supported and may lead to issues.","wrong":"const { useHover } = require('react-haiku');","symbol":"useHover","correct":"import { useHover } from 'react-haiku';"},{"note":"The `For` utility is a named export, not a default export. Ensure you use curly braces for named imports.","wrong":"import For from 'react-haiku';","symbol":"For","correct":"import { For } from 'react-haiku';"},{"note":"The library ships with TypeScript types, providing type safety for hook inputs and return values automatically when used in a TypeScript project.","symbol":"useToggle","correct":"import { useToggle } from 'react-haiku';"}],"quickstart":{"code":"import React from 'react';\nimport { useHover, useTitle, useCookie } from 'react-haiku';\n\n// Example 1: useHover hook\nconst HoverComponent = () => {\n  const { hovered, ref } = useHover();\n  return (\n    <div ref={ref} style={{ padding: '20px', border: '1px solid gray', marginBottom: '20px' }}>\n      <p>{hovered ? 'Mouse is hovering over me!' : 'Hover over me'}</p>\n    </div>\n  );\n};\n\n// Example 2: useTitle hook\nconst TitleUpdater = () => {\n  const [currentTitle, setTitle] = React.useState('Haiku App');\n  useTitle(currentTitle);\n  return (\n    <button onClick={() => setTitle(`Haiku Title: ${Math.random().toFixed(2)}`)}>\n      Change Page Title\n    </button>\n  );\n};\n\n// Example 3: useCookie hook\nconst CookieManager = () => {\n  const [value, updateCookie, deleteCookie] = useCookie('my_haiku_cookie', 'initial_value');\n\n  return (\n    <div style={{ marginTop: '20px' }}>\n      <p>Cookie \"my_haiku_cookie\": {value ?? 'Not set'}</p>\n      <button onClick={() => updateCookie(`new_value_${Date.now()}`)}>Update Cookie</button>\n      <button onClick={deleteCookie} style={{ marginLeft: '10px' }}>Delete Cookie</button>\n    </div>\n  );\n};\n\nconst App = () => {\n  return (\n    <div>\n      <h1>React Haiku Examples</h1>\n      <HoverComponent />\n      <TitleUpdater />\n      <CookieManager />\n    </div>\n  );\n};\n\nexport default App;\n","lang":"typescript","description":"Demonstrates common usage patterns for `useHover`, `useTitle`, and `useCookie` hooks within a React component, showcasing state management and side effects."},"warnings":[{"fix":"Implement client-side only rendering for components utilizing browser-API-dependent hooks, or wrap their usage within `typeof window !== 'undefined'` checks. For Next.js, consider `dynamic(() => import('...'), { ssr: false })`.","message":"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.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Wrap callback functions that are passed to `useEventListener`, `useInterval`, or similar hooks with `React.useCallback` to memoize them. This prevents unnecessary re-creations and ensures the hook's internal logic can correctly manage event listeners or timers.","message":"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.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Be aware of the strict typing when destructuring `useInputValue`. If mutable variables are needed, copy the values or explicitly cast them. For most usage patterns with input values, this `as const` assertion enhances type safety by preventing incorrect reassignments.","message":"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.","severity":"gotcha","affected_versions":">=2.3.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure 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.","cause":"Attempting to call a `react-haiku` hook (e.g., `useHover`, `useToggle`) outside of a React function component or a custom hook.","error":"Error: Invalid hook call. Hooks can only be called inside of the body of a function component."},{"fix":"Ensure 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 || []} ... />`.","cause":"The `each` prop passed to the `<For />` utility component is `undefined` or `null`, when it expects an iterable array.","error":"TypeError: Cannot read properties of undefined (reading 'name')"},{"fix":"Check 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';`","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.","error":"TS2345: Argument of type 'string | null' is not assignable to parameter of type 'string'. Type 'null' is not assignable to type 'string'."}],"ecosystem":"npm"}