Repository: pacocoursey/use-delayed-render
Branch: master
Commit: 0d9dca16351f
Files: 5
Total size: 5.2 KB
Directory structure:
gitextract_2acjkg2m/
├── .gitignore
├── README.md
├── index.ts
├── package.json
└── tsconfig.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
node_modules
dist
================================================
FILE: README.md
================================================
# useDelayedRender 
useDelayedRender is a react hook for delaying the render and unmount of a component. This is commonly used to animate UI on unmount.
<br />
## Installation
```
$ yarn add use-delayed-render
```
<br />
## Usage
Function signature:
```ts
const { mounted: boolean, rendered: boolean } = useDelayedRender(
active: boolean,
options?: {
enterDelay: number,
exitDelay: number,
onUnmount: () => void
}
)
```
Options:
- `active`: Whether your component is in an active state
- `enterDelay`: After mounting, the delay before `rendered` becomes true
- `exitDelay`: After `rendered` becomes false, the delay before unmounting
- `onUnmount`: A callback triggered after unmounting
Return values:
- `mounted`: Whether your component should be mounted in the DOM
- `rendered`: Whether your component should be visible
<br />
## Example
Render a modal, but delay the unmount so that our 2 second CSS transition completes before the modal is removed from the DOM.
```js
const Modal = ({ active }) => {
const { mounted, rendered } = useDelayedRender(active, {
exitDelay: 2000,
})
if (!mounted) return null
return (
<Portal>
<div className={rendered ? 'modal visible' : 'modal'}>{/* ... */}</div>
</Portal>
)
}
```
This allows you to use simple CSS transitions to animate the mounting/unmounting of your component.
```css
.modal {
opacity: 0;
transition: opacity 2s ease;
}
.modal.visible {
opacity: 1;
}
```
<br />
## Why?
- Usually you would use [`react-transition-group`](https://github.com/reactjs/react-transition-group) to solve this, but the 2.37MB install size is a bit overkill, compared to this package at 491B gzipped.
```jsx
<Transition in={active} unmountOnExit timeout={200} onExited={handleExit}>
<Modal />
</Transition>
```
- Hooks solve the problem without needing a render function or HOC.
================================================
FILE: index.ts
================================================
import { useState, useRef, useCallback } from 'react'
interface Options {
enterDelay?: number
exitDelay?: number
onUnmount?: () => void
}
const useDelayedRender = (active: boolean = false, options: Options = {}) => {
const [, force] = useState<any>()
const mounted = useRef(active)
const rendered = useRef(false)
const renderTimer = useRef<NodeJS.Timeout | null>(null)
const unmountTimer = useRef<NodeJS.Timeout | null>(null)
const prevActive = useRef(active)
const recalculate = useCallback(() => {
const { enterDelay = 1, exitDelay = 0 } = options
if (prevActive.current) {
// Mount immediately
mounted.current = true
if (unmountTimer.current) clearTimeout(unmountTimer.current)
if (enterDelay <= 0) {
// Render immediately
rendered.current = true
} else {
if (renderTimer.current) return
// Render after a delay
renderTimer.current = setTimeout(() => {
rendered.current = true
renderTimer.current = null
force({})
}, enterDelay)
}
} else {
// Immediately set to unrendered
rendered.current = false
if (exitDelay <= 0) {
mounted.current = false
} else {
if (unmountTimer.current) return
// Unmount after a delay
unmountTimer.current = setTimeout(() => {
mounted.current = false
unmountTimer.current = null
force({})
}, exitDelay)
}
}
}, [options])
// When the active prop changes, need to re-calculate
if (active !== prevActive.current) {
prevActive.current = active
// We want to do this synchronously with the render, not in an effect
// this way when active → true, mounted → true in the same pass
recalculate()
}
return {
mounted: mounted.current,
rendered: rendered.current
}
}
export default useDelayedRender
================================================
FILE: package.json
================================================
{
"name": "use-delayed-render",
"version": "0.1.0-beta.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"module": "dist/index.modern.js",
"source": "index.ts",
"license": "MIT",
"files": [
"dist"
],
"scripts": {
"prepublish": "yarn build",
"build": "microbundle --compress --no-sourcemap"
},
"devDependencies": {
"@types/react": "^16.9.35",
"microbundle": "^0.13.3",
"typescript": "^3.8.3"
},
"peerDependencies": {
"react": "*"
},
"dependencies": {},
"author": "@pacocoursey",
"repository": "pacocoursey/use-delayed-render"
}
================================================
FILE: tsconfig.json
================================================
{
"compilerOptions": {
"baseUrl": ".",
"allowJs": true,
"jsx": "preserve",
"target": "esnext",
"module": "esnext",
"lib": ["dom", "es2019"],
"noEmit": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"isolatedModules": true
}
}
gitextract_2acjkg2m/ ├── .gitignore ├── README.md ├── index.ts ├── package.json └── tsconfig.json
SYMBOL INDEX (1 symbols across 1 files)
FILE: index.ts
type Options (line 3) | interface Options {
Condensed preview — 5 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6K chars).
[
{
"path": ".gitignore",
"chars": 28,
"preview": ".DS_Store\nnode_modules\ndist\n"
},
{
"path": "README.md",
"chars": 1969,
"preview": "# useDelayedRender \n\nuseDelayedRender i"
},
{
"path": "index.ts",
"chars": 1914,
"preview": "import { useState, useRef, useCallback } from 'react'\n\ninterface Options {\n enterDelay?: number\n exitDelay?: number\n "
},
{
"path": "package.json",
"chars": 598,
"preview": "{\n \"name\": \"use-delayed-render\",\n \"version\": \"0.1.0-beta.0\",\n \"main\": \"dist/index.js\",\n \"types\": \"dist/index.d.ts\",\n"
},
{
"path": "tsconfig.json",
"chars": 766,
"preview": "{\n \"compilerOptions\": {\n \"baseUrl\": \".\",\n \"allowJs\": true,\n \"jsx\": \"preserve\",\n \"target\": \"esnext\",\n \"mo"
}
]
About this extraction
This page contains the full source code of the pacocoursey/use-delayed-render GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 5 files (5.2 KB), approximately 1.5k tokens, and a symbol index with 1 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.