I have a list of ~5000 elements and I would like to filter it by searchPhrase
which is given by user.
Usually user types first letter of filtering phrase, then second and then third.
For example user types 'a'
, then 'ab'
, then 'abc'
.
I'm trying to use reactjs/reselect library to improve filtering performance. I have used this lib as in Example on readme: Example I have changed this method:
export const getVisibleTodos = createSelector(
[ getVisibilityFilter, getTodos ],
(visibilityFilter, todos) => {
switch (visibilityFilter) {
case 'SHOW_ALL':
return todos
case 'SHOW_COMPLETED':
return todos.filter(t => t.completed)
case 'SHOW_ACTIVE':
return todos.filter(t => !t.completed)
}
}
)
to that implementation:
export const getVisibleTodos = createSelector(
[getSearchPhrase, getTodos],
(searchPhrase, todos) => {
return todos.filter((x) => {
return x.firstName.indexOf(searchPhrase) >= 0;
});
}
)
I noticed that each time when user types next letter todos.length
property is the same.
Shouldn't todos.length
be shorter when searchPhrase
is longer?
I think that performance without reactjs/reselect is the same.
Is that possibility to filter shorter todos
list when previous searchPhrase
is substring of actual searchPhrase
?
That's not how reselect improves performance: the actual filtering of the todos takes exactly the same time with or without reselect.
What reselect does for you is to memoize the filtering: as long as getSearchPhrase
and getTodos
return the same value (as defined by ===
equality), calling getVisibleTodos
multiple times does the filtering only once.
This is important in a complex app, where you have many unrelated changes to redux state: without reselect any change to the state would result in all selectors being run again, even if that part of the state is unchanged.