All Projects → joshwcomeau → React Collection Helpers

joshwcomeau / React Collection Helpers

Licence: mit
A suite of composable utility components to manipulate collections.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to React Collection Helpers

Koazee
A StreamLike, Immutable, Lazy Loading and smart Golang Library to deal with slices.
Stars: ✭ 446 (+309.17%)
Mutual labels:  arrays, functional-programming
Javascript For Everyone
A step by step guide to learn JavaScript and programming
Stars: ✭ 285 (+161.47%)
Mutual labels:  arrays, functional-programming
Async Ray
Provide async/await callbacks for every, find, findIndex, filter, forEach, map, reduce, reduceRight and some methods in Array.
Stars: ✭ 102 (-6.42%)
Mutual labels:  arrays
Clear Config
Scala FP configuration library with a focus on runtime clarity
Stars: ✭ 108 (-0.92%)
Mutual labels:  functional-programming
Forge
Functional style JSON parsing in Kotlin
Stars: ✭ 106 (-2.75%)
Mutual labels:  functional-programming
Gu
A web ui library for Go. [DEPRECATED]
Stars: ✭ 102 (-6.42%)
Mutual labels:  components
Miniboxing Plugin
Miniboxing is a program transformation that improves the performance of Scala generics when used with primitive types. It can speed up generic collections by factors between 1.5x and 22x, while maintaining bytecode duplication to a minimum. You can easily add miniboxing to your sbt project:
Stars: ✭ 106 (-2.75%)
Mutual labels:  arrays
Re Jok
A React UI Component library built with styled-components
Stars: ✭ 102 (-6.42%)
Mutual labels:  components
Python Memoization
A powerful caching library for Python, with TTL support and multiple algorithm options.
Stars: ✭ 109 (+0%)
Mutual labels:  functional-programming
Cats Stm
An STM implementation for Cats Effect
Stars: ✭ 106 (-2.75%)
Mutual labels:  functional-programming
Functionaljava
Functional programming in Java
Stars: ✭ 1,472 (+1250.46%)
Mutual labels:  functional-programming
Parapet
A purely functional library to build distributed and event-driven systems
Stars: ✭ 106 (-2.75%)
Mutual labels:  functional-programming
Server Components Mdx Demo
React server components + MDX
Stars: ✭ 102 (-6.42%)
Mutual labels:  components
Pattern Matching Ts
⚡ Pattern Matching in Typescript
Stars: ✭ 107 (-1.83%)
Mutual labels:  functional-programming
Orkestra
Functional DevOps with Scala and Kubernetes
Stars: ✭ 102 (-6.42%)
Mutual labels:  functional-programming
Fsconfig
FsConfig is a F# library for reading configuration data from environment variables and AppSettings with type safety.
Stars: ✭ 108 (-0.92%)
Mutual labels:  functional-programming
Pd Select
vue components ,like ios 3D picker style,vue 3d 选择器组件,3D滚轮
Stars: ✭ 101 (-7.34%)
Mutual labels:  components
Akka Stream Eventsourcing
Event sourcing for Akka Streams
Stars: ✭ 105 (-3.67%)
Mutual labels:  functional-programming
Freeesvclcomponents
Free ErrorSoft components for delphi (VCL) & EsVclCore lib
Stars: ✭ 106 (-2.75%)
Mutual labels:  components
Y Combinator For Non Programmers
🍱 Y Combinator for Non-programmers: A Wild Introduction to Computer Science
Stars: ✭ 109 (+0%)
Mutual labels:  functional-programming

React Collection Helpers

A suite of composable utility components to manipulate collections.

Travis npm package Coveralls

Quick Example

import { Filter, Sort, First } from 'react-collection-helpers';

const users = [
  { id: 'a', name: 'Harry', lastMessagedAt: '2016-03-14T15:00', isOnline: true },
  { id: 'b', name: 'Bob', lastMessagedAt: '2017-01-20T12:00', isOnline: false },
  { id: 'c', name: 'Molly', lastMessagedAt: '2013-01-02T03:04', isOnline: false },
  { id: 'd', name: 'Karrin', lastMessagedAt: '2017-01-12T11:05', isOnline: true },
  { id: 'e', name: 'Thomas', lastMessagedAt: '2014-03-04T13:37', isOnline: true },
]

