Guides
React Integration

React Integration

Advanced patterns and best practices for using threeparticles with React.

New to R3F? Start with the R3F Quick Start guide.

Performance Tips

  1. Memoize configs to prevent recreation on re-renders
  2. Use refs for particle systems to avoid React state updates
  3. Dispose properly in cleanup functions
  4. Limit re-renders by separating particle logic from reactive state
import { useState, useRef } from "react";
import { Particles } from "@threeparticles/core";
 
function Game() {
  const [score, setScore] = useState(0);
  const particlesRef = useRef<Particles>(null);
 
  // Update particles imperatively, not through state
  function onCollect() {
    setScore((s) => s + 1);
    // Trigger burst without causing re-render
    particlesRef.current?.start();
  }
 
  return <GameUI score={score} onCollect={onCollect} />;
}

Manual Integration

If you need more control than the built-in component provides, you can manually manage the particle lifecycle:

import { useEffect, useRef } from "react";
import { useFrame } from "@react-three/fiber";
import { Particles, ParticlesConfig } from "@threeparticles/core";
 
function ManagedParticles({ config }: { config: ParticlesConfig }) {
  const particlesRef = useRef<Particles | null>(null);
 
  useEffect(() => {
    const particles = new Particles(config);
    particlesRef.current = particles;
    particles.start();
 
    return () => {
      particles.stop();
      particles.dispose();
    };
  }, [config]);
 
  useFrame((_, delta) => {
    particlesRef.current?.update(delta);
  });
 
  return particlesRef.current ? <primitive object={particlesRef.current} /> : null;
}

Note: The native <Particles> component from @threeparticles/core/react handles lifecycle and frame updates automatically.

Custom Hook

Create a reusable hook for particle systems outside of R3F:

import { useEffect, useRef } from "react";
import { Particles, ParticlesConfig } from "@threeparticles/core";
 
export function useParticles(config: ParticlesConfig) {
  const particlesRef = useRef<Particles | null>(null);
 
  useEffect(() => {
    const particles = new Particles(config);
    particles.start();
    particlesRef.current = particles;
 
    return () => {
      particles.stop();
      particles.dispose();
      particlesRef.current = null;
    };
  }, []);
 
  return particlesRef;
}