Reactjs 当输入速度过快时,React输入字段现在不起作用
我有一个简单的组件来检查用户名是否有效。它通过在输入值更改时查询firebase来实现。它有一个问题。当我在输入字段中输入得太快时,输入字段中的值没有足够的时间更改,因此它只会遗漏一些字符。代码如下: 对于状态管理,我使用Recoil.JS 组件代码:Reactjs 当输入速度过快时,React输入字段现在不起作用,reactjs,typescript,recoiljs,Reactjs,Typescript,Recoiljs,我有一个简单的组件来检查用户名是否有效。它通过在输入值更改时查询firebase来实现。它有一个问题。当我在输入字段中输入得太快时,输入字段中的值没有足够的时间更改,因此它只会遗漏一些字符。代码如下: 对于状态管理,我使用Recoil.JS 组件代码: export const UsernameInput = (props: { topLabel: string; bottomLabel?: string; placeholder?: string; className?: st
export const UsernameInput = (props: {
topLabel: string;
bottomLabel?: string;
placeholder?: string;
className?: string;
valueIn: any;
valueOut: any;
valid: any;
validIn: boolean;
}) => {
const usernameRef = db.collection("usernames");
const query = usernameRef.where("username", "==", props.valueIn);
useEffect(() => {
query
.get()
.then((querySnapshot) => {
if (querySnapshot.size >= 1) {
props.valid(false);
} else {
props.valid(true);
}
})
}, [props.valueIn]);
function handleChange(event: any) {
props.valueOut(event.target.value);
}
return (
<InputSkeleton
topLabel={props.topLabel}
bottomLabel={props.bottomLabel}
className={props.className}
>
<div className="input-username">
<input type="text" onChange={handleChange} value={props.valueIn} />
<span className="text">
<span className={props.validIn ? "available" : "taken"}></span>
{props.validIn ? "Available" : "Taken"}
</span>
</div>
</InputSkeleton>
);
};
export const UsernameInput=(道具:{
标签:字符串;
底部标签?:字符串;
占位符?:字符串;
类名?:字符串;
价值单位:任何;
估价输出:任何;
有效期:任何;
validIn:布尔型;
}) => {
const usernameRef=db.collection(“用户名”);
const query=usernameRef.where(“username”、“==”、props.valueIn);
useffect(()=>{
查询
.get()
.然后((querySnapshot)=>{
如果(querySnapshot.size>=1){
道具。有效(假);
}否则{
道具。有效(真);
}
})
},[props.valueIn]);
函数句柄更改(事件:任意){
props.valueOut(event.target.value);
}
返回(
{props.validIn?“可用”:“take”}
);
};
{
setFormD({…formD,用户名:value});
}}
有效={(值:布尔)=>{
setFormD({…formD,usernameValid:value});
}}
validIn={formD.usernameValid}
bottomLabel=“这将是您在xyz.com上的唯一句柄”
/>
创建一个简单的去盎司函数,将函数和时间(以秒为单位)作为参数:
export function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
timeout = null;
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
然后在事件处理程序handleChange函数中使用它:
function handleChange(event: any) {
event.preventDefault();
// This means that you want to update the value after 500 milliseconds, i.e when you're sure that the user has stopped typing. You can extend this time to whatever figure you want
debounce(props.valueOut(event.target.value), 500);
}
将此变量置于
UsernameInput
函数外部
const WAIT_INTERVAL = 1000;
编辑您的手柄更改为此
componentWillMount() {
this.timer = null;
}
function handleChange(event: any) {
clearTimeout(this.timer);
this.timer = setTimeout(props.valueOut(event.target.value), WAIT_INTERVAL);
}
Princewill的想法是正确的,但是实现需要一些调整。具体来说,您需要在多次调用
debounce
时保留计时器句柄,并且debounce
的参数需要是实际函数。使用普通函数并不能做到这一点,因为每次调用都会产生不同的本地超时句柄,并且旧句柄永远不会被取消或更新
我建议调整或使用useHooks中的钩子。这使用useffect来利用React的effect unmounting来清除任何先前设置的超时,并且总体上非常清楚
const{valueIn,valueOut}=props;
const[username,setUsername]=useState(valueIn);
//在每个事件中,更新`username'`
const handleChange=useCallback(
(event:any)=>setUsername(event.target.value),
[设置用户名]
);
//收集对用户名的更改并将debouncedUsername更改为最新
//500毫秒内未进行更改后的值。
const debouncedUsername=useDebounce(用户名,500);
//每次debouncedUsername更改时,运行所需的回调
useffect(()=>{
如果(debouncedUsername!==valueIn){
valueOut(debouncedUsername);
}
},[valueIn、valueOut、debouncedUsername]);
这里的想法是:
用户名更改后触发,但在500毫秒内不会再次更改
此外,您还需要将字段的
值设置为用户名
,而不是中的值
,以便字段能够实时更新,而不是延迟更新。问题仍然存在。问题仍然存在。救命!非常感谢。