Установка состояния реакции в обратном вызове не работает должным образом - PullRequest
2 голосов
/ 08 мая 2020

Я делаю приложение для чтения штрих-кодов. Я использую Quaggajs и Reactjs. Quagga js имеет функцию Quagga.onDetected(callback), callback имеет один параметр result. result содержит обнаруженный штрих-код. У меня состояние реакции (const [count, setCount] = useState(0);), в котором я считаю обнаруженные штрих-коды. Проблема в том, что когда я использую setCount(count + 1) в callback, переменная count всегда является начальным значением (0), поэтому каждый раз, когда onDetect, setCount устанавливает новое значение равным 1.

Вот пример компонента функциональной реакции, который я использую (я думаю, что нет проблем с получением count и setCount из реквизита):

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>
    )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...