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

side-effects

v1.2.0

Published

Add side effects to Redux

Downloads

2

Readme

side-effects

Adds side-effects to redux, heavily inspired by redux-loop. I rewrote it because of the lack of documentation, the lack of typescript definitions, and the fact that testability has been dropped.

The only reason why you'd want to return a side effect from your reducer rather than just making a side effect happen is so that you can test them. This library also decouples the effect result from the description of the effect.

Installation

$ yarn add side-effects

## Overview

A side effect is basically the equivalent of an action - that is, it is a description of behaviour. The side-effect equivalent of a reducer, the function that makes the side effect happen, is called an effector.

Effector functions make the side effects happen, and optionally return an action or a promise for an action (or actions).

You might find it useful to create side effect creator functions, similar to action creators.

Example

Here is an example of a logging side effect:

import { createStore } from 'redux';
import { installSideEffects } from 'side-effects';

function loggingEffector(effect) {
  switch (effect.type) {
    case 'LOG':
      console.log(effect.message);
      break;
  }
}

function reducer(state, action) {
  switch (action.type) {
    case 'DO_A_THING':
      return [
        {...state, frobblesAligned: true},
        {type: 'LOG', message: 'frobbles aligned'}
      ];

    default:
      return state;
  }
}

const store = createStore(reducer, installSideEffects(loggingEffector));

To make a side effect, just return a tuple, with the new state as the first element and the side effect as the second.

Here's a more useful example, using promises:

import { createStore } from 'redux';
import { installSideEffects } from 'side-effects';

function apiEffector(effect) {
  switch (effect.type) {
    case 'GET':
      return fetch(effect.url)
        .then((response) => response.json())
        .then((result) => ({
          type: 'RESPONSE_READY',
          result
        }));
  }
}

function reducer(state, action) {
  switch (action.type) {
    case 'FETCH_WIDGETS':
      return [
        {...state, loading: true},
        {type: 'GET', url: '/api/widgets'}
      ];

    case 'RESPONSE_READY':
      return {
        ...state,
        loading: false,
        widgets: action.result
      };

    default:
      return state;
  }
}

const store = createStore(reducer, installSideEffects(apiEffector));

API

installSideEffects(effector: Effector)

Returns an enhancer to pass to createStore. The effector is a function which makes the side effect happen. It's much like a reducer in that it'll probably do a switch on the effect type, but it returns an action or a promise for an action.

hasSideEffect(obj)

Determines if the given object has a side effect (duck typing, can't know for sure).

combineReducers(...reducers: (Partial<DeepReducerMap<S>> | ReducerWithSideEffects<S>)[]): ReducerWithSideEffects<S>

Replaces redux's combineReducers - this one is side effect aware. It can accept an aribtrarily deep nesting of reducer maps and multiple arguments, either reducer functions or more maps.

noSideEffect()

Creates a dummy side effect with type equal to 'none', in case you want to keep your reducers consistent.

multipleSideEffects(sideEffects: SideEffect[], serial=false)

Creates a side effect which represents multiple other side effects. If serial is true, the effects will be run in serial; that is, the following ones will only run when previous promises have resolved.

dispatchAction(...actions: Action[])

A utility effect whose effector just immediately returns the action(s) passed. Useful for dispatching other actions from a reducer.