Reputation: 105
I au using elasticsearch to do searching in my view (ReactJs). I created a function handleChange to change the state of the data in the table according to what I am searching. so I did this so far in my code :
var esClient = new elasticsearch.Client({
host: 'localhost:9200',
log: 'info'
});
class MesExtraits extends Component {
constructor() {
super();
this.state = {
MP3info: [],
searchText: '',
}
}
updateSearch = (evt) => {
this.setState({ searchText: evt.target.value, });
var searchQ = evt.target.value;
var search_queryES = "titre:" + searchQ + "*"
esClient.search({
q: search_queryES
}).then(function (body) {
this.setState({ MP3info: body.hits.hits.map(i => i._source) })
console.log(this.state.MP3info)
console.log(body.hits.hits.map(i => i._source))
}.bind(this), function (error) {
console.trace(error.message);
});
};
render() {
const { MP3info } = this.state;
return (
<div>
<SearchBox styleName="gx-d-none gx-d-lg-block gx-lt-icon-search-bar-lg"
placeholder="Search in app..."
onChange={this.updateSearch.bind(this)}
value={this.state.searchText}
/>
<Paper className={classes.root}>
<Table className={classes.table} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell><IntlMessages id="MP3.titre" /></TableCell>
<TableCell align="left"><IntlMessages id="MP3.descfiption" /></TableCell>
<TableCell align="left"><IntlMessages id="MP3.langue" /></TableCell>
<TableCell align="left"><IntlMessages id="MP3.stats" /></TableCell>
</TableRow>
</TableHead>
<TableBody>
{MP3info.map(row => (
<TableRow key={row.titre}>
<TableCell component="th" scope="row">
{row.titre}
</TableCell>
<TableCell align="left">{row.description}</TableCell>
<TableCell align="left">{row.langue}</TableCell>
<TableCell align="left"> <span id={row.idMedia} onClick={this.onClickPoup}><i class="icon icon-chart" /> </span> </TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Paper>
</div>
);
}
}
The problem is when I console.log(this.state.MP3info)
after setState for MP3info it is not changing.
Any help would be appreciated.
Upvotes: 2
Views: 45
Reputation: 1178
After calling setState, you cannot expect the state to be updated immediately since setState is an asynchronous operation.
However, there is an optional 2nd parameter of a callback function which you can use in setState, if you want to do something immediately after updating the state.
this.setState({
value: newStateValue,
}, () => {
const { value } = this.state; // access the updated value here
})
Please follow this beautiful explanation of how setState works! link
Also:
React docs recommend that you use the lifecycle events.
Here’s why.
PureComponent
and shouldComponentUpdate
can be used to tune up a component’s performance. They work by preventing lifecycle methods from firing when props and state haven’t changed.
The
setState
callback fires regardless of whatshouldComponentUpdate
returns. So, thesetState
callback will fire, even when state hasn’t changed.
So.. Don’t be afraid to use the setState callback. It’s there for a reason. But when you do, keep an eye on shouldComponentUpdate, if you see any shiftiness.
Upvotes: 2
Reputation: 1490
setState
is asynchronous.
so it will work like this:
this.setState({ MP3info: body.hits.hits.map(i => i._source) }, () => {
console.log(this.state.MP3info)
})
from documentation:
setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied.
Upvotes: 4