@playcanvas/react
Version:
A React renderer for PlayCanvas – build interactive 3D applications using React's declarative paradigm.
84 lines • 2.62 kB
JavaScript
import { useEffect, useCallback } from "react";
import { useApp } from "./use-app.js";
import { warnOnce } from "../utils/validation.js";
/**
* Generic hook for subscribing to PlayCanvas application events.
* Supports both built-in events and custom events with proper TypeScript typing.
*
* @param event - The event name to subscribe to
* @param callback - The callback function to execute when the event fires
*
* @example
* ```tsx
* // Built-in events with type safety
* useAppEvent('update', (dt) => console.log('Frame time:', dt));
* useAppEvent('prerender', () => console.log('Pre-render'));
* useAppEvent('postrender', () => console.log('Post-render'));
* ```
*
* @example
* ```tsx
* // Custom events with custom event map - no inheritance needed
* interface MyEventMap {
* levelComplete: (level: number, score: number) => void;
* playerDeath: (position: [number, number, number]) => void;
* }
*
* useAppEvent<MyEventMap>('levelComplete', (level, score) => {
* console.log(`Level ${level} completed with score ${score}`);
* });
*
* useAppEvent<MyEventMap>('playerDeath', (position) => {
* console.log('Player died at', position);
* });
* ```
*
* @example
* ```tsx
* function MyComponent() {
* // Frame update with delta time
* useAppEvent('update', (dt) => {
* console.log('Frame delta time:', dt);
* });
*
* // App lifecycle events
* useAppEvent('prerender', () => {
* console.log('Pre-rendering');
* });
*
* return null;
* }
* ```
*/
export function useAppEvent(event, callback) {
const app = useApp();
const handler = useCallback((...args) => {
if (event === 'update') {
// update event always receives delta time as first argument
callback(args[0]);
}
else {
callback();
}
}, [callback, event]);
useEffect(() => {
if (!app) {
throw new Error("`useAppEvent` must be used inside an `<Application />` component");
}
app.on(event, handler);
return () => {
app.off(event, handler);
};
}, [app, handler, event]);
}
/**
* useFrame hook — registers a callback on every frame update.
* The callback receives the delta time (dt) since the last frame.
*
* @deprecated Use useAppEvent('update', callback) instead
*/
export const useFrame = (callback) => {
warnOnce("`useFrame` is deprecated and will be removed in a future release. Please use useAppEvent('update', callback) instead.");
return useAppEvent('update', callback);
};
//# sourceMappingURL=use-app-event.js.map