我有一个状态为“ text”的TextInput组件,代表其值。另外,我还有另一个组件UsernameTextInput,它包装TextInput并包含状态“ isUsernameAvailable”,该状态指示是否允许将文本输入的当前值写入我的数据库。
由于useState是异步的,因此有时当用户真正快速键入时,与键入的用户名相对应的isUsernameAvailable是错误的。例如,用户名“ tarantino”不可用,但是有时,在我当前的代码中,是因为useState是async,并且我没有正确处理它...
有什么办法可以做到同步吗?
这是我当前的代码:
function UsernameInput(props) {
const [isUsernameAvailable, setIsUsernameAvailable] = useState(undefined);
const usernameInputRef = useRef(null);
const previousValues = useRef(null);
const checkUsername = async () => {
const { firebase } = props;
// Get the username
const username = usernameInputRef.current.getText();
// Check if the username is valid and available on the database
const isUsernameAvailable = validateUsername(username) &&
(await firebase.isUsernameAvailable(username));
setIsUsernameAvailable(isUsernameAvailable);
};
useEffect(() => {
// Get the username from the text input
const username = usernameInputRef.current.getText();
if (
previousValues.current?.username !== username &&
previousValues.current?.isUsernameAvailable !== isUsernameAvailable
) {
console.log(`${username} - ${isUsernameAvailable}`)
// Update previousValues reference
previousValues.current = { username, isUsernameAvailable };
}
});
return (
<TextInput
ref={usernameInputRef}
onChange={checkUsername}
/>
);
}
TextInput伪代码
TextInput(props, ref) {
const getTextInput = () => text;
const [text, setText] = useState(null)
useEffect(() => {
const { onChange } = props;
if(text) onChange();
}, [text]);
return <NativeTextInput value={text} onChange={(e) => setText(e.nativeEvent.text)}/>
...
}
编写快速返回用户名“ tarantino”的不同值:
tarantino-true | tarantino-错误
我认为这里的问题是UsernameInput“ isUsernameAvailable”的状态更新速度比TextInput状态“ text”的更新速度快,也许不是错误,但我想是这样。
有什么想法可以解决我的问题吗?谢谢。
您是否考虑过添加去抖动来真正快速地处理键入,并且仅firebase.isUsernameAvailable
在用户停止键入后才调用端点?
const checkUsername = async () => {
const { firebase } = props;
// Get the username
const username = usernameInputRef.current.getText();
// Check if the username is valid and available on the database
const isUsernameAvailable = validateUsername(username) && (await firebase.isUsernameAvailable(username));
setIsUsernameAvailable(isUsernameAvailable);
};
// The debounced function that you call instead of checkUsername
const debouncedCheck = debounce(checkUsername, 500);
我看不出对await
每个键击都是好的习惯,更不用说遇到诸如您所经历的错误之类的错误的可能性了。
编辑:
而不是尝试调用onChange
propuseEffect
来代替。
TextInput(props, ref) {
const getTextInput = () => text;
const [text, setText] = useState(null)
const handleChange = async (value) => {
const { onChange } = props;
setText(value);
await onChange(value);
}
return <NativeTextInput value={text} onChangeText={handleChange}/>
...
}
这样,您无需usernameInputRef.current.getText();
在checkUsername
方法中执行此操作,而可以仅使用username
传入的值作为参数。
const checkUsername = async (username) => {
const { firebase } = props;
// Check if the username is valid and available on the database
const isUsernameAvailable = validateUsername(username) && (await firebase.isUsernameAvailable(username));
setIsUsernameAvailable(isUsernameAvailable);
};
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句