You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中useFocusEffect未触发,权限校验更新异常求助

解决React Native中useFocusEffect从设置返回不触发权限检查的问题

问题场景

打开应用后弹出权限请求弹窗,要求授予write_settings_permission。期望用户从系统设置返回应用时,自动检查权限是否授予,已授予则跳转至Network页面,否则继续显示弹窗。但实际情况是,用户首次从设置返回后无反应,需再次点击授权按钮进入设置返回才会触发跳转。

问题原因

  1. requestWriteSettingsPermission中,调用openWriteSettings()跳转到系统设置后,应用进入后台,后续的权限检查代码执行时机不稳定,可能无法及时获取最新权限状态。
  2. useFocusEffect的回调依赖未正确配置,导致页面重新获得焦点时未触发权限检查(或检查逻辑未正确更新)。

修复方案

  1. 用useCallback包裹checkPermissions函数,确保其引用稳定,作为useFocusEffect的依赖项,保证焦点触发时执行最新的检查逻辑。
  2. 移除requestWriteSettingsPermission中openWriteSettings()后的权限检查,完全依赖useFocusEffect在页面获得焦点时统一检查权限状态,避免后台执行的不确定性。
  3. 调整弹窗显示逻辑,确保权限授予后自动隐藏弹窗。

修改后的完整代码

import React, { useEffect, useState, useCallback } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
import { useNavigation, useFocusEffect } from '@react-navigation/native';
import HotspotManager, { TetheringError } from '@react-native-tethering/hotspot';

const FirstScreen = () => {
  const [loading, setLoading] = useState(true);
  const [showPermissionsPopup, setShowPermissionsPopup] = useState(false);
  const [permissionsGranted, setPermissionsGranted] = useState(false);
  const navigation = useNavigation();

  const requestWriteSettingsPermission = async () => {
    try {
      // 仅跳转到设置页面,权限检查交给useFocusEffect处理
      await HotspotManager.openWriteSettings();
    } catch (error) {
      if (error instanceof TetheringError) {
        console.log(error.message);
      }
      console.log(error);
    }
  };

  // 用useCallback包裹,确保引用稳定
  const checkPermissions = useCallback(async () => {
    try {
      const granted = await HotspotManager.isWriteSettingsGranted();
      console.log(`Write settings permission is ${granted ? 'granted' : 'not granted'}`);
      setPermissionsGranted(granted);
      // 权限授予后隐藏弹窗
      if (granted) {
        setShowPermissionsPopup(false);
      }
    } catch (error) {
      if (error instanceof TetheringError) {
        console.log(error.message);
      }
      console.log(error);
    }
  }, []);

  useFocusEffect(
    useCallback(() => {
      checkPermissions();
      console.log('页面获得焦点,执行权限检查');
    }, [checkPermissions]) // 依赖checkPermissions,确保回调能触发最新逻辑
  );

  useEffect(() => {
    const timeout = setTimeout(() => {
      setLoading(false);
      setShowPermissionsPopup(true);
    }, 2000);

    return () => clearTimeout(timeout);
  }, []);

  useEffect(() => {
    if (permissionsGranted) {
      console.log('权限已授予,跳转至Network页面');
      navigation.navigate('Network');
    }
  }, [navigation, permissionsGranted]);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      {loading ? (
        <ActivityIndicator size="large" color="blue" />
      ) : (
        <Text>Welcome to My App!</Text>
      )}

      {showPermissionsPopup && !permissionsGranted && (
        <View
          style={{
            position: 'absolute',
            top: 0,
            bottom: 0,
            left: 0,
            right: 0,
            backgroundColor: 'rgba(0, 0, 0, 0.5)',
            justifyContent: 'center',
            alignItems: 'center',
          }}>
          <View style={{ backgroundColor: 'white', padding: 20 }}>
            <Text>Please grant the required permissions to continue.</Text>
            <Text
              style={{ color: 'blue', textDecorationLine: 'underline' }}
              onPress={requestWriteSettingsPermission}>
              Grant Permissions
            </Text>
          </View>
        </View>
      )}
    </View>
  );
};

export default FirstScreen;

关键修改点说明

  • checkPermissions用useCallback包裹:避免组件每次渲染时重新创建函数,保证useFocusEffect的回调依赖稳定,确保页面焦点变化时执行正确的检查逻辑。
  • 移除requestWriteSettingsPermission内的权限检查:用户跳转到设置后应用进入后台,后续代码执行不可靠,改为依赖焦点事件触发检查,更准确及时。
  • useFocusEffect依赖checkPermissions:确保回调函数能响应checkPermissions的更新(虽然这里checkPermissions依赖为空,但显式声明依赖是React Hooks的最佳实践,避免潜在问题)。
  • 权限授予后隐藏弹窗:在checkPermissions中添加setShowPermissionsPopup(false),确保权限通过后弹窗自动消失,提升用户体验。

内容的提问来源于stack exchange,提问作者ohto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 16:42:42