Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Context
Create a filter context that exposes two methods and one field:
handleFilter: (query: string) => null
addToSkillMap: (skillMap: Record<string, string>) => null
filtersMatches: Set<string> | null
When a skill tree is rendered, a component is rendered that returns null,
<AddToFilter />
. This component (much like<CalculateNodeCount />
, is its own component so that it can perform a potentially expensive computation and subscribe to a context, without having any children that will rerender unnecessarily.This
<AddToFilter />
component iterates recursively through the tree's nodes to generate a map where each entry is{ [skillId]: [treeId] }
. This is the index that theFilterContext
iterates through to see which tree should be displayed.When a user then tries to filter through the tree, via the
handleFilter
method. TheFilterContext
will go through each key and return their respective values. The returned values will then be moved into aSet
so all duplicates are removed.The trees will subscribe to any changes in the filters, and will not display if
filtersMatches
doesn't contain a reference to one of its child skills.Example
There are two trees, one with an
id
oftreeOne
and another with anid
oftreeTwo
.treeOne
has skills with ids:skillOne
,skillTwo
.treeTwo
has skills with ids:skillThree
,skillFour
,skillFive
.After all components have rendered the
skillMap
will look like the following:A user filters the list of skills by entering a query of
skillT
.The skill trees will receive the
filtersMatches
value, which in this case would be['treeOne', 'treeTwo']
and determine whether or not to hide the skill tree, based on whether the tree's id exists within the array. Since both trees match the filter, neither will hide.A user continues filtering with by finishing the query to be
skillThree
. ThefiltersMatches
array will be['treeTwo']
, which means thattreeOne
will become hidden.Considerations
Performance: Whenever the
SkillMap
is updated, a sorted list of the keys will be created and maintained. This means that I can use two binary searches to find the first and last keys that match the query, and pull out the list of values that way.