繁体   English   中英

在 React 受控组件中清除 datalist 输入 onClick

[英]Clear datalist input onClick in React controlled component

我有一个 html5 输入和一个 React 控制组件内的关联数据列表。 我想在单击输入字段或接收焦点时清除文本,以便显示所有选项以供选择。 我在这个问题中遵循了 Alfred 的出色回答,但无法在 React 控制组件中获得完全相同的结果。 不幸的是,在 onClick 处理程序中调用 blur 会阻止我的用户输入多个字符,因为焦点(当然)丢失了。

每当单击文本框时,如何保持用户键入但清除文本并显示全套选项的能力?

import React, { useState } from "react";

const MyForm = () => {
  const [options, setOptions] = useState(["Apples", "Oranges", "Bananas", "Grapes"]);

  const handleChange = (event) => {
    event.target.blur();
  };

  const clear = (event) => {
    event.target.value = "";
  };

  return (
    <>
      <input
        type="input"
        list="optionsList"
        onChange={handleChange}
        onFocus={clear}
        placeholder="Select an option"
      />
      <datalist id="optionsList">
        {options.map((o) => (
          <option key={o}>{o}</option>
        ))}
      </datalist>
    </>
  );
};

export default MyForm;

请注意,我还尝试了一个调用 clear onClick 而不是 onFocus 的版本。 这使我无需在 handleChanges 中调用 blur() 以解决键入问题。 但是,这需要我单击两次才能查看完整的选项集,因为选项列表似乎是在清除框之前显示的。

看到你对我的一个问题的评论,所以我想我会把它贴在这里作为答案。

根据您的用例,这是我认为您需要的

import React, { useState } from "react";

const MyForm = () => {
  const [options, setOptions] = useState(["Apples", "Oranges", "Bananas", "Grapes"]);

  const handleChange = (event) => {
    if (!event.nativeEvent.inputType) {
      event.target.blur();
    }
  };

  const clear = (event) => {
    event.target.value = "";
  };

  return (
    <>
      <input
        type="input"
        list="optionsList"
        onChange={handleChange}
        onClick={clear}
        onFocus={clear}
        placeholder="Select an option"
      />
      <datalist id="optionsList">
        {options.map((o) => (
          <option key={o}>{o}</option>
        ))}
      </datalist>
    </>
  );
};

export default MyForm;

为了防止handleChange正常阻塞文本输入,您必须检查event.nativeEvent.inputType ,因为单击datalist触发的onChange不会有inputType值。 因此,在这种情况下,我们将仅在由datalist填充时执行输入模糊,并为任何其他事件保持焦点。

我还添加了一个额外的onClick处理程序来清除输入,无论输入是否已经成为焦点。

我猜您实际上希望将input值作为 state,而不是options

因此可能的受控组件实现应该是:

const options = ["Apples", "Oranges", "Bananas", "Grapes"];

const EMPTY_INPUT = "";

const MyForm = () => {
  const [value, setValue] = useState(EMPTY_INPUT);

  const onFocusClear = () => {
    setValue(EMPTY_INPUT);
  };

  const onChange = ({ target: { value } }) => {
    setValue(value);
  };

  return (
    <>
      <input
        value={value}
        type="input"
        list="optionsList"
        onChange={onChange}
        onFocus={onFocusClear}
        placeholder="Select an option"
      />
      <datalist id="optionsList">
        {options.map((o) => (
          <option key={o}>{o}</option>
        ))}
      </datalist>
      Value: {value}
    </>
  );
};

编辑数据列表示例


通过删除onChange使其成为不受控制的组件非常简单。 现在您在ref.current.value中有了输入值(不是那么有用的用例,只是一个示例)。

const MyForm = () => {
  const inputRef = useRef();

  const onFocusClear = () => {
    inputRef.current.value = ''
  };

  return (
    <>
      <input
        type="input"
        list="optionsList"
        onFocus={onFocusClear}
        placeholder="Select an option"
      />
      <datalist id="optionsList">
        {options.map((o) => (
          <option key={o}>{o}</option>
        ))}
      </datalist>
    </>
  );
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM