master 0d9dca16351f cached
5 files
5.2 KB
1.5k tokens
1 symbols
1 requests
Download .txt
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 ![npm bundle size](https://img.shields.io/bundlephobia/minzip/use-delayed-render)

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
  }
}
Download .txt
gitextract_2acjkg2m/

├── .gitignore
├── README.md
├── index.ts
├── package.json
└── tsconfig.json
Download .txt
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 ![npm bundle size](https://img.shields.io/bundlephobia/minzip/use-delayed-render)\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.

Copied to clipboard!