0.2.1 • Published 7 years ago

react-redux-collect v0.2.1

Weekly downloads
3
License
MIT
Repository
github
Last release
7 years ago

React Redux Collect

Build Status Coverage Status Dependency Status devDependency Status JavaScript Style Guide

This is the consequence of some feedback and meditation on react-redux-connect-helpers.
Chiefly, the resulting nested mess of connectors after composition:

screen shot 2017-04-08 at 3 01 55 pm
screenshot from React Developer Tools

This function implements the same core functionality as react-redux-connect-helper's connectStateValue, but by building up mapStateToProps and mapDispatchToProps arguments to be passed to a single connect call.

Collect some values in state and connect them as props. :+1:

Installation

$ npm install react-redux-connect-helpers

Usage

import collect from 'react-redux-collect'

const provideProps = collect([<path>, <name>, <transformer>], ...)

The arguments to connect a value in state are ordered as follows:

  • path: An array or string denoting the key(s) to access the value in state.
  • name (optional): The key of the resulting prop, defaults to. the last key in path.
  • transformer (optional): Function to transform the accessed value or action.
    For values, will pass the value as the first param and state as the second.
    For actions, will pass the action as the first param and props as the second.

For example, where state and actionCreators look like this:

const state = {
  id: 'SST-130',
  title: 'You\'re Living All Over Me',
  artist: 'Dinosaur Jr.',
  tracks: [
    { title: 'Little Fury Things', length: '3:06' },
    { title: 'Kracked', length: '2:50' },
    { title: 'Sludgefeast', length: '5:17' },
    { title: 'The Lung', length: '3:51' },
    { title: 'Raisans', length: '3:50' },
    { title: 'Tarpit', length: '4:36' },
    { title: 'In a Jar', length: '3:28' },
    { title: 'Lose', length: '3:11' },
    { title: 'Poledo', length: '5:43' }
  ]
}

const actionCreators = {
  openPlayer: () => ({
    type: 'OPEN_PLAYER'
  }),
  playAlbum: albumId => ({
    type: 'PLAY_ALBUM',
    payload: albumId
  })
}

This code:

import { createCollect } from 'react-redux-collect'
import actionCreators from './actionCreators'

const collect = createCollect(actionCreators)

const provideProps = collect(
  'id',
  ['title']
  ['artist', 'band'],
  [['tracks', 0], 'firstTrack'],
  ['tracks', 'numTracks', tracks => tracks.length],
  [['actions', 'openPlayer']],
  [['actions', 'playAlbum'], 'onClick', (action, {id}) => action.bind(null, id)]
)

Is equivalent to:

import { connect } from 'react-redux'
import actionCreators from './actionCreators'

const mapStateToProps = (state, ownProps) => ({
  title: state.title,
  band: state.artist,
  firstTrack: state.tracks[0],
  numTracks: state.tracks.length
})

const mapDispatchToProps = (dispatch, ownProps) => ({
  openPlayer: (...args) =>
    dispatch(actionCreators.openPlayer(...args)),
  onClick: (...args) =>
    dispatch(actionCreators.playAlbum(props.id, ...args))
})

const provideProps = connect(
  mapStateToProps,
  mapDispatchToProps
)

Immutable

If your state uses Immutable.js, import with react-redux-collect/immutable.

Tricks

Creating collect is only necessary if you intend to connect actions as props.
Otherwise you can just use the default export.

import collect from 'react-redux-collect'

// Ideally a created collect is declared in another file
// and imported as needed throughout your application.

You can pass selector functions instead of path arrays.

import collect from 'react-redux-collect'

const selectFirstTrack = state => state.tracks[0]

// props: { firstTrack: { title: 'Little Fury Things', length: '3:06' } }
const provideProps = collect([selectFirstTrack, 'firstTrack'])

You can spread a state value into props using the string '...'.

import collect from 'react-redux-collect'

// props: { title: 'Kracked', length: '2:50' }
const provideProps = collect([['tracks', 1], '...'])

You can pass the entirety of state into props using the string '*'.

import collect from 'react-redux-collect'

// props: {...state}
const provideProps = collect('*')
// NOTE:
// If state['*'] is not undefined, collect will throw an error