React Native安卓端TextInput首次显示时autoFocus失效问题
问题根因
这是React Native在安卓平台长期存在的时序兼容问题:你当前通过三元表达式做条件渲染,首次点击按钮切换状态时,TextInput是首次被挂载到视图层级,安卓输入框的焦点调度逻辑和组件首帧渲染存在时间差,autoFocus={true}触发的焦点请求会在输入框未完全就绪时被系统丢弃,因此首次点击不会唤起键盘;后续切换时TextInput已经有挂载缓存,焦点调度可以正常匹配,autoFocus就会生效。
修复方案
不要依赖内置的autoFocus属性,通过useRef拿到TextInput实例,在状态切换到输入模式、视图渲染完成后主动调用focus()方法触发焦点,是安卓端兼容性最稳定的方案。
你只需要修改add.js文件即可,App.js和样式文件不需要改动,修改后的完整代码:
import React, {useEffect, useState, useRef} from "react"; import {View, TouchableOpacity, Image, TextInput, Text, TouchableHighlight} from "react-native"; import styles from "./add.style" function Add() { const [add_mode_as_btn, set_add_mode_as_btn] = useState(true); // 创建输入框实例引用 const textInputRef = useRef(null); // 监听输入模式切换,视图渲染完成后主动聚焦 useEffect(() => { if (!add_mode_as_btn) { // 加100ms短延时等待安卓完成首帧绘制,覆盖全机型兼容 const focusTimer = setTimeout(() => { textInputRef.current?.focus(); }, 100); return () => clearTimeout(focusTimer); } }, [add_mode_as_btn]); return( <View> {add_mode_as_btn ? <View style={styles.add_btn_container}> <TouchableHighlight onPress={() => {set_add_mode_as_btn(false)}} style={styles.add_btn}> <Image style={styles.add_btn_image} source={require('./icons/add.png')}/> </TouchableHighlight> </View> : <View style={styles.save_container}> <TextInput ref={textInputRef} style={styles.save_text_input} placeholder="Add Task" placeholderTextColor={"#808080"} /> <TouchableOpacity style={styles.save_btn} onPress={() => set_add_mode_as_btn(true)} > <Text style={{color:"white", fontSize:20, fontWeight:"bold"}}>Save</Text> </TouchableOpacity> </View> } </View> ); }; export default Add;
补充说明
- 代码中100ms的短延时用户完全感知不到,比无延时直接调用focus()的稳定性高很多,能覆盖所有安卓版本、定制ROM的兼容问题
- 如果你不想用延时,也可以把条件渲染改成两个分支常驻、通过
opacity:0/height:0这类样式控制显隐的写法,但会让组件长期占用内存,不如ref方案轻量。
内容的提问来源于stack exchange,提问作者Furkan Özgel
相关产品推荐
相关产品推荐

