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

redax

v0.0.0

Published

A simple flux architecture that combines actions & reducers and maps your store's state directly to your components

Downloads

13

Readme

Redax

Redax combines your actions & reducers to reduce the amount of files you'll need open, and amount of code you have to write - no more searching through dozens of files to find the reducer that matches your action, and no more constants for action types.

Redax also lets you access the entire state tree from every action so that you can easily store it in local storage, reset the entire state, or update multiple collections of data easily.

The redax Store has a very useful map function to connect your store directly to a component's props. No more need to manually add and remove listeners for state changes, or wrap your application with a provider. Because redax uses immutablejs it internally difs your previous and next state, so that components will only update if a change has been made.

By default redax will allow you to chain actions and handle asynchronous requests as calls made to actions from inside an action are deferred until the action has been resolved.

Usage

Create a store

A store's default state is an immutablejs Map. We call our setCount action after creation to set the initial count value, but this could set the entire initial state of your application, or be used to reset the state if you need to do so (which you should do with state.clear()).

// store.js

import { Store } from 'redax';
import * as actions from './actions';

const store = new Store(
  // Object containing our actions
  actions
);

store.actions.setCount();

export default store;

Actions

Every action is also a reducer, so they must all return the state. The state in each action is the entire state of the store. It's recommended that you use setIn and deleteIn for grouping related data (example a little further down).

// actions.js

// Used to set the initial count value
export function setCount (state) {
  return state.set('count', 0);
}

Combine multiple action files

Use Object.assign or similar, e.g. _.extend, to combine multiple sets of actions.

// store.js

import * as login from './login';
import * as todo from './todo';

const store = new Store(
  Object.assign(
    {},
    login,
    todo
  )
);

Chaining actions

Notice that the incrementThenDecrementTwice action calls the decrement action twice. The decrement calls will be deferred until incrementThenDecrementTwice is resolved, this means that you can easily chain actions, and handle asynchronous requests.

// actions.js

export function decrement (state) {
  return state.set('count', state.get('count') - 1);
}

export function incrementThenDecrementTwice (state) {
  this.actions.decrement();
  this.actions.decrement();
  return state.set('count', state.get('count') + 1);
}

Asynchronous example

Here we make an asynchronous request and then call either our success or failure action. You can access the store's actions via this.actions if you do not have access to the store itself. Notice how we group our state into login and auth because we have access to the entire state.

// login.js

export function loginSuccess(state, response) {
  const login = state.get('login', Map())
    .delete('loading')
    .delete('error');

  return state.set('login', login)
    .setIn(['auth', 'token'], response);
}

export function loginFailure(state, error) {
  const login = state.get('login', Map())
    .delete('loading')
    .set('error', error);

  return state.set('login', login)
    .deleteIn(['auth', 'token']);
}

export function login(state, username, password) {
  const login = state.get('login', Map())
    .set('loading', true)
    .delete('error');

  request('/login/')
    .data({username, password})
    .send()
    .then(this.actions.loginSuccess, this.actions.loginFailure);

  return state.set('login', login)
    .deleteIn(['auth', 'token']);
}

Connecting your store state to your components

Connect your store's state to your components easily with store.map. Notice that we do not need to connect our actions to our component as these are automatically dispatched on call.

// component.js

import store from './store';
// Destructuring our actions from the store
const { actions: { incrementThenDecrementTwice } } = store;

class Component extends React.Component {
  render() {
    const { count } = this.props;

    return (
      <button onClick={incrementThenDecrementTwice}>
        Count: {count}
      </button>
    );
  }
}

function stateToProps(state) {
  return {
    count: state.get('count')
  };
}

export default store.map(stateToProps).to(Component);