React Use Hooks Collection
react-use is a comprehensive, open-source collection of over 80 essential React Hooks, offering a wide array of utilities for managing state, effects, browser APIs, and sensor data. It aims to simplify common patterns and reduce boilerplate in React applications, providing modular and reusable solutions for tasks such as tracking window size, battery status, geolocation, and various input events. The library is actively maintained, with its current stable version being 17.6.0 (released December 2024), and demonstrates a frequent release cadence, often pushing minor updates and bug fixes multiple times a year. Its key differentiators include the sheer volume and diversity of well-documented hooks, strong TypeScript support, and a focus on abstracting complex browser APIs into simple hook interfaces. It originated as a port from the `libreact` library.
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-use` hook outside of a React functional component or a custom hook, violating the Rules of Hooks.fixEnsure all calls to `use*` functions adhere to the Rules of Hooks by being placed at the top level of React function components or custom hooks. -
TypeError: (0, react_use__WEBPACK_IMPORTED_MODULE_2__.useSomeHook) is not a function
cause This error typically occurs when attempting to import hooks using CommonJS `require()` syntax or an incorrect named import in an environment expecting ES modules, or if tree-shaking removed the export unexpectedly.fixAlways use ES module named import syntax: `import { useSomeHook } from 'react-use';`. Verify your build configuration supports ES modules correctly. -
Type 'FC<Props>' is not assignable to type 'FunctionComponent<Props>'
cause This TypeScript error indicates a compatibility issue between an older version of `react-use` and `@types/react` v18 or newer, where the generic type argument for `React.FC` was deprecated.fixUpgrade `react-use` to version 17.3.3 or newer to get the necessary type definition updates compatible with `@types/react` v18.
Warnings
- breaking When upgrading your project's `@types/react` to v18 (or newer), you may encounter TypeScript compilation errors related to `React.FC` (FunctionComponent) type arguments. Specifically, `React.FC` no longer accepts a generic type parameter in `@types/react` v18.
- gotcha Hooks relying on browser-specific APIs (e.g., `useMedia`, `useWindowSize`, `useGeolocation`) can cause hydration mismatches or errors when used in Server-Side Rendering (SSR) environments if their initial state is not handled correctly or doesn't match the client-side render.
- gotcha Incorrectly resolved `react` and `react-dom` peer dependencies can lead to runtime errors or multiple instances of React, causing unpredictable behavior. This can occur if your project's React version doesn't satisfy `react-use`'s peer dependency range.
Install
-
npm install react-use -
yarn add react-use -
pnpm add react-use
Imports
- useWindowSize
const { useWindowSize } = require('react-use');import { useWindowSize } from 'react-use'; - useBattery
import useBattery from 'react-use';
import { useBattery } from 'react-use'; - useToggle
import * as ReactUse from 'react-use'; // then ReactUse.useToggle
import { useToggle } from 'react-use'; - useStateList
import { useStateList } from 'react-use';
Quickstart
import React from 'react';
import { useWindowSize, useBattery, useToggle } from 'react-use';
const App = () => {
const { width, height } = useWindowSize();
const batteryState = useBattery();
const [isVisible, toggleVisibility] = useToggle(true);
return (
<div style={{ padding: '20px', fontFamily: 'sans-serif' }}>
<h1>react-use Quickstart</h1>
<p>Window Size: {width}px x {height}px</p>
{batteryState.isSupported ? (
<p>
Battery Level: {((batteryState.level ?? 0) * 100).toFixed(0)}%
{batteryState.charging ? ' (Charging)' : ' (Discharging)'}
</p>
) : (
<p>Battery status not supported on this device.</p>
)}
<button onClick={() => toggleVisibility()} style={{ marginTop: '15px', padding: '8px 12px', cursor: 'pointer' }}>
{isVisible ? 'Hide' : 'Show'} Toggled Content
</button>
{isVisible && (
<div style={{ marginTop: '15px', border: '1px dashed #ccc', padding: '10px', borderRadius: '4px' }}>
<p>This content is toggled!</p>
<p>Current Time: {new Date().toLocaleTimeString()}</p>
</div>
)}
</div>
);
};
export default App;