You need to enable JavaScript to run this app. React Native + Expo中useEffect自动聚焦在Android Box端报错
优惠活动
大模型
产品
解决方案
定价
更多

React Native + Expo中useEffect自动聚焦在Android Box端报错

问题核心原因

你遇到的报错本质有两层原因:

  1. 从React Native原生设计逻辑上,TouchableWithoutFeedback组件本身不支持Android TV/Box的焦点交互能力——它是纯JS层的触摸包裹组件,不会渲染对应的原生可聚焦视图,自然不会把focus()这类系统方法透传到绑定的ref上。
  2. 本地Expo开发环境下,React的开发模式补丁会给组件ref附加模拟的focus/blur方法,所以调试时调用不会报错;到Android Box的Expo Go实机环境下,运行的是不带开发补丁的生产逻辑,ref实例上根本不存在focus方法,直接调用就会触发focus is not a function的TypeError。
具体解决方案

1. 替换支持原生焦点能力的可点击组件

  • 把原来的TouchableWithoutFeedback替换为Pressable、TouchableOpacity这类在原生层实现了焦点逻辑的组件,这类组件会自动把原生视图的focus()、blur()方法透传到绑定的ref上,实机环境下也能正常调用
  • 不要在useEffect里硬调用focus方法,加上可选链做防御判断,避免组件ref还未挂载完成时触发空值报错
  • 针对Android Box的焦点扫描规则,给可点击组件显式加上focusable={true}属性,否则系统可能不会把该组件纳入方向键的焦点遍历范围

2. 调整自动聚焦的触发时机

Android Box上的原生视图挂载延迟比普通手机、本地模拟器高,空依赖的useEffect执行时,组件可能还没完成原生层的绑定,哪怕组件支持focus方法也会调用失败。可以加100ms左右的延时触发聚焦,确认视图完全挂载后再执行focus调用。

修正后的可运行代码示例
import { StyleSheet, Image, View, Pressable } from 'react-native';
import * as React from 'react';

const HomeScreen = ({navigation}) => {
  const goToNextScreen = React.useRef(null)

  React.useEffect(() => {
    const focusTimer = setTimeout(() => {
      // 防御性判断,避免空引用报错
      goToNextScreen.current?.focus()
    }, 100)
    // 组件卸载时清理定时器,避免内存泄漏
    return () => clearTimeout(focusTimer)
  }, []);

  return (
      <View style={styles.container}>
        <Pressable
            ref={goToNextScreen}
            focusable={true}
            onPress={() => navigation.navigate('NextPage')}>
            <Image
                source={require('../assets/img/logo.png')}
            />
        </Pressable>
      </View>
  );
}

export default HomeScreen;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 02:57:00