1.0.2 • Published 6 years ago

create-reducer-actions v1.0.2

Weekly downloads
3
License
MIT
Repository
github
Last release
6 years ago

createReducerActions

Build Status

NPM

createReducerActions is a single function that creates a redux reducer and linked action creators.

You don't need to define action types or actions, and you don't need to write tedious switch/case statements in your reducers.

createReducerActions works like this:

const initialState = 0;
const { reducer, actions } = createReducerActions(
  {
    up: state => state + 1,
    down: state => state - 1
  },
  initialState
);

actions.up(); // { type: "up" }
reducer(); // 0 === initialState
reducer(7, up()); // 8

Getting Started

Installation

$ npm install --save create-reducer-actions
// or
$ yarn add create-reducer-actions

Usage with React

// redux/counter.js
import createReducerActions from "create-reducer-actions";

const initialState = 0;
export const { reducer, actions } = createReducerActions(
  {
    increment: state => state + 1,
    decrement: state => state - 1,
    add: (state, { payload }) => state + payload,
    sub: (state, { payload }) => state - payload
  },
  initialState
);


// store.js
import { createStore, combineReducers } from "redux";

import { reducer as counter } from "./redux/counter";

const rootReducer = combineReducers({ counter });
const store = createStore(rootReducer);

export default store;


// Counter.js
import React from "react";
import { connect } from "react-redux";
import { actions } from "./redux/counter";

export const Counter = ({ counter, add, sub, increment, decrement }) => {
  return (
    <div>
      <h1>Counter: {counter}</h1>
      <button onClick={increment}>increment</button>
      <button onClick={decrement}>decrement</button>
      <button onClick={() => add(5)}>add 5</button>
      <button onClick={() => sub(5)}>subtract 5</button>
    </div>
  );
};

const mapStateToProps = state => {
  return { counter: state.counter };
};
const mapDispatchToProps = actions; // automatically includes all exported actions

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

Options

actionPrefix

In a large application action names can conflict with each other. Prefix actions with {appName}/{reducerName}/ to avoid conflicts:

const { reducer, actions } = createReducerActions(
  {
    like: state => state + 1,
    unlike: state => state - 1
  },
  0,
  { actionPrefix: "FACEBOOK/LIKE_REDUCER/" }
);

actions.like() will now dispatch an action with type FACEBOOK/LIKE_REDUCER/like.

mutable

Redux requires immutable changes to state.

Immutable changes in deeply nested objects are difficult to do, so add mutable: true to the createReducerActions options and you can make mutable changes to state that will be automatically turned into immutable changes:

const initialState = {
  photos: { large: { url: "" } }
};
const { reducer, actions } = createReducerActions(
  {
    setLargePhotoUrl: (state, { payload: { url } }) => {
      // mutate the state!
      state.photos.large.url = url;
      // don't return anything
    }
  },
  initialState,
  { mutable: true }
);

const url = "https://i.imgur.com/4LR3f32.jpg";
const newState = reducer(initialState, actions.setLargePhotoUrl({ url }));
newState.photos.large.url; // "https://i.imgur.com/4LR3f32.jpg"
initialState.photos.large.url; // "" The initial state wasn't mutated =O

These mutating changes are done with the immutable helper library immer.

Similar Projects

1.0.2

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago