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

redux-act-classy

v3.0.0

Published

Make Redux classier with Async Lifecycle Actions that take a modern approach to redux action creation.

Downloads

7

Readme

Redux Act Classy

Make Redux classier with Async Lifecycle Actions that take a modern approach to redux action creation.

Build Status Coverage Status

Examples

Are you a hands-on learner? Checkout this example project! React Redux example app

Docs

Documentation is auto-generated but encompasses all exported members of the library. View the documentation

Define a basic action

A basic action with a generated type
class MyAction extends Classy() {
}
A basic action with a manually specified type
class MyAction extends Classy('my-action') {
}
A basic action with some data
// Using TypeScript
class MyAction extends Classy() {
  constructor(readonly data: string) { super() }
}
// Using JavaScript
class MyAction extends Classy() {
  constructor(data) { 
    super()
    this.data = data
  }
}

Define an asynchronous action

class LoadJokeAction extends Classy<JokeDetails>() {
    public perform = async (dispatch, getState) => {
      // do something asynchronously... e.g. await fetch()
      return {
        setup: 'Two peanuts were walking down the street',
        punchLine: 'One of them was a salted'
      }
    }
}

Dispatch actions

An action with data
dispatch(new MyAction('some-data'))
An async action

Asynchronous actions are not directly received by reducers. Instead, Lifecycle actions are automatically dispatched to report information on the state of asynchronous activity.

dispatch(new LoadJokeAction()) // nothing interesting here

Identify actions in your reducer function

When using TypeScript

Typescript Type Guards allow the reducer helper functions (isAction, beforeStart, afterSuccess, etc) to add type information to the action within the if block.

// Identify basic actions
if (isAction(action, MyAction)) {
  // action is a MyAction
}

// Identify asynchronous lifecycle actions
if (beforeStart(action, LoadJokeAction)) {
  state = {
    showSpinner: true
  }
} else if (afterSuccess(action, LoadJokeAction)) {
  state = {
    showSpinner: false,
    joke: action.successResult
  }
}
When using JavaScript
switch(action.type) {

  // Identify basic actions
  case MyAction.TYPE:
    // action is a MyAction
    

  // Identify asynchronous lifecycle actions
  case LoadJokeAction.OnStart:
    state = {
      showSpinner: true
    }
  case LoadJokeAction.OnSuccess:
    state = {
      showSpinner: false,
      data: action.successResult.data
    }
}

Set Up

Add the package to your project
yarn add redux-act-classy

# or

npm install redux-act-classy --save
Add the middleware to your redux store

In Redux you can only dispatch plain object actions. To get around this design, we need a middleware to intercept our Classy actions and convert them into plain object actions (removing all functions and leaving only data properties) before passing them along to the reducer functions.

The middleware is responsible for calling perform on asynchronous actions and dispatching the Lifecycle Actions.

import { buildAClassyMiddleware } from 'redux-act-classy'

// You may optionally pass an object to the build method to configure the middleware
const classyMiddleware = buildAClassyMiddleware()

const reduxStore = createStore(
    combineReducers({
        someReducer,
        anotherReducer
    }),
    {},
    compose(applyMiddleware(classyMiddleware))
)

Motivation

I came up with some of the ideas for this library while trudging through the action portion of the redux ecosystem.

I've found it cumbersome to deal with

  • action creators
  • action types
  • accessing action data in reducers (esp. w/ type friendliness)
  • async thunk actions that result in multiple concrete actions to record the current lifecycle stage of the async action (Start/Success/Fail/etc) for loading spinners etc

Each of these individually are not that bad, but taken as a whole I felt like there should be a simpler way to do these things.

Goals

Types are first class

With the growing popularity of typescript, it makes sense to provide a solution that improves developing in typescript as well as a javascript.

Simplistic usage

I want users to feel like this is the way actions were meant to be used.

Fully tested codebase

I work in a Test Driven Design environment, and I think it's important to bring that level of confident development to this library so that others can have confidence in using this library for their production environments.

Contributing

TODO: project setup instructions...

Currently I am doing most of this by myself. If you have thoughts, inspiration, feedback, or want to add a feature. Feel free to reach out or send a pull request!

Task List

  • Could add a reducer that stores all lifecycle states: OnStart, etc for each Action. e.g. state.asyncActions[MyAction.TYPE].status. Multiple async actions of the same type (potentially with different data) may be going at the same time... (new DeleteJokeAction({id: 5}))

  • Add tests to middleware

    • test that functions are not passed when deconstructing {...action}
  • Add tests to helper functions

  • Bug: Fix perform return types that are arrays. only able to determine they are any[] atm

  • perform takes a getState: () => T T should be the defined top level state interface for users projects... How can we make this generic (without passing it into EACH new ClassyAction)...