【问题标题】:State Not Updating As Expected Between Event Listeners事件侦听器之间的状态未按预期更新
【发布时间】:2019-08-06 17:01:42
【问题描述】:

我有两个输入。

Email Address

First Name

在初始加载时,名字是隐藏的。

单击电子邮件地址输入,将隐藏一个 div 并显示名字输入。 它还将在输入上方隐藏一个 div,输入将填充该空间。

现在,我正在寻找的功能是在用户单击电子邮件地址输入后,然后用户单击名字,名字不应该消失并且要返回的 div。

为此,目前,我在 onBlur 事件监听器上添加了一个 lodash debounce 延迟,以等待查看用户是否专注于输入名字。

我有一个状态变量 onBlurWait,默认为 false,当用户关注名字输入时,它会更新为 true

关注名字输入,调用onBlur 事件监听器来检查onBlurWait 状态的值。这个监听器目前只返回一个console.logonBlurWait

电子邮件地址输入中的onBlur 似乎在名字输入的onFocus 之前被调用。所以似乎onBlurWait 状态没有更新,所以onBlur 事件监听器中的console.log 将返回false。

这里有一个CodeSandbox,可以帮助你玩转它,希望你能理解我上面提到的内容。

下面是我的组件

import React, { useState } from "react";
import ReactDOM from "react-dom";
import _ from "lodash";

import InputControl from "./InputControl";

import "./styles.css";

const App = () => {
  const [hideContent, setHideContent] = useState(false);
  const [emailSignUpRef, setEmailSignUpRef] = useState(null);
  const [firstNameSignUpRef, setFirstNameEmailSignUpRef] = useState(null);
  const [onBlurWait, setOnBlurWait] = useState(false);

  let registerEmailInput = null;
  let firstNameInput = null;

  // If you click on email address then on first name, I would expect the console.log below to return true
  // due to when a user focuses on the first name input the handleInputFocus function gets called
  // inside that function, setOnBlurWait(true); is ran updating the value of onBlurWait to true
  // But it seems like it has not actually been updated
  // Now when you click on email address to first name, back to email address and first name again, the console log now returns true?
  const waitOnUpdateState = _.debounce(() => console.log(onBlurWait), 2000);
  const hideContentAfterState = _.debounce(
    () =>
      setHideContent(
        emailSignUpRef.length > 0 || firstNameSignUpRef.length > 0 || onBlurWait
      ),
    2000
  );

  const handleOnFocus = event => {
    setEmailSignUpRef(registerEmailInput.value);
    setFirstNameEmailSignUpRef(firstNameInput.value);
    setHideContent(true);
  };

  const handleOnInput = () => {
    setEmailSignUpRef(registerEmailInput.value);
    setFirstNameEmailSignUpRef(firstNameInput.value);
  };

  const handleInputFocus = () => {
    console.log("clicked on first name, onBlurWait should be set as true");
    setOnBlurWait(true);
  };

  const handleOnBlur = () => {
    console.log("clicked away from email address");
    // waitOnUpdateState is just a test function to return a console log, hideContentAfterState is what is going to be used
    waitOnUpdateState();
    hideContentAfterState();
  };

  return (
    <div className="App">
      <div className={hideContent ? "hidden" : "visible"} />
      <InputControl
        autoComplete="off"
        refProp={input => {
          registerEmailInput = input;
        }}
        onInput={handleOnInput}
        onFocus={handleOnFocus}
        onBlur={handleOnBlur}
        type="text"
        name="emailAddressRegister"
        placeholder="Email address"
        label="Email Address"
      />
      <InputControl
        className={
          !hideContent ? "InputControl--hidden" : "InputControl--visible"
        }
        autoComplete="off"
        refProp={input => {
          firstNameInput = input;
        }}
        onInput={handleOnInput}
        onFocus={handleInputFocus}
        type="text"
        name="firstName"
        placeholder="First Name"
        label="First Name"
      />
      <input type="submit" value="Submit" />
    </div>
  );
};

export default App;

【问题讨论】:

    标签: javascript reactjs lodash react-hooks


    【解决方案1】:

    考虑让它更简单,你想多了。

    onFocusonBlur 都接收relatedTarget 作为其SyntheticEvent 中的属性之一。对于onBlurrelatedTarget 是 DOM 元素 for which the focus is leaving target

    您可以做的是处理blur 事件并将事件的relatedTarget 属性与输入引用进行比较。然后您将能够确定焦点是离开页面上的另一个表单元素还是其他一些 DOM 元素。

    【讨论】:

    • 感谢您的回答,当将 event 作为参数传递 onBlur 时,event.relatedTarget 将返回为 null?我已经更新了 CodeSandbox,所以你可以看到
    • 实际上,刚刚意识到它是null,因为我单击的是正文而不是元素。再次感谢!有用的信息:)
    猜你喜欢
    • 2021-07-18
    • 1970-01-01
    • 2020-05-09
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多