Below is my relevant Javascript code -
useEffect(()=> {
Promise.all([
faceapi.nets.tinyFaceDetector.loadFromUri('/models'),
faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
faceapi.nets.faceRecognitionNet.loadFromUri("/models"),
faceapi.nets.faceExpressionNet.loadFromUri('/models')
]).then(()=> {
if(navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices
.getUserMedia({ audio:false, video:true })
.then((stream) => {
console.log(stream)
const video = document.getElementById("video");
videoRef.current.srcObject = stream;
console.log("video is " + video)
video.play();
setisLoaded(true);
addEvent();
})
.catch((e) => {
console.log(e);
});
}
});
}, []);
const addEvent = () => {
console.log("Inside")
const video = document.getElementById("video");
video.addEventListener("play", () => {
const canvas = faceapi.createCanvas(video);
canvas.id = "canvas";
document.querySelector("#video").append(canvas);
document.body.append(canvas);
const displaySize = { width:width, height:height };
faceapi.matchDimensions(canvas, displaySize);
setInterval(async () => {
const detections = await faceapi.detectAllFaces('video', new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions();
const resizedDetections = faceapi.resizeResults(detections, displaySize);
canvas
.getContext("2d")
.clearRect(0, 0, canvas.width, canvas.height);
faceapi.draw.drawFaceExpressions(canvas, resizedDetections);
if(resizedDetections[0].expressions && tracking) {
setData(arr => [...arr, resizedDetections[0].expressions]);
}
}, 100);
})
}
The if statement in the setInterval function always evaluates the tracking state variable as false. The tracking variable is initially set to false, but I later change the state to true (in a function that is not shown). However, the setInterval function still evaluates the tracking variable to be false.
Is there any way for me to ensure the setInterval function knows when a variable or state changes?
I tried using a localStorage variable and even the useRef react hook, but got the same result. I tried using the useInterval hook as well, but that did not work.
It would be helpful to see the full example as your useEffect is not full. I don't see dependencies. Are you sure that
trackingis part ofuseEffectdependencies?In general useEffect will not update values of variables that are not part of dependencies array. This is most likely the issue here.
It worth mentioning that adding
trackingas part of dependencies list will cause you to reload models on change. So you will need to add extra checks or refactor this useEffect. You might also need to callvideo.removeEventListenerfor cleanupDocs: https://react.dev/reference/react/useEffect