1.2.0
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 }
/>
}
}
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.
"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.
I have same problem.
I have a workaround that gets the job done for my project. The containing component has to track a requestPending state as well, and then in its shouldComponentUpdate, I say no if requestPending is true. Haven't hit issues with it, but it's definitely suboptimal.
Thanks for the detailed report. I can repro. Will look into a fix.
@juanpaco can you share what your workaround looks like in your setup?
Same thing happening here, had to ditch the AsyncTypeahead and immediately fetch all the data from the backend.
Not the best solution... hoping for a fix
And btw I've implemented @juanpaco solution, tracking the isLoading prop of the request, but it's not working either...
Having a similar problem. My onSearch function calls setState multiple times since I fetch my results chunk by chunk till they're done. AsyncTypeahead only displays the first call to setState and ignores the rest. Ideally I'd like to be able to incrementally add to state (call setState multiple times) and have AsyncTypeahead update its list each time
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 the isLoading prop of the component.
Note that this isn't a workaround; it will require changes to the component.
The isLoading prop is the perfect solution for this. Thanks!
v2.0.0-rc.1 now requires the use of isLoading. The example has been updated to reflect the new API.