[英]React Native useState sync
我有一个带有状态“文本”的组件 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(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”返回不同的值:
塔伦蒂诺 - 真实 | 塔伦蒂诺 - 假
我认为这里的问题是 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
每一次击键都不是一个好习惯,更不用说遇到诸如您遇到的错误的可能性。
编辑:
与其在useEffect
中调用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);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.