Состояние не обновляется, как ожидается между прослушивателями событий - PullRequest
0 голосов
/ 15 марта 2019

У меня есть два входа.

Email Address

First Name

При начальной загрузке имя скрыто.

Нажатие наВвод адреса электронной почты, будет скрывать div и показывать имя ввода.Он также будет скрывать div над входами, и входы будут заполнять это пространство.

Теперь, функциональность, которую я ищу, заключается в том, что пользователь нажимает на ввод адреса электронной почты, а затем пользователь нажимает первое имяимя не должно исчезать, а div возвращаться.

Для этого на данный момент я добавил задержку отладки lodash в обработчике событий onBlur, чтобы дождаться, когда пользователь сосредоточится на первомВвод имени.

У меня есть переменная состояния onBlurWait, которая по умолчанию false и обновляется до true, когда пользователь фокусируется на вводе имени.

Сосредоточение на первомпри вводе имени вызывает прослушиватель событий onBlur для проверки значения состояния onBlurWait.Этот слушатель пока только возвращает console.log или onBlurWait.

. onBlur на вводе адреса электронной почты, кажется, вызывается до onFocus ввода имени.Похоже, что состояние onBlurWait не обновляется, поэтому console.log в прослушивателе событий onBlur вернет 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;

1 Ответ

1 голос
/ 15 марта 2019

Подумайте об упрощении, вы слишком обдумываете.

onFocus и onBlur оба получают relatedTarget как одно из свойств в SyntheticEvent .В случае onBlur, relatedTarget - это элемент DOM , для которого фокус покидает target.

Что вы можете сделать, это обработать событие blur и сравнитьrelatedTarget свойство события для ввода ссылок.Затем вы сможете выяснить, уходит ли фокус на другой элемент формы или какой-либо другой элемент DOM на странице.

...