In my react app on user register page am trying to check weather a username already exist or not my code is
checkUserName = (e) => {
this.setState({username:e.target.value});
let username = this.state.username;
db.collection("users").doc(username).get()
.then((snapshot)=>{
if(snapshot.exists)
{
this.setState({usernameExistError:"show"}); *//this is classname of error div*
this.setState({isUsernameOk:false})
console.log(this.state.usernameExistError,this.state.isUsernameOk);
}
else
{
this.setState({usernameExistError:"hide"});
this.setState({isUsernameOk:true})
console.log(this.state.usernameExistError,this.state.isUsernameOk);
}
})
}
all works fine when i check console.But The Problem is when i pressed a key in my input , state username is blank and when i type the second letter then the username state reads the first letter. so when an existing username is found only when the data is like "EXISTINGUSERNAME" + SOME_KEY_PRESS How can i solve this...Thanks In Advance
Because you use the state
at the moment when it is still old, since the setState()
occurs asynchronously.
To solve your problem, you should set the value to a variable and use it in the future:
const { target: { value: username } } = e;
this.setState({ username });
db.collection("users").doc(username).get()
// ...the rest of code
Or perform all actions depending on the current state in the callback:
this.setState({ username: e.target.value }, () => {
db.collection("users").doc(this.state.username).get()
// ...the rest of code
});
Example of setState()
async behavior:
class TestComponent extends React.Component {
state = {
data: 1
}
onClick = () => {
console.log(`data before set: ${this.state.data}`);
const newData = this.state.data + 1;
this.setState(
{ data: newData },
() => console.log(`data in callback: ${newData}`)
);
console.log(`data after set: ${this.state.data}`);
console.log(`actual current data: ${newData}`);
}
render() {
return <div onClick={this.onClick}>Click Me!</div>;
}
};
ReactDOM.render(<TestComponent />, document.getElementById('app'));
#app {
cursor: pointer;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="app"></div>