HOOK组件内使用useRef作用于隐藏的Input为什么会导致ref失效?

https://preview.pro.ant.desig...
v4预览版,【个人中心】 菜单栏下,【标签】这个组件,后边那个+图标点击之后Input没有自动获取到焦点,所以导致失去焦点隐藏Input也失效,必须手动获取下焦点在失去才有效. v2版本没有问题

📷 复现步骤

v4失效:https://preview.pro.ant.desig...

v2可以:https://v2-preview-ant-design...
HOOK组件内使用useRef作用于隐藏的Input为什么会导致ref失效?

💻 复现代码

import { Input, Tag } from 'antd';

import React, { useState, useRef } from 'react';

const TagList: React.FC<{}> = ({ tags }) => {

const ref = useRef<Input | null>(null);

const [newTags, setNewTags] = useState([]);

const [inputVisible, setInputVisible] = useState<boolean>(false);

const [inputValue, setInputValue] = useState<string>('');

const showInput = () => {

setInputVisible(true);

if (ref.current) {

console.log(ref.current); // 这里打印ref.current为null

ref.current?.focus();

}

};

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {

setInputValue(e.target.value);

};

const handleInputConfirm = () => {

let tempsTags = [...newTags];

if (inputValue && tempsTags.filter((tag) => tag.label === inputValue).length === 0) {

tempsTags = [...tempsTags, { key: `new-${tempsTags.length}`, label: inputValue }];

}

setNewTags(tempsTags);

setInputVisible(false);

setInputValue('');

};

return (

<div>

<div>标签</div>

{(tags || []).concat(newTags).map((item) => (

<Tag key={item.key}>{item.label}</Tag>

))}

{inputVisible && (

<Input

ref={ref}

type="text"

size="small"

style={{ width: 78 }}

value={inputValue}

onChange={handleInputChange}

onBlur={handleInputConfirm}

onPressEnter={handleInputConfirm}

/>

)}

{/* 点击时隐藏此按钮,并打开Input,同时自动获取到焦点, 但此时Input自动获取焦点失败 */}

{!inputVisible && (

<Tag onClick={showInput} style={{ borderStyle: 'dashed' }}>

<PlusOutlined />

</Tag>

)}

</div>

);

};

请问是什么原因,应该注意什么?

我想应该是 Input组件放在判断里边,初始为false,所以input初始没有渲染, 但是点击显示时,为什么ref会失效呢?

© 版本信息

  • Ant Design Pro 版本: [e.g. 4.0.0]
  • umi 版本
  • 浏览器环境
  • 开发环境 [e.g. mac OS]

回答

// hooks 执行时异步操作,当你设置显示input之后,有立马执行获取焦点操作,肯定会出问题,试试下面的操作

 useEffect(()=>{

if(inputVisible && ref.current) {

console.log(ref.current);

ref.current?.focus();

}

},[inputVisible])

const showInput = () => {

setInputVisible(true);

};

在github上得到了一个答案是可行的,而且还很简单

setInputVisible(true);执行之后,组件并不会立即重新渲染,而是会继续执行剩下的语句,所以ref.current的值仍然是null,你的那个log应该是打印不出来的。
Input添加autoFocus应该可以在渲染的时候自动获取焦点

以上是 HOOK组件内使用useRef作用于隐藏的Input为什么会导致ref失效? 的全部内容, 来源链接: utcz.com/a/64720.html

回到顶部