Parent re-rendering causes AsyncTypeahead to think request is done too early
See original GitHub issueVersion
1.2.0
Steps to reproduce
I have a that contains an AsyncTypeahead. As part of the onSearch
handler, it calls setState
. This ends up triggering a re-rendering of Parent, which falls through to componentWillReceiveProps
in src/containers/asyncContainer.js
. In that function requestPending
gets set to false prematurely.
class Parent extends React.Component {
constructor() {
super()
this.handleSearch = this.handleSearch.bind(this)
this.state = { options: [] }
}
handleSearch() {
const resultWillBe = [ 'bears', 'beets', 'battlestar galactica'];
// If this is present, it triggers the bug
this.setState({ arbitrary: 'setting' })
setTimeout(() => this.setState({ options: resultWillBe }), 2000)
}
render() {
return <AsyncTypeahead
minLength={ 1 }
name="wut"
onSearch={ this.handleSearch }
options={ this.state.options }
/>
}
}
Expected Behavior
The AsyncTypeahead component should pop the “searching” element, replacing it with the list of results when they come back. This happens if useCache
is true. If useCache
is false, the list will show up correctly, but the little pop up that would have the results visibly flashes through various other things first.
Actual Behavior
“Type to search” gets popped and gets replaced with “No matches found”. The list of results never shows up.
First guess at a fix would be that if we can assume that the onSearch
passed to the AsyncTypeahead component returns a Promise, then the call to set requestPending
state to false could happen in a then
call on that Promise. I don’t know if that will blow other things up though.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:7
- Comments:10 (3 by maintainers)
I think the only real solution here is to track the request state externally and pass it into the async component as a prop. I thought I could have the component guess at the state, but it’s clearly buggy and really should be explicit.
The overhead would be minimal: just a
setState
call before the request is made, and another one when the results come back. That state would be passed to theisLoading
prop of the component.Note that this isn’t a workaround; it will require changes to the component.
Thanks for the detailed report. I can repro. Will look into a fix.