I am creating a React App that makes search request to server as the user types. I want to debounce this search request, but not sure how to implement it in my existing code:
Mobx Store:
// function which initiates a fetch request to server
@action searchPlanet = async (event) => {
this.searchString = event.target.value;
this.planets = await getPlanets(this.searchString);
}
React Component calling searchPlanet
:
const Search = observer(({ store }) => {
const planetList = toJS(store.planets);
return (
<div>
<div className={style.search_container}>
<input type="text" id="search" onChange={e => store.searchPlanet(e)} value={store.searchString} placeholder="search planet" />
</div>
</div>
)
})
I can't use debounce function directly on onChange
because that will also delay the re-rendering of Search ponent, so the user will see the typed text after some time. But I am not able to figure out to how to implement debounce function in my store? I can do something like:
import _ from lodash
@action searchPlanet = async (event) => {
this.searchString = event.target.value;
this.planets = await getPlanets(this.searchString);
}
debounceSearch = _.debounce(this.searchPlanet, 250);
The issue with this is that I can't call debounceSearch
directly from Search
ponent because of reason mentioned above. But I want to debounce getPlanets
function, which returns a promise (I am not sure if Lodash debounce function can return the promise returned by the wrapped function)?
I am creating a React App that makes search request to server as the user types. I want to debounce this search request, but not sure how to implement it in my existing code:
Mobx Store:
// function which initiates a fetch request to server
@action searchPlanet = async (event) => {
this.searchString = event.target.value;
this.planets = await getPlanets(this.searchString);
}
React Component calling searchPlanet
:
const Search = observer(({ store }) => {
const planetList = toJS(store.planets);
return (
<div>
<div className={style.search_container}>
<input type="text" id="search" onChange={e => store.searchPlanet(e)} value={store.searchString} placeholder="search planet" />
</div>
</div>
)
})
I can't use debounce function directly on onChange
because that will also delay the re-rendering of Search ponent, so the user will see the typed text after some time. But I am not able to figure out to how to implement debounce function in my store? I can do something like:
import _ from lodash
@action searchPlanet = async (event) => {
this.searchString = event.target.value;
this.planets = await getPlanets(this.searchString);
}
debounceSearch = _.debounce(this.searchPlanet, 250);
The issue with this is that I can't call debounceSearch
directly from Search
ponent because of reason mentioned above. But I want to debounce getPlanets
function, which returns a promise (I am not sure if Lodash debounce function can return the promise returned by the wrapped function)?
1 Answer
Reset to default 7Instead of assigning a value to planets
in your searchPlanet
action, you could do it in the debounced function instead.
Example
@observer
class App extends Component {
@observable value = "";
@observable query = "";
onChange = action(event => {
const { value } = event.target;
this.value = value;
this.search(value);
});
search = debounce(action(query => {
this.query = query;
}), 250);
render() {
const { value, query, onChange } = this;
return (
<div>
<input value={value} onChange={onChange} />
<div>{query}</div>
</div>
);
}
}