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

无法设置文本输入Ref:自定义输入组件Ref传递失败致焦点切换异常

问题描述

尝试在onSubmitEditing事件触发时切换输入框焦点,但无法将ref属性从自定义文本输入组件传递到主组件,ref中的控制台日志没有输出任何内容。

相关代码:

const MyCustomInput = (props) => {
    <View> 
        <FormInput
              {...props}
              editable={!props.disabled}
              selectTextOnFocus={!props.disabled}
              disable={props.disabled}
              displayOnly={props.displayOnly}
              small={props.small}
              placeholderTextColor={'#AFAFAF'}
         />
    </View>
}
<Controller
    control={control}
    render={({field: {onChange, onBlur, value, ref}}) => (
        <MyCustomInput
            onBlur={onBlur}
            onChangeText={(value: string) => onChange(value)}
            value={value}
            ref={(r: any) => {
                console.log('r', r);
                ref(r);
                inputRef.current = r;
            }}
        />
    )}
    name="myInput"
/>
解决方案

问题核心是自定义函数组件默认不支持接收ref,需要通过React.forwardRef转发ref到内部实际的输入组件,同时修复原组件缺少return的隐性问题。

1. 改造自定义组件为forwardRef形式

import React, { forwardRef } from 'react';
import { View } from 'react-native';

const MyCustomInput = forwardRef((props, ref) => {
    const { ...restProps } = props;
    return (
        <View> 
            <FormInput
                {...restProps}
                ref={ref} // 将外部传入的ref绑定到内部FormInput组件
                editable={!props.disabled}
                selectTextOnFocus={!props.disabled}
                disable={props.disabled}
                displayOnly={props.displayOnly}
                small={props.small}
                placeholderTextColor={'#AFAFAF'}
            />
        </View>
    );
});

export default MyCustomInput;

2. 调整Controller中的ref使用

现在自定义组件可以正常接收ref,控制台日志也能输出FormInput实例:

<Controller
    control={control}
    render={({field: {onChange, onBlur, value, ref}}) => (
        <MyCustomInput
            onBlur={onBlur}
            onChangeText={(value: string) => onChange(value)}
            value={value}
            ref={(r) => {
                console.log('r', r); // 现在能输出输入框实例
                ref(r);
                inputRef.current = r;
            }}
        />
    )}
    name="myInput"
/>

关键说明

  • forwardRef允许函数组件接收ref参数,并转发给内部的原生输入组件,这样才能获取到输入框实例调用focus()方法
  • 原组件缺少return语句,导致组件无法正常渲染,这也是ref无法传递的隐性原因
  • 必须将ref绑定到实际的输入组件(FormInput),而非外层View,否则无法获取到切换焦点所需的实例方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:20:26