我有一个具有状态"text“的组件TextInput,它表示它的值。此外,我还有另一个组件UsernameTextInput,它包装TextInput并包含状态"isUsernameAvailable",它指示是否允许在数据库中写入文本输入的当前值。
由于useState是异步的,有时当用户输入非常快时,对应于类型化用户名的isUsernameAvailable是错误的。例如,用户名"tarantino“不可用,但有时,在我当前的代码中,它是可用的,因为useState是异步的,我没有正确地处理它.
有什么办法让这段时间同步吗?
以下是我的当前代码:
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- false
我认为这里的问题是UsernameInput "isUsernameAvailable“的状态比TextInput状态"text”更新得更快,也许不是错误,但我认为是错误。
有什么办法解决我的问题吗?谢谢。
发布于 2020-09-15 19:56:17
您是否考虑过添加一个脱去来处理类型,并且只在用户停止输入之后才调用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中调用useEffect道具,而是尝试使用这个方法。
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);
};https://stackoverflow.com/questions/63908120
复制相似问题