Javascript 反应本机useState同步
我有一个组件TextInput,其状态为“text”,表示其值。另外,我还有一个组件UsernameTextInput,它包装了TextInput并包含一个状态“isUsernameAvailable”,它指示是否允许在我的数据库中写入文本输入的当前值 由于useState是异步的,有时当用户键入的速度非常快时,与键入的用户名相对应的isUsernameAvailable是错误的。例如,用户名“tarantino”不可用,但有时,在我当前的代码中,它是可用的,因为useState是异步的,我没有正确处理它 有什么方法可以同步吗 这是我目前的代码:Javascript 反应本机useState同步,javascript,reactjs,react-native,asynchronous,async-await,Javascript,Reactjs,React Native,Asynchronous,Async Await,我有一个组件TextInput,其状态为“text”,表示其值。另外,我还有一个组件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}
/>
);
}
函数UsernameInput(props){
const[isUsernameAvailable,setIsUsernameAvailable]=useState(未定义);
const usernameInputRef=useRef(null);
const previousValues=useRef(null);
const checkUsername=async()=>{
const{firebase}=props;
//获取用户名
const username=usernameInputRef.current.getText();
//检查用户名是否有效且在数据库中可用
const isusernameavable=validateUsername(用户名)&&
(等待firebase.isUsernameAvailable(用户名));
setIsUsernameAvailable(isUsernameAvailable);
};
useffect(()=>{
//从文本输入中获取用户名
const username=usernameInputRef.current.getText();
如果(
previousValues.current?.username!==用户名&&
previousValues.current?.isUsernameAvailable!==isUsernameAvailable
) {
console.log(`${username}-${isUsernameAvailable}`)
//更新以前的值引用
previousValues.current={username,isUsernameAvailable};
}
});
返回(
);
}
文本输入伪码
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)}/>
...
}
TextInput(道具,参考){
常量getput=()=>文本;
const[text,setText]=useState(null)
useffect(()=>{
const{onChange}=props;
if(text)onChange();
},[正文];
return setText(e.nativeEvent.text)}/>
...
}
写入fast会为用户名“tarantino”返回不同的值:
塔伦蒂诺-真|
塔伦蒂诺-错
我认为这里的问题是UsernameInput“isUsernameAvailable”的状态更新速度比TextInput状态“text”快,可能不是错误,但我认为是错误
有什么办法解决我的问题吗?谢谢。您是否考虑过添加一个可快速处理键入操作,并且仅在用户停止键入后调用
firebase.isusernameavable
端点
const checkUsername=async()=>{
const{firebase}=props;
//获取用户名
const username=usernameInputRef.current.getText();
//检查用户名是否有效且在数据库中可用
const isUsernameAvailable=validateUsername(用户名)和&(wait firebase.isUsernameAvailable(用户名));
setIsUsernameAvailable(isUsernameAvailable);
};
//您调用的取消公告的函数,而不是checkUsername
const debouncedCheck=debounce(checkUsername,500);
我不认为等待每一次击键都是一种好的做法,更不用说遇到错误的可能性了,比如你正在经历的错误
编辑:
不要在useffect
中调用onChange
属性,而要尝试此操作
TextInput(道具,参考){
常量getput=()=>文本;
const[text,setText]=useState(null)
常量handleChange=async(值)=>{
const{onChange}=props;
setText(值);
等待一次改变(价值);
}
返回
...
}
这样做,而不是这样做usernameInputRef.current.getText()
在checkUsername
方法中,只需使用作为参数传入的username
值即可
const checkUsername=async(username)=>{
const{firebase}=props;
//检查用户名是否有效且在数据库中可用
const isUsernameAvailable=validateUsername(用户名)和&(wait firebase.isUsernameAvailable(用户名));
setIsUsernameAvailable(isUsernameAvailable);
};
我这样做是因为我想实时显示用户名的可用性。我还看到您正在将onChange
道具传递到TextInput
组件中,但您没有在NativeInput
中的任何地方调用它。伪代码不完整,它是在useffect中调用的,当文本状态更新时。我会更新它。我已经测试了取消公告的呼叫,它工作得很好!所以它基本上是停止执行,直到它没有被调用,然后,在一段延迟后,调用原始函数,对吗?我想我的问题解决了!非常感谢。是的,这是总的想法。很高兴我能帮忙!