Predicates in React Collection Helpers
January 24, 2017 ยท View on GitHub
Many React Collection Helpers (<Filter>, <Find>, <Every>, and more) use a predicate prop to determine whether an item in a collection matches or not.
Predicates in general
Don't let the word predicate scare you. A predicate is simply a function that returns a boolean value.
For example, the following predicate will allow us to determine whether an item in a list is within our budget:
const items = [
{ name: 'apple', price: 1.00 },
{ name: 'banana', price: 5.00 },
{ name: 'bugatti veyron', price: 1695000.00 },
]
const isWithinBudgetPredicate = item => item.price < 1000;
In this ridiculous example, we have a thousand bucks, so we can afford some fruit but not a supercar.
We can apply this predicate with several different functions, in vanilla JS:
const allAffordableItems = items.filter(isWithinBudgetPredicate);
// -> [{ name: 'apple', price: 1.00 }, { name: 'banana', price: 5.00 }]
const firstAffordableItem = items.find(isWithinBudgetPredicate);
// -> { name: 'apple', price: 1.00 }
Predicates in React Collection Helpers
We use predicates in much the same way:
const items = [
{ name: 'apple', price: 1.00 },
{ name: 'banana', price: 5.00 },
{ name: 'bugatti veyron', price: 1695000.00 },
]
const isWithinBudgetPredicate = item => item.price < 1000;
<Filter collection={items} predicate={isWithinBudgetPredicate}>
{item => <div key={item.name}>{item.name} - ${item.price}</div>}
</Filter>
/*
<div>
<div>apple - \$1.00</div>
<div>banana - \$5.00</div>
</div>
*/
<Find collection={items} predicate={isWithinBudgetPredicate}>
{item => <div key={item.name}>{item.name} - ${item.price}</div>}
</Find>
/*
<div>
<div>apple - \$1.00</div>
</div>
*/
Object Short-hand
Instead of passing a function, you can pass it an object that describes your requirement:
const items = [
{ name: 'apple', price: 1.00, isOnSale: false },
{ name: 'banana', price: 2.50, isOnSale: true },
{ name: 'bugatti veyron', price: 500000, isOnSale: true },
];
<Filter collection={items} predicate={{ isOnSale: true }}>
{item => <div key={item.name}>{item.name} - ${item.price}</div>}
</Filter>
/*
<div>
<div>banana - \$2.50</div>
<div>bugatti veyron - \$500000</div>
</div>
*/
This is often a more declarative way to present a predicate, if you're testing for a specific object value. Under the hood, it creates a predicate function based on this object and applies it in the same way.