360 Secure SkillHub
360 安全技能中心

React Game Loop Hooks

这是生产级TypeScript React自定义hooks,基于requestAnimationFrame实现游戏循环与动画功能。核心功能含启停控制、delta时间钳制、防stale-closure、卸载自动清理、错误容错等。适用于React浏览器项目的游戏开发、动画效果实现场景。输入需配置必选的onFrame回调及可选maxDeltaTime参数,输出start/stop方法与isRunning状态,依赖React≥16.8、TypeScript≥4.0,仅支持浏览器环境。

ravenquasar
ravenquasar
热度 34.20
最近更新 2026-05-11 17:46:21
分类:开发依赖:纯提示词应用场景:代码生成 / API 集成

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add react-game-loop
Metadata
name
react-hooks-game-loop
description
Create custom React hooks in TypeScript for game loops and animations. Use when the user asks for a React hook, requestAnimationFrame integration, game loop pattern, or delta-time handling. Handles stale-closure safety, unmount cleanup, error resilience, and configurable parameters.

React Game Loop Hooks

Production-ready custom React hooks for game loops and animations using requestAnimationFrame.

Installation

Copy the hook file into your project:

# From your skill directory
cp <skill-dir>/assets/hooks/useGameLoop.ts src/hooks/

<skill-dir> resolves to your OpenClaw skill installation directory.

Dependencies

  • React >= 16.8 (hooks support)
  • TypeScript >= 4.0 (for type safety)
  • react-dom >= 16.8 (for requestAnimationFrame types in browser environment)

This is a browser-only hook — it requires requestAnimationFrame, which is not available in Node.js or SSR environments.

API Reference

useGameLoop(options)

import { useGameLoop } from './hooks/useGameLoop';

Parameters:

Option Type Default Description
onFrame (deltaTime: number, elapsedTime: number) => void — Called every frame with delta (ms) and elapsed time (ms). Required.
maxDeltaTime number 100 Maximum delta clamp in ms. Prevents huge jumps after tab-switch or lag.

Returns:

Field Type Description
start () => void Start the game loop
stop () => void Stop the game loop
isRunning boolean Current loop state

Patterns

Stale-closure safety

Use useRef for callbacks/state read inside async/closure contexts (e.g. requestAnimationFrame, setInterval, event listeners). Always sync ref in useEffect.

const cbRef = useRef(onFrame);
useEffect(() => { cbRef.current = onFrame; }, [onFrame]);

Cleanup on unmount

Always return cleanup from useEffect. For RAF/intervals, store handle in ref and cancel on unmount.

useEffect(() => {
  const id = requestAnimationFrame(tick);
  return () => cancelAnimationFrame(id);
}, []);

Error resilience

Wrap user callbacks in try/catch so errors don't break internal loop state.

try {
  callbackRef.current(delta, elapsed);
} catch (err) {
  console.error('hook callback error:', err);
}

Delta-time clamping

For game loops, clamp deltaTime to avoid huge jumps after tab-switch or lag spikes.

const delta = Math.min(rawDelta, maxDeltaTime);

Example

See assets/examples/GameTimer.tsx for a complete usage example showing elapsed time and FPS display.

Reference

  • assets/hooks/useGameLoop.ts — requestAnimationFrame-based game loop with start/stop/isRunning controls, deltaTime clamping, and error resilience
  • assets/examples/GameTimer.tsx — basic usage example