我有一个简单的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>
);
};
1条答案
按热度按时间ht4b089n1#
这个问题来自React Navigation缓存它的屏幕(并提供糟糕的缓存失效API)。从
nagitation.navigate
切换到navigation.reset
为我解决了这个问题:请记住,这将重置您的导航堆栈。另一种解决方案是使用
isFocused
钩子,更多信息请参见this thread。