如何使用Hooks让自定义TextInput组件获取焦点?
问题描述
点击按钮时希望让自定义组件内的TextInput获取焦点,但直接传递ref出现Uncaught TypeError: usernameTextInput.current is null错误。直接使用原生TextInput时功能正常,需要适配Hooks的解决方案。
现有代码
Screen A代码
import React, { useRef } from 'react'; import { Pressable, Text } from "react-native"; import MyTextInput from "../components/MyTextInput"; const ScreenA = () => { const refTextInput = useRef(null); return ( <> <MyTextInput ref={refTextInput} // 其他props /> <Pressable onPress={() => refTextInput.current.focus()}> <Text>Focus</Text> </Pressable> </> ); }; export default ScreenA;
MyTextInput组件代码
import { TextInput } from "react-native"; const MyTextInput = (props) => { return ( <TextInput ref={props.ref} // 其他props /> ); }; export default MyTextInput;
解决方案
方法一:使用React.forwardRef传递ref
函数组件默认不支持接收ref,需要用forwardRef包裹自定义组件,将父组件的ref直接传递给内部的TextInput:
修改MyTextInput组件
import React, { forwardRef } from 'react'; import { TextInput } from "react-native"; // 用forwardRef包裹组件,接收props和ref两个参数 const MyTextInput = forwardRef((props, ref) => { return ( <TextInput ref={ref} // 将父组件的ref绑定到内部TextInput {...props} // 传递其他props /> ); }); export default MyTextInput;
此时父组件的refTextInput.current会直接指向内部的TextInput实例,调用focus()即可正常触发聚焦,Screen A代码无需修改。
方法二:自定义暴露focus方法(更灵活)
如果需要对聚焦逻辑添加自定义处理,可以在组件内部维护TextInput的ref,通过useImperativeHandle向父组件暴露focus方法:
修改MyTextInput组件
import React, { useRef, useImperativeHandle, forwardRef } from 'react'; import { TextInput } from "react-native"; const MyTextInput = forwardRef((props, ref) => { const inputRef = useRef(null); // 向父组件暴露自定义的focus方法 useImperativeHandle(ref, () => ({ focus: () => { inputRef.current?.focus(); // 这里可添加自定义逻辑,比如日志、状态更新等 } })); return ( <TextInput ref={inputRef} {...props} /> ); }); export default MyTextInput;
父组件依然通过refTextInput.current.focus()调用,这种方式既能实现聚焦功能,又能封装内部逻辑,避免直接暴露TextInput实例。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