const UserList = ({ users }) => (
  <Filter collection={users} predicate={{ isOnline: true }}>
    <Sort comparator="lastMessagedAt">
      <First num={4}>
        {user => <div key={user.id}>{user.name}</div>}
      </First>
    </Sort>
  </Filter>
)

ReactDOM.render(
  <UserList users={users}>,
  document.querySelector('#root')
)

/*
  Renders:

  <div>
    <div>Karrin</div>
    <div>Harry</div>
    <div>Thomas</div>
  </div>
*/

Live Demo

Play with a live demo.

Table of Contents

Features

  • Useful - includes 10+ components to help you filter, sort, and slice collections.
  • ✒️ Designer-friendly - make your designers' lives easier by writing components without complex inline logic.
  • ⚡️ Tiny - full build is only 2.5kb, and is modular so you can import only the components you need.
  • 💪 Performant - experiments show that these components are just as performant as native methods.
  • 🔧 Customizable - the wrapper element can be any element type you'd like (native or composite), and all non-recognized props are passed through. Composing Collection Helpers does not create additional HTML markup!

Drawbacks

So, React Collection Helpers is an experiment, designed to test if React's component model makes sense when used for array manipulation.

I believe that it's nicer, for the reasons outlined above, than doing vanilla JS manipulation within your component's render method. That said, this is often the wrong place to be doing this kind of logic.

For very large collections, or for components that re-render frequently, it makes sense to move this kind of intense manipulation into memoized functions. If you use Redux, then reselect is likely a better place to do this kind of work.

It also means that your presentation layer never has to concern itself with this work, which is usually a good thing.

For small apps (or simple sections within large apps), React Collection Helpers can be a nice touch. For redux apps, though, there is often a better way.

Ultimately, React Collection Helpers is built as a starting point, not a final destination. I feel like with enough trial and error, we might stumble upon something genuinely innovative and useful. I'm going to continue experimenting, and I would encourage us all to keep an open mind, and an eye out for exciting new possibilities.

Installation

npm i -S react-collection-helpers

UMD builds are also available via CDN:

(If you use the UMD build, the global variable is CollectionHelpers)

Feedback Wanted

This project is an experiment to test the usefulness of collection manipulators in component form factor.

When I say that it's an experiment, I don't necessarily mean that it's experimental. I'm pretty confident that it's stable and safe to use in production; the code is quite simple.

Rather, I mean that I'm not convinced that it solves a real problem. I'd like to hear from users who implement them; does it improve the development experience of you or your team? Do you think the idea has potential if it went in a certain direction? I'm open to exploring tangential ideas.

Let me know on Twitter, or via email

Usage

Import the component(s) you need:

// ES6 modules
import { Find, Every, Map } from 'react-collection-helpers';

// CommonJS
const { Find, Every, Map } = require('react-collection-helpers');

Alternatively, you can import components individually, to avoid bundling the components you don't use:

// This method avoids bundling unused components, and reduces gzipped bundles
// by about 1kb.
import Find from 'react-collection-helpers/lib/components/Find';
import Every from 'react-collection-helpers/lib/components/Every';
import Map from 'react-collection-helpers/lib/components/Map';

Guides

Learn more about how best to use React Collection Helpers with these in-depth guides:

API Reference

<Every>

Render the children if the predicate returns true for every child. A Fallback node can be provided, to be rendered if the predicate returns false for any child. Otherwise, nothing will be rendered.

If no predicate is provided, the content will be rendered as long as the collection has 1 item or more. If an empty collection is supplied, the fallback content will be rendered.

Props

Prop Required Types Notes
collection [any] Can be implicitly passed by parent Collection Helpers
predicate function/object See predicates for more information
fallback node Alternate content to be rendered if the predicate returns false on any items.

Example

const collection = [
  { id: 'a', src: '...', isLoaded: true },
  { id: 'b', src: '...', isLoaded: true },
  { id: 'c', src: '...', isLoaded: false },
];

<Every
  collection={collection}
  predicate={{ isLoaded: true }}
  fallback={<span>Loading...</span>}
>
  {item => <img key={item.id} src={item.src} />}
</Every>

<Filter>

Render only the children for which the predicate returns true.

Props

Prop Required Types Notes
collection [any] Can be implicitly passed by parent Collection Helpers
predicate function/object See predicates for more information

Example

const collection = [
  { id: 'a', name: 'apple', price: 1.00 },
  { id: 'b', name: 'banana', price: 5.00 },
  { id: 'c', name: 'carrot', price: 2.50 },
];

