场景:有两个input框A、B,在A输入之后要进行校验,如果校验通过,自动聚焦到B的输入框……
做法:我就想得到了在B框上使用ref,通过调用xxxRef.current?.focus()来实现这个小场景
坑:但是坑来了
- current拿不到值,打印出来是 undefined
- 控制台还报错:
Warning: Function components cannot be given refs. Attempts to access this ref will fail.
解决:需要套用forwardRef
子组件:
套了一层forwardRef,并且有了第二个参数ref,在input上传入了ref={ref}
const RgInput = forwardRef((props: IInputProps, ref: React.Ref<InputRef> | undefined) => {
const { className, onlyText, ...rest } = props;
return (
<Input
{...rest}
className={classNames(
'rg-input',
{ 'only-text': onlyText },
className,
)}
ref={ref}
></Input>
);
});
父组件:
employeeIdRef.current?.focus();就能正常使用了
const employeeIdRef = useRef<any>();
...
<RgInput size="large" placeholder="扫描员工号" ref={employeeIdRef} />
这里的RgInput是其他人封装过的input框,后来我换成了antd的input也可以直接使用ref,不需要去包一层forwardRef了
原因:
因为原来父组件通过 ref 获取了子组件的节点,子组件是函数式组件。
函数创建的子组件不能增加 refs. 官方推荐使用 React.forwardRef 解决。
概括:
ref不能使用在函数式组件上,因为函数式组件没有实例!要配合forwardRef使用!
官方解释:
1、转发 refs 到 DOM 组件
2、默认情况下,你不能在函数组件上使用 ref 属性,因为它们没有实例: