I need to make a fetch call when the camera’s position crosses a threshold. I need the function to be callable again, but not until after 1000ms has passed.
Ideally this would happen immediately, but a small delay is tolerable. My main concern is performance as I’m rendering a very complex scene.
import { useMemo, useEffect } from "react";
import { useThree, useFrame } from "@react-three/fiber";
import throttle from "lodash/throttle";
export default function Component() {
const { camera } = useThree();
const throttledFetch = useMemo(
() =>
throttle(
(positionY: number) => {
fetch(`/something?positionY=${positionY}`).then((res) => {
console.log(res);
});
},
1000,
{ leading: true, trailing: false }
),
[]
);
useFrame(() => {
if (camera.position.y < 1.5) {
throttledFetch(camera.position.y);
}
});
useEffect(() => {
return () => {
throttledFetch.cancel();
};
}, [throttledFetch]);
return null;
}
This code works, but is it a sensible approach?
Minimal improvement using a useRef instead of lodash.throttle Avoids an external dependency and keeps control tight.
import { useRef } from "react";
import { useThree, useFrame } from "@react-three/fiber";
export default function Component() {
const { camera } = useThree();
const lastCall = useRef(0);
useFrame(() => {
if (camera.position.y < 1.5) {
const now = Date.now();
if (now - lastCall.current > 1000) {
lastCall.current = now;
fetch(`/something?positionY=${camera.position.y}`).then(res => {
console.log(res);
});
}
}
});
return null;
}