Setting a react state in callback does not work as expected

279 Views Asked by At

I am making barcode reading app. I use Quaggajs and Reactjs.
Quaggajs has a function Quagga.onDetected(callback), the callback has one parameter result. The result is containing the detected barcode. I am having a react state (const [count, setCount] = useState(0);) in which I am counting the detected barcodes. The problem is that when I use setCount(count + 1) in the callback the count variable is allways it's initial value (0) so every time onDetect the setCount is setting the new value to be 1.

Here is an example of the functional react component I use(I think that there is no problem getting the count and setCount from the props of ):

const Body = ({setCount, count, ...rest }) => {

    const start = () => {
        Quagga.init({
            inputStream: {
                name: "Live",
                type: "LiveStream",
                constraints: {
                    facingMode: "environment",
                },
                area: {
                    top: "30%",
                    bottom: "30%"
                }
            },
            locate: false,
            frequency: 50,
            decoder: {
                readers: [
                    // "code_128_reader",
                    "ean_reader",
                    // "ean_8_reader",
                    // "code_39_reader",
                    // "code_39_vin_reader",
                    // "codabar_reader",
                    // "upc_reader",
                    // "upc_e_reader",
                    // "i2of5_reader"
                ],
                debug: {
                    showCanvas: true,
                    showPatches: true,
                    showFoundPatches: true,
                    showSkeleton: true,
                    showLabels: true,
                    showPatchLabels: true,
                    showRemainingPatchLabels: true,
                    boxFromPatches: {
                        showTransformed: true,
                        showTransformedBox: true,
                        showBB: true
                    }
                }
            },

        }, function (err) {
            if (err) {
                console.log(err);
                return
            }

            console.log("Initialization finished. Ready to start");
            Quagga.start();
        });

        Quagga.onProcessed(function (result) {
            var drawingCtx = Quagga.canvas.ctx.overlay,
                drawingCanvas = Quagga.canvas.dom.overlay;

            if (result) {
                if (result.boxes) {
                    drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
                    result.boxes.filter(function (box) {
                        return box !== result.box;
                    }).forEach(function (box) {
                        Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 2 });
                    });
                }

                if (result.box) {
                    Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "#00F", lineWidth: 2 });
                }

                if (result.codeResult && result.codeResult.code) {
                    Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 });
                }
            }
        });

        Quagga.onDetected((result) => {
            if (result && result.codeResult && result.codeResult.startInfo && result.codeResult.startInfo.error < 0.03) {
                console.log("Sould change")
                setCount(count + 1);
            }
        });
    }

    const stop = () => { Quagga.stop(); }


    useEffect(() => {
        start();
        console.log("CHANGE BODY");
        return () => {
            stop();
        }
    }, [])

    return (
        <Grid container justify="center">
            <div id="interactive" className="viewport" style={{ position: 'unset', width: '100vw', height: "100vh" }}>
                <video src=""></video>
                <canvas class="drawingBuffer"></canvas>
            </div>
        </Grid>
    )
}
0

There are 0 best solutions below