How is this code running after setState hook without a listener in useEffect hook?

asnyder002 :

I'm looking into an expo barcode scanner and in their example they have a function running after a setState hook. I would just like to understand why it's about to run after the hook is called because my understanding was once setState hook is called it rerenders the component.

I'm referring to the function handleBarCodeScanned. How is the alert being called after setScanned(true)?

import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { BarCodeScanner } from 'expo-barcode-scanner';

const ScanScreen = (props) => {
    const [hasPermission, setHasPermission] = useState(null);
    const [scanned, setScanned] = useState(false);

    useEffect(() => {
        (async () => {
        const { status } = await BarCodeScanner.requestPermissionsAsync();
        setHasPermission(status === 'granted');
        })();
    }, []);

    const handleBarCodeScanned = ({ type, data }) => {
        setScanned(true);
        alert(`Bar code with type ${type} and data ${data} has been scanned!`);
    };

    if (hasPermission === null) {
        return <Text>Requesting for camera permission</Text>;
    }
    if (hasPermission === false) {
        return <Text>No access to camera</Text>;
    }

    return (
        <View
        style={{
            flex: 1,
            flexDirection: 'column',
            justifyContent: 'flex-end',
        }}>
        <BarCodeScanner
            onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
            style={StyleSheet.absoluteFillObject}
        />

        {scanned && <Button title={'Tap to Scan Again'} onPress={() => setScanned(false)} />}
        </View>
    );
};

export default ScanScreen;
Alex Wayne :

Setting state is asynchronous. This is because you may set multiple bits of state in some event handler. You could, for instance:

const handleBarCodeScanned = ({ type, data }) => {
    setScanned(true);
    setData(data);
    setScanType(type);
};

Then after everything is done executing the component will re-render with all the state that just got changed. Internally, react just marks that component as needing an update when you change state, and (very briefly) later it starts actually doing the render.

So because it keeps executing after you change state, you can also do other stuff after you change state. Like show an alert, or start an HTTP request, or whatever your application needs.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=29867&siteId=1