npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@duckness/use-redux

v1.0.0

Published

React hook for Redux store

Downloads

231

Readme

@duckness/use-redux

React hook for Redux store

NPM License Libraries.io dependency status for latest release, scoped npm package GitHub issues vulnerabilities npm bundle size

Example

import React from 'react'
import useRedux from '@duckness/use-redux'

const counterSelector = (state => state.counter || 0)

export default function Counter() {
  const counter = useRedux(store, counterSelector)
  return <span>[ {counter} ]</span>
}

Table of Contents

useRedux

const selectedState = useRedux(store, selector, shouldUpdate?, shouldSelect?)

store

Redux store to subscribe to.

selector

Select relevant data from store state.

function selector(state) {
  // ... calculate selectedState from state
  return selectedState
}

shouldSelect

Optional select filter. This optimization helps to avoid expensive calculations in selector.

selector will be called on every redux store update if:

  1. shouldSelect is not specified or null
  2. 'function' === typeof shouldSelect and true == shouldSelect(nextStoreState, prevStoreState)

shouldUpdate

Optional selectedState update filter.

useRedux will update after every redux store update and selector call if:

  1. true === shouldUpdate
  2. 'function' === typeof shouldUpdate and true == shouldUpdate(nextSelectedState, prevSelectedState)
  3. shouldUpdate is not specified or null and nextSelectedState !== prevSelectedState

useDispatchAction

Binds actionCreator to store.dispatch.

const onAction = useDispatchAction(store, actionCreator, payloadTransformer?)
// ...
onAction(payload)
// => dispatch action with payload

actionCreator

function myAction(payload) {
  type: 'MY_ACTION',
  payload: payload
}

payloadTransformer

Optional payload transformer.

  1. undefined === payloadTransformer - use supplied payload.
const onAction = useDispatchAction(store, myAction)
onAction('PAYLOAD')
// => dispatch { type: 'MY_ACTION', payload: 'PAYLOAD' }
  1. 'function' === typeof payloadTransformer - transform payload.
const onAction = useDispatchAction(store, myAction, str => str.toLowerCase())
onAction('PAYLOAD')
// => dispatch { type: 'MY_ACTION', payload: 'payload' }
  1. any other values for payloadTransformer - use payloadTransformer as payload.
const onAction = useDispatchAction(store, myAction, null)
onAction('PAYLOAD')
// => dispatch { type: 'MY_ACTION', payload: null }

Third option is useful when using useDispatchAction as a callback for DOM events.

function increment(amount) {
  return { type: 'INC', payload: null == amount ? 1 : amount }
}

const onInc = useDispatchAction(store, increment, null)

// <button onClick={onInc}>INC</button>

// onInc will be called with { payload: null } instead of { payload: event }

useDispatch

useDispatch(store, dispatcher, deps)

Example:

const onMultiAction = useDispatch(store, (dispatch, amount) => {
  for (let i = 0; i < amount; i++) {
    dispatch( actionCreator(i) )
  }
}, [actionCreator])
// ...
onMultiAction(10)
// => dispatch 10 actions
function SetStatusButton({ status = 'ready' } = {}) {
  const onClick = useDispatch(
    store,
    dispatch => {
      dispatch(actionSetStatus(status))
    },
    [status]
  )

  return <button onClick={onClick}>{status}</button>
}

combineSelectors

Produces three functions from a map of selectors:

  1. selector - combined selector
  2. shouldUpdate - selectedState update filter (see above)
  3. areEqual - negative of shouldUpdate
const { selector: actionCounterSelector, shouldUpdate: shouldUpdateActionCounter } = combineSelectors({
  actionsDispatched: CounterDuck.select.actionsDispatched,
  lastActionDispatchedAt: CounterDuck.select.lastActionDispatchedAt
})
export default function ActionCounter() {
  const { actionsDispatched, lastActionDispatchedAt } = usePool(
    CounterPool,
    actionCounterSelector,
    shouldUpdateActionCounter
  )
  return (
    <span>
      (ACTIONS: {actionsDispatched}, LAST: {lastActionDispatchedAt})
    </span>
  )
}

Passing custom selectedStatesEqual function that compares selected states

combineSelectors(selectorsMap, { selectedStatesEqual } = {})

selectedStatesEqual(selectorKey, nextSelectedState[selectorKey], prevSelectedState[selectorKey]): Boolean

connect

Creates HOC connected to Redux store.

connect(store, selector, shouldUpdate, shouldSelect, dispatch = store.dispatch) => (Component, ?mapToProps) => ConnectedComponent

store, shouldUpdate, shouldSelect are the same arguments used in useRedux.

selector is the same function used in useRedux but with ownProps added: selector(state, ownProps)

mapToProps is an optional props mapper in form of

(selectedState, ownProps, dispatch) => componentProps

Example:

import { connect, combineSelectors } from '@duckness/use-redux'

import TodoList from '../../components/TodoList'
import TodoListPool, { TodoDuck } from '../TodoListPool'

const { selector, shouldUpdate } = combineSelectors({
  // we should wrap selector because TodoDuck.select.visibleTodos expects (state, duckFace) with duckFace added by Duck,
  // but connected selector is called as (state, ownProps) that would lead to (state, ownProps, duckFace) call.
  todos: state => TodoDuck.select.visibleTodos(state)
})

export default connect(
  TodoListPool.store,
  selector,
  shouldUpdate
)(TodoList, (selectedState, ownProps, dispatch) => {
  return {
    ...ownProps,
    ...selectedState,
    onToggleTodo: id => void dispatch(TodoDuck.action.toggleTodo(id))
  }
})

@Duckness packages: