Treat the runtime as an external system
A mascot component owns a canvas and a Rive instance. The surrounding React application owns product state. Keep those responsibilities separate so rendering a form or updating a field does not recreate the character on every change.
Store the canvas and runtime instance in refs. Initialize after the DOM canvas exists, using the official Rive runtime or its official React wrapper. Choose one ownership model rather than combining two wrappers around the same canvas.
Make setup and cleanup symmetrical
React effects are a natural boundary for a manually managed runtime. Create the instance in setup, then remove listeners, disconnect observers and call cleanup when that instance is no longer needed. Development checks may run setup and cleanup more than once; the integration must tolerate that.
Avoid using a changing object literal as an effect dependency when it contains stable configuration. Rebuilding the instance because an unrelated parent rerendered can reset the character and allocate unnecessary resources.
// Inside a component; canvasRef points to its canvas.
useEffect(() => {
const mascot = createMascot(canvasRef.current);
return () => mascot.cleanup();
}, []);This lifecycle sketch assumes createMascot handles load errors, sizing and the input contract. If the export path can change, include that dependency and clean up the previous instance before creating another. See the official effect reference for lifecycle details.
Send events without rerendering every frame
Pointer coordinates change quickly. Store a target position outside React render state and update the Rive input values through a bounded animation loop. A React rerender for every pointer event adds work without improving the character.
Product events can be translated into named triggers after the file has loaded. Do not fire a signup celebration simply because a component mounted; connect it to the application’s confirmed transition. Repeated renders should not replay one-time reactions.
Keep the fallback part of the component
Render the static image and reserve the canvas space before the runtime starts. Hide the fallback only when the file and expected state machine have loaded. If loading fails, keep the image visible and preserve any useful surrounding text.
Listen for reduced-motion changes and pause when hidden or offscreen. If the component appears in a modal or route that can unmount, verify cleanup there as well as in the initial page. A keyboard-accessible greeting button should remain a normal HTML button.
Define what the integration handoff includes
Your developer needs the asset path, state-machine name, typed inputs and ranges. Agree whether the deliverable includes a reusable React component, a JavaScript example or integration assistance inside the product repository. These are different scopes.
This marketing website is plain static HTML; the React guidance describes a customer integration. Share your React version, rendering setup and mascot placement so the example can be tested against your environment rather than treated as a universal drop-in.