Hooks
There are a number of important hooks that are useful when working with @playcanvas/react
. These can often be useful when creating custom components, hooks or utilities.
useApp
The useApp
hook returns the Application
instance that is currently active. This is useful if you need reference to the PlayCanvas Application instance directly.
import { useApp } from '@playcanvas/react/hooks'
const MyComponent = () => {
const app = useApp();
console.log(app);
return <Entity>
<Render type="box" />
</Entity>
}
useParent
The useParent
hook returns the parent Entity
of the current component. This can be useful if you need to access the parent entity of a component. For example, if you are creating a custom component that should be attached to a specific entity.
import { useParent } from '@playcanvas/react/hooks'
const ChildEntity = () => {
const parent = useParent();
console.log(parent);
return <Entity>
<Render type="box" />
</Entity>
};
const ParentEntity = () => {
return <ChildEntity />;
};
useFrame
Deprecated: The
useFrame
hook is deprecated and will be removed in a future release. Please useuseAppEvent('update', callback)
instead.
The useFrame
hook ties into the event loop and will be called on every frame whilst the component is mounted. Use this when you need to update a value or perform a calculation on every frame. This is better for performance than using react state updates.
import { useFrame } from '@playcanvas/react/hooks'
const MyComponent = () => {
const entityRef = useRef(null);
useFrame((dt) => {
entityRef.current.rotate(0, dt, 0);
})
return <Entity ref={entityRef} />;
}
useAppEvent
The useAppEvent
hook provides a generic way to subscribe to PlayCanvas application events with proper TypeScript support. It supports both built-in events and custom events with their specific callback signatures.
Built-in Events
'update'
: Called every frame with delta time(dt: number) => void
'prerender'
: Called before rendering with no parameters() => void
'postrender'
: Called after rendering with no parameters() => void
Custom Events
You can define custom event maps for events fired by your application:
import { useAppEvent } from '@playcanvas/react/hooks'
// Define your custom event map - no need to extend anything
interface MyEventMap {
levelComplete: (level: number, score: number) => void;
playerDeath: (position: [number, number, number]) => void;
gameOver: (finalScore: number) => void;
}
const MyComponent = () => {
// Subscribe to custom events with full type safety
useAppEvent<MyEventMap>('levelComplete', (level, score) => {
console.log(`Level ${level} completed with score ${score}`);
});
useAppEvent<MyEventMap>('playerDeath', (position) => {
console.log('Player died at position:', position);
});
useAppEvent<MyEventMap>('gameOver', (finalScore) => {
console.log('Game over! Final score:', finalScore);
});
return null;
};
Note: Custom events must be fired from your PlayCanvas application instance using app.fire('eventName', ...args)
for the hook to receive them.
import { useAppEvent } from '@playcanvas/react/hooks'
const MyComponent = () => {
const entityRef = useRef(null);
// Frame update with delta time (replaces useFrame)
useAppEvent('update', (dt) => {
entityRef.current.rotate(0, dt, 0);
});
// Pre-render hook
useAppEvent('prerender', () => {
console.log('About to render frame');
});
// Post-render hook
useAppEvent('postrender', () => {
console.log('Finished rendering frame');
});
return <Entity ref={entityRef} />;
}
Migration from useFrame
To migrate from the deprecated useFrame
hook:
// Old way (deprecated)
useFrame((dt) => {
// your frame logic
});
// New way
useAppEvent('update', (dt) => {
// your frame logic
});
usePhysics
The usePhysics
hook provides access to physics context information, allowing you to check the physics state and handle physics-related errors. This hook is particularly useful when working with physics-enabled applications.
import { usePhysics } from '@playcanvas/react/hooks'
const PhysicsStatus = () => {
const { isPhysicsEnabled, isPhysicsLoaded, physicsError } = usePhysics();
if (physicsError) {
return <div>Physics error: {physicsError.message}</div>;
}
if (!isPhysicsLoaded) {
return <div>Loading physics...</div>;
}
return <div>Physics is ready!</div>;
};
Return Value
The hook returns an object with the following properties:
isPhysicsEnabled
:boolean
- Whether physics is enabled on the applicationisPhysicsLoaded
:boolean
- Whether the physics library has been successfully loadedphysicsError
:Error | null
- The error that occurred when loading physics, if any
Usage with Physics Components
This hook is commonly used alongside physics components like RigidBody
and Collision
to provide user feedback about physics state:
import { usePhysics } from '@playcanvas/react/hooks'
const PhysicsAwareComponent = () => {
const { isPhysicsEnabled, isPhysicsLoaded, physicsError } = usePhysics();
if (!isPhysicsEnabled) {
console.warn('Physics is not enabled on this application');
return null;
}
if (physicsError) {
console.error('Failed to load physics', physicsError);
return null;
}
if (!isPhysicsLoaded) {
console.log('Loading physics library...');
return null;
}
return (
<Entity>
<RigidBody type="dynamic" />
<Collision type="box" />
</Entity>
);
};
Note: This hook requires the application to have physics enabled via the usePhysics
prop on the Application
component.