A hook to filter list of objects in React.
npm install usefiltexuseFilter() hook and the filter() function.
useFilter() is the core of the library. It lets you declaratively filter an array of objects in React. You provide a list of objects and a list of filters β the hook handles the rest.
filter() function is a helper to define your filtering rules in a clean and reusable way.
cli
npm install usefiltex
`
Hook API
###
$3
`jsx
useFilter({
list: ,
filters:
})
`
#### π§Ύ Arguments
| Name | Description | Required |
| --------- | ---------------------------------------------------------- | -------- |
| list | The array of objects you want to filter | β
Yes |
| filters | An array of filters that will be used to filter the list | β
Yes |
Example:
`jsx
useFilter({
list: [
{ firstName: "John", lastName: "Doe", age: 28 },
{ firstName: "Alice", lastName: "Johnson", age: 22 },
{ firstName: "Bob", lastName: "Brown", age: 17 },
{ firstName: "Charlie", lastName: "Davis", age: 40 }
],
filters: [
filter("age", (person) => person.age > 25)
]
})
`
> NOTE: To declare a filter use the helper function filter()
> NOTE: The filters do not apply immediately to the given list but we have to apply and activate them with the apply() and activate() methods on the manager.
#### π Return Values
`jsx
const { filtered, manager, getFilter } = useFilter(...)
`
| Name | Description |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| filtered | The filtered list, in sync with the the all the applied and activated filters. |
| manager | An object to manage all the filters: apply them, remove them, toggle, and activate all. |
| getFilter | A function to grab filters. You can get filters by name (e.g. getFilter("filterName")) or all the filters by passing "all" to it (e.g. getFilter("all")). |
> NOTE: The returned filtered list is exposed under the filtered key by default. This is intended as a placeholder, and it's recommended to _rename_ it to something meaningful for the context, e.g. const { filtered: filteredBooks } = useFilter(...)
manager object handles all interactions with your filters.
apply(filterName, payload?) | Marks a filter as active and stores an optional payload. | manager (chainable) |
remove(filterName, payload?) | Deactivates the specified filter and stores an optional payload. | manager (chainable) |
toggle(filterName, payload?) | Toggles the active state of a filter. If it was active, it becomes inactive, and vice-versa. | manager (chainable) |
reset() | Deactivates all filters and clears their active state. | manager (chainable) |
activate() | Applies all active filters to the list and updates the filtered result. | void |
apply(), remove(), toggle() and reset() do not immediately filter the list β they only update the filter state.
activate() to apply the current active filters and update the filtered result.
activate()) return the manager itself, so you can chain calls.
filter() function is used to define filtering rules for useFilter().
name|The identifier of the filter. Used to reference the filter when applying, removing or toggling it.|
filter|A callback function that defines the filtering logic. It receives the current list item (and optionally a payload if passed) and must return true to include the item in the filtered list.|
jsx
const myFilter = filter("minAge", (person, minAge) => person.age >= minAge);
`
In this example:
- name is "minAge".
- The filtering logic keeps only the people whose age is greater than or equal to minAge.
- payload is expected to be a number (minAge) when applying the filter.
Examples - Filtering Books
For the following examples we'll use a list of books:
`jsx
const books = [
{ title: "Harry Potter and the Sorcerer's Stone", author: "J.K. Rowling", genre: "Fantasy", year: 1997 },
{ title: "The Hobbit", author: "J.R.R. Tolkien", genre: "Fantasy", year: 1937 },
{ title: "1984", author: "George Orwell", genre: "Dystopian", year: 1949 },
{ title: "To Kill a Mockingbird", author: "Harper Lee", genre: "Classic", year: 1960 },
{ title: "Sapiens", author: "Yuval Noah Harari", genre: "Non-fiction", year: 2011 }
];
`
Let's create also a component to display the list of books:
`jsx
function FilteredBooks({ books }) {
return (
{books.map((book) => (
{book.title} - {book.year}
{book.author}
{book.genre}
))}
)
}
`
$3
Let's imagine we want to obtain all the books published _after the year 2000_:
`jsx
import { useFilter, filter } from 'usefiltex';
function Books() {
const { filtered: filteredBooks, manager } = useFilter({
// list to filter
list: books,
filters: [
// declare our filters
filter("year", (book) => book.year > 2000)
]
})
const filter = () => {
manager
.apply("year") // apply the 'year' filter
.activate() // activate all the applied filters
}
return (
)
}
`
When the user clicks on the _Filter_ button, the declared "year" filter will be applied and immediately activated, showing only _Sapiens - by Yuval Noah Harari_.
> NOTE: Use function expressions with const instead of using function declarations with the function keyword.
$3
Let's imagine we want to obtain all the _fantasy books_ published _after the year 1990_:
`jsx
import { useFilter, filter } from 'usefiltex';
function Books() {
const { filtered: filteredBooks, manager } = useFilter({
// list to filter
list: books,
filters: [
// declare our filters
filter("fantasy", (book) => book.genre === "Fantasy"),
filter("year", (book) => book.year > 1990),
]
})
const filter = () => {
manager
.apply("fantasy") // apply the 'fantasy' filter
.apply("year") // apply the 'year' filter
.activate() // activate all the applied filters
}
return (
)
}
`
$3
Let's imagine we want our user to be able to apply different filters depending on its needs and activate all of them all at once:
`jsx
import { useFilter, filter } from 'usefiltex';
function Books() {
const { filtered: filteredBooks, manager } = useFilter({
// list to filter
list: books,
filters: [
// declare our filters
filter("fantasy", (book) => book.genre === "Fantasy"),
filter("year", (book) => book.year > 1990),
]
})
const applyFantasyFilter = () => {
manager.apply("fantasy") // apply the 'fantasy' filter
}
const applyYearFilter = () => {
manager.apply("year") // apply the 'year' filter
}
const activateFilter = () => {
manager
.activate() // activte all the applied filters
}
return (
)
}
`
$3
If we want to let our user to know which filters are applied whenever they want, we can use the returned getFilter() function returned by useFilter().
In this way the user can use the status of the filter to toggle the style of a button:
`jsx
import { useFilter, filter } from 'usefiltex';
function Books() {
const {
filtered: filteredBooks,
manager,
getFilter
} = useFilter({
// list to filter
list: books,
filters: [
// declare our filters
filter("fantasy", (book) => book.genre === "Fantasy"),
]
})
const applyFilter = () => {
manager.
toggle("Fantasy") // toggle filter
}
const filter = () => {
manager
.activate() // activte all the applied filters
}
return (
style={getFilter("fantasy").isActive ? { background: "blue"} : {}}
onClick={applyFilter}
>Filter
)
}
`
$3
In this example, weβll use payload to pass dynamic filter conditions β like filtering books by publication year range.
This shows how flexible your hook is when the filtering rules depend on user input (search bars, sliders, dropdowns, etc.).
`jsx
import { useFilter, filter } from 'usefiltex';
function Books() {
const { filtered: filteredBooks, manager } = useFilter({
list: books,
filters: [
filter("yearRange", (book, [minYear, maxYear]) => book.year >= minYear && book.year <= maxYear),
filter("byAuthor", (book, searchTerm) =>
book.author.toLowerCase().includes(searchTerm.toLowerCase())
)
]
});
const filterByAuthor = () => {
manager
.apply("byAuthor", "Kyle") // search for "Kyle" in the author name
}
const filterByYear = () => {
manager
.apply("yearRange", [2010, 2020]) // Year between 2010 and 2020
}
const filter = () => {
manager
.activate();
}
return (
)
}
`
$3
If you find a bug, have an idea for a feature, or just want to say hi β open an issue!
I'd love to hear how you're using this library and how it can improve.
---
Thanks for checking out usefiltex`!