React Native Expo BarCodeScanner在导航时保持摄像头打开

igetnqfo  于 2023-06-30  发布在  React
关注(0)|答案(1)|浏览(104)

我有一个简单的expo管理的React Native项目设置,带有react-navigation,我有两个屏幕,其中一个是主屏幕,另一个是使用expo的BarCodeScanner的QRCode扫描器屏幕。
这里的问题是,当从主屏幕导航到QR码屏幕并返回主屏幕时,相机保持活动。我可以看到状态栏中的活动说'Expo Go正在使用您的相机'
我尝试了各种方法来解决这个问题,

  • 将屏幕作为渲染 prop 传递给Stack.Screen,这样每次导航时都会挂载它,但问题还是一样
  • 尝试使用isFocused方法有条件地呈现组件,但仍然失败
<NavigationContainer fallback={<Text>Loading...</Text>}>
   <Stack.Navigator
     screenOptions={({ route, navigation }) => ({
       headerShadowVisible: false,
       headerTitle: () => (
         <Text
           style={{
             fontSize: 30,
             fontFamily: Font["900"],
           }}
         >
           Test
         </Text>
       ),
       headerRight: () =>
         route.name !== "QR" ? (
           <Pressable onPress={() => navigation.navigate("QR")}>
             <QrcodeIcon size={26} color="black" />
           </Pressable>
         ) : null,
     })}
   >
     <Stack.Screen name="Home" component={Home} />
     <Stack.Screen name="QR" children={() => <QRCode />} />
   </Stack.Navigator>
 </NavigationContainer>

QRCode组件的代码如下所示:

const QRCode = () => {
  const [hasPermission, setHasPermission] = useState<boolean>();
  const [scanned, setScanned] = useState<boolean>(false);
  const isFocused = useIsFocused();
  const linkTo = useLinkTo();

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

  const handleBarCodeScanned = ({ type, data }: BarCodeEvent) => {
    setScanned(true);
    linkTo(data);
  };

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

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

  return (
    <View style={styles.container}>
      {isFocused ? (
        <BarCodeScanner
          onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
          style={StyleSheet.absoluteFill}
        />
      ) : null}
    </View>
  );
};
ht4b089n

ht4b089n1#

这个问题来自React Navigation缓存它的屏幕(并提供糟糕的缓存失效API)。从nagitation.navigate切换到navigation.reset为我解决了这个问题:

navigation.reset({
    index: 1,
    routes: [
      {
        name: 'ScreenYouWantToNavigateTo',
      },
    ],
  })

请记住,这将重置您的导航堆栈。另一种解决方案是使用isFocused钩子,更多信息请参见this thread

相关问题