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

reactionpack

v0.3.0

Published

ReactionPack

Downloads

10

Readme

ReactionPack

ReactionPack offers a simple way to decouple actions and state changes from view components. With ReactionPack properly built components are stateless, use only props, and are easily unit testable.

This state management package draws heavily from Redux but attempts to simplify development for small and large applications. The major difference with this library is that there are no reducers or constants to worry about. Actions return with state changes eliminating the need for constants and reducers. Additionally asynchronous actions and computed values are first class citizens with no need for external packages.

Key Features:

  • Zen mode component development (Stateless, simple, organized, and testable. See: Component Development)
  • No Redux (No constants and reducers, just actions)
  • No Thunk (Actions are natively asynchronous. See: Actions)
  • No Reselect (Built in support for computed values. See: Computed Values)
  • Small package size

Examples:

Installation

npm install reactionpack --save

State Container

createStateContainer(Component, [initialState])

Arguments

  • Component

Returns

  • (Component) Returns a new component that serves as the app's root state container.
  • initialState - optional state object
import { createStateContainer } from 'reactionpack';

const AppContainer = createStateContainer(App);

Component Development

Folder Structure

Components should have a folder structure like the following:

Component/
├── actions.js  (Action functions get mapped to props by name)
├── actions.spec.js
├── computed-values.js  (Computed value definitions get mapped to props by name)
├── computed-values.spec.js
├── index.js  (Returns the connected component)
├── View.jsx  (Stateless view component)
└── View.spec.js

Connecting Components

connectToProps(Component, [actions, [computed]])

Arguments

  • Component
  • [actions] (object) - key names map to properties
  • [computeds] (object) - key names map to properties

Returns

  • (Component) Returns a new component with actions and computeds bound to props.
import { connectToProps } from 'reactionpack';

const ConnectedPage = connectToProps(Page, actions, computeds);

Props Override Rules

Props are overrided in the following priority from highest to lowest.

  • prop passed in from owner component
  • computed value from bound computed function
  • action bound function
  • state value from state container (if defined in propTypes)
  • component default props

Actions

Actions are async out of the gate and can return with state changes or a promises.

// Return state changes
actionName(state, [value, ...]) {
  return {
    ...state
    someValue: value
  }
}

// Return promises
actionName(state, [value, ...]) {
  return fetchApiStuff(value).then((res) => {
    return {
      ...this.getState();
      things: res.things;
    }
  })
}

Return Values

Actions can return three kinds of values: A object representing the new state, a promise, or null.

  • (object): Container state will be replaced with returned object.
  • Promise: Container state will be updated with the resolved object.
  • null: No state change required

Action Context

  • this.getActions()
  • this.getComputed()
  • this.getDefaults()
  • this.getState()

Computed Values

ReactionPack has computed value support built in. Inspired by Reselect, computed values can be defined using an array containing one or more value selector functions and a computation function.

export const computedDef = [
  selectorFunc,
  <more selector functions>,
  computeFunc
]

Example Usage

(Excerpt taken from the todomvc example app)

// Selector definitions
function getTodos(state) {
  return state.todos;
}

function getFilter(state) {
  return state.filter;
}

// Exported computed value definition
export const filteredTodos = [
  getTodos,
  getFilter,
  (todos, filter) => _.filter(todos, TODO_FILTERS[filter]),
];

Unit Testing

Action Helper

wip

Computed Value Helper

wip

Use with React-Router

// App.jsx
...
export default connectToProps(App, actions, computed);

// ./pages/home.jsx && /pages/about.jsx
export default connectToProps(Home, actions, computed);

// Routes.jsx
import { createStateContainer } from 'reactionpack';

import App from './app';
import Home from './pages/home';
import About from './pages/about';

const Routes = (
  <Route path='/' component={createStateContainer(App)}>
    <Route path='/home' component={Home} />
    <Route path='/about' component={About} />
  </Route>
);

Redux DevTools Extension

NOTE: Only partially supported WIP

ReactionPack can be used with the Redux DevTools Chrome extension. To do this, forward state changes to the extension by passing in an onNextState handler to the state container component:

function onNextState(state, action) {
  if (window.devToolsExtension) {
    window.devToolsExtension.send({ type: action }, state);
  }
}

render(
  <AppContainer onNextState={onNextState} />,
  document.getElementById('root')
);