如何将自动对焦设置为 select 下拉列表中的输入?

How do I set autofocus to an input that's inside a select dropdown?

我在 select 下拉菜单中有一个输入字段。当用户单击它时,一旦显示下拉列表,我就需要关注该输入框。我尝试使用 refs,但这似乎不起作用。我正在使用 antd 3.26.14 和 React 16.8.6。这是代码:

<Select
  labelInValue
  open={isOpenSelectCategory}
  onDropdownVisibleChange={onDropdownVisibleChange}
  placeholder="Select Category"
  onChange={() => {
    searchDropdownOptions('formCategories', '');
    setCategoryInputValue('');
  }}
  notFoundContent={null}
  dropdownRender={menu => (
                      <>
      <div
        onMouseDown={lockSelectCategoryClose}
        onMouseUp={lockSelectCategoryClose}
        style={{ marginBottom: '10px' }}
      >
        <Input
          value={categoryInputValue}
          ref={inputRef}
          onChange={event => {
            searchDropdownOptions(
              'formCategories',
              event.target.value,
            );
            setCategoryInputValue(event.target.value);
          }}
          placeholder="Search category or create new one"
        />
...

输入参考的 useEffect:

useEffect(() => {
  if (inputRef.current) inputRef.current.focus();
}, [inputRef]);

我已经尝试了上述 useEffect 的变体,我不是在 inputRef 上监听变化,而是在加载下拉列表时监听变化。但是他们都没有工作。

如有任何帮助,我们将不胜感激...

尝试将 ref={(input) => input && input.focus()}autofocus 属性 结合使用,例如:

<Input
    autofocus
    ref={(input) => input && input.focus()}
...
/>

Here 是 React class 组件的工作堆栈闪电战。

注意:此解决方案的问题在于它将输入集中在任何重新渲染上(这可能不是所希望的)。

另请参阅 了解更多选项。

链接完整示例的代码:

import React, { useFocus } from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Select, Divider, Input } from 'antd';
import { PlusOutlined } from '@ant-design/icons';

const { Option } = Select;

let index = 0;

class App extends React.Component {
  state = {
    items: ['jack', 'lucy'],
    name: '',
  };

  onNameChange = (event) => {
    this.setState({
      name: event.target.value,
    });
  };

  addItem = () => {
    console.log('addItem');
    const { items, name } = this.state;
    this.setState({
      items: [...items, name || `New item ${index++}`],
      name: '',
    });
  };

  render() {
    // const [inputRef, setInputFocus] = useFocus();
    const { items, name } = this.state;
    return (
      <Select
        style={{ width: 240 }}
        placeholder="custom dropdown render"
        dropdownRender={(menu) => (
          <div>
            {menu}
            <Divider style={{ margin: '4px 0' }} />
            <div style={{ display: 'flex', flexWrap: 'nowrap', padding: 8 }}>
              <Input
                autofocus
                ref={(input) => input && input.focus()}
                style={{ flex: 'auto' }}
                value={name}
                onChange={this.onNameChange}
              />
              <a
                style={{
                  flex: 'none',
                  padding: '8px',
                  display: 'block',
                  cursor: 'pointer',
                }}
                onClick={this.addItem}
              >
                <PlusOutlined /> Add item
              </a>
            </div>
          </div>
        )}
      >
        {items.map((item) => (
          <Option key={item}>{item}</Option>
        ))}
      </Select>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('container'));