事件侦听器之间的状态未按预期更新
State Not Updating As Expected Between Event Listeners
我有两个输入。
Email Address
First Name
初始加载时,名字被隐藏。
点击电子邮件地址输入,将隐藏 div 并显示名字输入。
它还会在输入上方隐藏一个 div 并且输入将填充 space.
现在,我正在寻找的功能是在用户单击电子邮件地址输入后,然后用户单击名字,名字不应该消失,div 到 return .
为此,目前,我在 onBlur
事件侦听器上添加了 lodash 去抖动延迟,以等待查看用户是否专注于名字输入。
我有一个状态变量 onBlurWait
,默认为 false
,并在用户关注名字输入时更新为 true
。
关注名字输入,调用onBlur
事件侦听器来检查onBlurWait
状态的值。现在这个听众只是 return 一个 console.log
或 onBlurWait
.
电子邮件地址输入的 onBlur
似乎在名字输入的 onFocus
之前被调用。所以似乎 onBlurWait
状态没有得到更新,所以 onBlur
事件侦听器中的 console.log
将 return 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;
考虑简化一下,你想多了。
onFocus
和 onBlur
都将 relatedTarget
作为其 SyntheticEvent. In case of onBlur
, relatedTarget
is the DOM element for which the focus is leaving 和 target
.
中的属性之一
您可以做的是处理 blur
事件并将事件的 relatedTarget
属性 与输入引用进行比较。然后您将能够确定焦点是否离开另一个表单元素或页面上的其他 DOM 元素。
我有两个输入。
Email Address
First Name
初始加载时,名字被隐藏。
点击电子邮件地址输入,将隐藏 div 并显示名字输入。 它还会在输入上方隐藏一个 div 并且输入将填充 space.
现在,我正在寻找的功能是在用户单击电子邮件地址输入后,然后用户单击名字,名字不应该消失,div 到 return .
为此,目前,我在 onBlur
事件侦听器上添加了 lodash 去抖动延迟,以等待查看用户是否专注于名字输入。
我有一个状态变量 onBlurWait
,默认为 false
,并在用户关注名字输入时更新为 true
。
关注名字输入,调用onBlur
事件侦听器来检查onBlurWait
状态的值。现在这个听众只是 return 一个 console.log
或 onBlurWait
.
电子邮件地址输入的 onBlur
似乎在名字输入的 onFocus
之前被调用。所以似乎 onBlurWait
状态没有得到更新,所以 onBlur
事件侦听器中的 console.log
将 return 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;
考虑简化一下,你想多了。
onFocus
和 onBlur
都将 relatedTarget
作为其 SyntheticEvent. In case of onBlur
, relatedTarget
is the DOM element for which the focus is leaving 和 target
.
您可以做的是处理 blur
事件并将事件的 relatedTarget
属性 与输入引用进行比较。然后您将能够确定焦点是否离开另一个表单元素或页面上的其他 DOM 元素。