Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.0k views
in Technique[技术] by (71.8m points)

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...
image

?? 复现代码

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]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

 useEffect(()=>{
    if(inputVisible && ref.current) {
        console.log(ref.current);
        ref.current?.focus();
    }
 },[inputVisible])
 const showInput = () => {
    setInputVisible(true);
  };
  

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...