【问题标题】:How to stop inner onClick event's propogating into outer onSubmit event in React?如何停止内部 onClick 事件传播到 React 中的外部 onSubmit 事件?
【发布时间】:2020-11-10 14:42:18
【问题描述】:

我有一个 React 应用程序,我在其中从 Unsplash api 检索数据。我实现了一个带有多个输入字段和按钮的表单,以便从这个 api 请求数据。

除了我的输入字段,我还创建了一个按钮并在onClick 事件上传递了一个函数clearInputField,它只需单击一下即可清除输入字段的值。但是,在此实施之后,该事件开始冒泡并触发我的表单上的onSubmit 事件。为了防止这种行为,我在clearInputField 函数中传递了e.preventDefault()

现在一切正常,除了我不能使用 ENTER 键,如果我想触发表单提交。相反,ENTER 键现在触发clearInputField 函数。

在给定的情况下,我如何在保留 clearInputField 函数的功能的同时让 ENTER 键触发 onSubmit 事件?

export const SearchImages = (props) => {
  const [query, setQuery] = useState("");
  const [images, setImages] = useState([]);
  const [imagesTotal, setImagesTotal] = useState(0);
  const [inputError, setInputError] = useState(false);
  const [noResultsError, setNoResultsError] = useState(false);
  const [excessInputError, setExcessInputError] = useState(false);
  const [topLoader, setTopLoader] = useState(false);
  const [bottomLoader, setBottomLoader] = useState(false);
  const focusOnSearch = useRef(null);


  const handleSubmit = (e) => {
    if (query.length === 0) {
      e.preventDefault();
      setInputError(true);
    } else if (query.length > 50) {
      e.preventDefault();
      setInputError(false);
      setExcessInputError(true);
    } else {
      setInputError(false);
      setExcessInputError(false);
      setTopLoader(true);
      searchPhotos(e);
      props.addSavedQuery(query);
    }
  };


  const searchPhotos = async (e) => {
    e.preventDefault();
    setNoResultsError(false);
    UnsplashAccessKey.search
      .photos(query, 1, 10)
      .then(toJson)
      .then((json) => {
        setTopLoader(false);
        setImagesTotal(json.total);
        if (json.results <= 0) {
          setNoResultsError(true);
        } else {
          setImages(json.results);
        }
      });
  };

  const clearInputField = (e) => {
    e.preventDefault();
    setQuery("");
    stopPropagation(e);
  };

  return (
      <form className="search-form" onSubmit={handleSubmit}>
        <div className="search-form__input--wrapper">
          <input
            type="text"
            name="query"
            placeholder='Use keywords, ex: "phone"'
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            ref={focusOnSearch}
            className="search-form__input"
          />
          <button className="search-form__btn--clear" onClick={clearInputField}>
            &#88;
          </button>
        </div>

        <button type="submit" className="search-form__btn--submit">
          Search
        </button>
        <span
          className="search-form__warning"
          style={
            inputError || excessInputError
              ? { display: "block" }
              : { display: "none" }
          }>
          {inputError
            ? "The search field should not stay empty!"
            : "" || excessInputError
            ? "50 characters max length exceeded. Use concise keywords. This is not a poetry app!"
            : ""}
        </span>
      </form>
}

【问题讨论】:

    标签: reactjs event-handling


    【解决方案1】:

    尝试添加type="button"

    <button className="search-form__btn--clear" type="button" onClick={clearInputField}>
      &#88;
    </button>
    

    【讨论】:

    • 那行不通。但是,例如,如果我将其更改为 type="search",这会附带一个 x 按钮的默认实现,该按钮会清除输入字段并且可以触发表单提交。不幸的是,它不兼容浏览器。所以,我宁愿拥有自己的自定义实现
    • 我说的是按钮的类型,你似乎是在说输入的类型。
    【解决方案2】:

    使用stopPropagation事件的方法。

    e.stopPropagation();
    

    【讨论】:

    • 抱歉,它不适用于 React 的合成事件。
    • 你的意思是,clearInputField 中的 e.stopPropagation 不起作用?
    • 没错,无论我使用与否,行为都保持不变。
    猜你喜欢
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    • 2014-09-29
    • 2014-05-06
    相关资源
    最近更新 更多