atechhub-use-mounted
Version:
A React hook to track component mounted state
155 lines (110 loc) • 3.52 kB
Markdown
# useMounted Hook
A lightweight React hook to track component mounted state and prevent memory leaks.
## Installation
```bash
npm install atechhub-use-mounted
# or
yarn add atechhub-use-mounted
# or
pnpm add atechhub-use-mounted
# or
bun add atechhub-use-mounted
```
## Usage
```tsx
import React, { useEffect } from "react";
import useMounted from "atechhub-use-mounted";
function MyComponent() {
const { mounted } = useMounted();
useEffect(() => {
// Simulate async operation
const fetchData = async () => {
const data = await api.getData();
// Safe to update state only if component is still mounted
if (mounted.current) {
setData(data);
}
};
fetchData();
}, [mounted]);
return <div>My Component</div>;
}
```
## API
### `useMounted()`
**Returns:** `{ mounted: RefObject<boolean> }`
- `mounted`: A ref object containing a boolean value that tracks the component's mounted state
- `mounted.current` is `true` when the component is mounted
- `mounted.current` is `false` when the component is unmounted
## Use Cases
- **Prevent memory leaks**: Check if component is mounted before setting state
- **Conditional async operations**: Avoid state updates on unmounted components
- **Safe DOM manipulations**: Ensure component exists before DOM access
- **Cleanup async operations**: Prevent unnecessary API calls or timers
## Examples
### Preventing State Updates After Unmount
```tsx
import React, { useState, useEffect } from "react";
import useMounted from "atechhub-use-mounted";
function UserProfile({ userId }: { userId: string }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const { mounted } = useMounted();
useEffect(() => {
const loadUser = async () => {
try {
const userData = await fetchUser(userId);
// Only update state if component is still mounted
if (mounted.current) {
setUser(userData);
setLoading(false);
}
} catch (error) {
if (mounted.current) {
setLoading(false);
}
}
};
loadUser();
}, [userId, mounted]);
if (loading) return <div>Loading...</div>;
return <div>{user?.name}</div>;
}
```
### With setTimeout/setInterval
```tsx
import React, { useEffect, useState } from "react";
import useMounted from "atechhub-use-mounted";
function Timer() {
const [count, setCount] = useState(0);
const { mounted } = useMounted();
useEffect(() => {
const interval = setInterval(() => {
// Safe to update state
if (mounted.current) {
setCount((prev) => prev + 1);
}
}, 1000);
return () => clearInterval(interval);
}, [mounted]);
return <div>Count: {count}</div>;
}
```
## TypeScript Support
This hook is written in TypeScript and provides full type safety out of the box.
```tsx
import { RefObject } from "react";
const useMounted: () => { mounted: RefObject<boolean> };
```
## Why Use This Hook?
React components can be unmounted while async operations are still running. This can lead to:
- Memory leaks
- "Can't perform a React state update on an unmounted component" warnings
- Unnecessary API calls or computations
The `useMounted` hook provides a simple way to check if your component is still mounted before performing state updates.
## License
MIT
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## Repository
https://github.com/atechhub24/use-mounted