I have a weird behaviour from my "TextInput". I am trying to filter a ListView based on a TextInput entry:
export default class SearchTabScreen1 extends Component {
constructor(props) {
super(props);
this.state = {
searchText:'',
data:[]
};
}
setSearchText(event) {
var reset = realm.objects('User');
if (this.state.data !== reset){
this.setState({
data:realm.objects('User')
});
const searchText = event.nativeEvent.text;
this.setState({searchText:searchText});
console.log(this.state.searchText);
var searchString = this.state.searchText;
if(searchString != ""){
let searchResult = realm.objects('User').filtered('name BEGINSWITH[c] $0', searchString);
var filteredData = searchResult;
this.setState({
data : filteredData
});
console.log("FILTERED", filteredData);
}
}
}
render() {
return (
<View style={{flex: 1, padding: 20}}>
<TextInput
ref="recherche"
placeholder="Search"
autoCorrect={true}
returnKeyLabel="search"
underlineColorAndroid="black"
value = {this.state.searchText}
onChange={this.setSearchText.bind(this)}
/>
<ListViewDico
navigator={this.props.navigator}
dataFromParent={this.state.data}
/>
</View>
The problem is when I type an 'L', for example, in the TextInput the log: console.log(this.state.searchText);
shows nothing.
The log shows this 'L' only after I typed a second character (whatever it is) and so on.
I always get a response at a "t+1 entry".
I would appreciate some help, thanks.
The reason that it happens is that setState
doesn't immediately mutate the state, but takes time and as Javascript
is async your console.log()
gets executed before the state is mutated and hence you don't get the updated value, only when it is executed the next time you see the old value. The solution is to call the console.log()
in the setState callback
.
this.setState({searchText:searchText}, () => {
console.log(this.state.searchText);
});
Code:
setSearchText(event) {
var reset = realm.objects('User');
if (this.state.data !== reset){
this.setState({
data:realm.objects('User')
});
const searchText = event.nativeEvent.text;
this.setState({searchText:searchText}, function() {
console.log(this.state.searchText);
});
var searchString = searchText;
if(searchString != ""){
let searchResult = realm.objects('User').filtered('name BEGINSWITH[c] $0', searchString);
var filteredData = searchResult;
this.setState({
data : filteredData
}, function() {
console.log("FILTERED", filteredData);
});
}
}
}