<Filter collection={collection} predicate={item => (item.price < 3)}>
  {item => <div key={item.id}>{item.name}</div>}
</Filter>

<Find>

Render the first child for which the predicate returns true.

Props

Prop Required Types Notes
collection [any] Can be implicitly passed by parent Collection Helpers
predicate function/object See predicates for more information

Example

const collection = [
  { id: 'a', name: 'John', isAdmin: false },
  { id: 'b', name: 'Jane', isAdmin: true },
  { id: 'c', name: 'Jala', isAdmin: false },
];

<Find collection={collection} predicate={{ isAdmin: true }}>
  {user => <div key={user.id}>Your group's admin is {user.name}</div>}
</Find>

<First>

Returns the first 1 or more items of the collection. Generally only useful as a child to another Collection Helper.

Props

Prop Required Types Notes
collection [any] Can be implicitly passed by parent Collection Helpers
num number Defaults to 1

Example

const collection = [
  { id: 'a', name: 'John', distance: 3.14 },
  { id: 'b', name: 'Jane', distance: 0.45 },
  { id: 'c', name: 'Jala', distance: 1.23 },
];

<Sort collection={collection} comparator="distance">
  <First>
    {user => <div key={user.id}>You are closest to {user.name}</div>}
  </First>
</Sort>

<Last>

Returns the last 1 or more items of the collection. The opposite of <First>. Generally only useful as a child to another Collection Helper.

Props

Prop Required Types Notes
collection [any] Can be implicitly passed by parent Collection Helpers
num number Defaults to 1

Example

const collection = [
  { id: 'a', name: 'John', distance: 3.14 },
  { id: 'b', name: 'Jane', distance: 0.45 },
  { id: 'c', name: 'Jala', distance: 1.23 },
];

<Sort collection={collection} comparator="distance">
  <Last>
    {user => <div key={user.id}>You are furthest from {user.name}</div>}
  </Last>
</Sort>

<Map>

The simplest Collection Helper, doesn't do very much. Can be useful to ensure consistency between your components.

Props

Prop Required Types Notes
collection [any] Can be implicitly passed by parent Collection Helpers

Example

const collection = [
  { id: 'a', name: 'John' },
  { id: 'b', name: 'Jane' },
  { id: 'c', name: 'Jala' },
];

<Map collection={collection}>
  {user => <div key={user.id}>{user.name}</div>}
</Map>

<Reject>

Render only the children for which the predicate returns false. The opposite of <Filter>.

Props

Prop Required Types Notes
collection [any] Can be implicitly passed by parent Collection Helpers
predicate function/object See predicates for more information

Example

const collection = [
  { id: 'a', name: 'apple', price: 1.00 },
  { id: 'b', name: 'banana', price: 5.00 },
  { id: 'c', name: 'carrot', price: 2.50 },
];

<Reject collection={collection} predicate={item => (item.price > 3)}>
  {item => <div key={item.id}>{item.name}</div>}
</Reject>

<Some>

Render the children if the predicate returns true for any child. A Fallback node can be provided, to be rendered if the predicate returns false for all children. Otherwise, nothing will be rendered.

If no predicate is provided, the content will be rendered as long as the collection has 1 item or more. If an empty collection is supplied, the fallback content will be rendered.

Props

Prop Required Types Notes
collection [any] Can be implicitly passed by parent Collection Helpers
predicate function/object See predicates for more information
fallback node Alternate content to be rendered if the predicate returns false on all items.

Example

const collection = [
  { id: 'a', username: 'sickskillz', hasWon: false },
  { id: 'b', username: 'dabomb12345', hasWon: false },
];

<Some
  elementType={Leaderboard}
  collection={collection}
  predicate={{ hasWon: true }}
>
  {user => <LeaderboardRow key={user.id} {...user} />}
</Some>

<Sort>

Sorts the children based on a comparator.

Props

Prop Required Types Notes
collection [any] Can be implicitly passed by parent Collection Helpers
comparator function/object See comparators for more information
descending boolean Whether to sort in descending order, when providing a 'string' comparator. Defaults to false (string comparators sort in ascending).

Example

const collection = [
{ id: 'a', name: 'apple', price: 1.00 },
{ id: 'b', name: 'banana', price: 5.00 },
{ id: 'c', name: 'carrot', price: 2.50 },
];

<Sort collection={collection} comparator="price">
  {item => <StoreItem key={item.id} {...item} />}
</Sort>
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].