Coder Social home page Coder Social logo

redux-actions's Introduction

redux-actions

Build Status codecov npm npm

Flux Standard Action utilities for Redux

Table of Contents

Getting Started

Installation

$ npm install --save redux-actions

or

$ yarn add redux-actions

The npm package provides ES modules that should be compatible with every modern build tooling.

Usage

import { createActions, handleActions, combineActions } from 'redux-actions';

const defaultState = { counter: 10 };

const { increment, decrement } = createActions({
  INCREMENT: (amount = 1) => ({ amount }),
  DECREMENT: (amount = 1) => ({ amount: -amount })
});

const reducer = handleActions(
  {
    [combineActions(increment, decrement)]: (
      state,
      { payload: { amount } }
    ) => {
      return { ...state, counter: state.counter + amount };
    }
  },
  defaultState
);

export default reducer;

See the full API documentation.

Documentation

redux-actions's People

Contributors

acdlite avatar albertogasparin avatar alexander-heimbuch avatar andrewsuzuki avatar danny-andrews avatar dbachrach avatar dbrans avatar deadcoder0904 avatar deoxxa avatar dustyburwell avatar ggilberth avatar grifotv avatar heygrady avatar isaddo avatar jacobmoyle avatar jakxz avatar jamiedixon avatar jaridmargolin avatar jasonkid avatar mslipper avatar nikita-graf avatar nimish-gupta avatar nowells avatar pensierinmusica avatar simek avatar spartan563 avatar suayoo avatar timche avatar vinnymac avatar yangmillstheory avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redux-actions's Issues

Payload undefined instead of unset

Hi, I just started toying around with this lib so I'm probably missing something important. The spec for FSA states that an action MAY have a payload property, however when I do this:

const type = 'TYPE';
const myActionCreator = createAction(type);
const action = myActionCreator();
console.log(action); // <- {type: "TYPE", payload: undefined} but I expected {type: "TYPE"}

Is there a reason for this?

Wrapping reducer in handleAction throws undefined state

If I wrap a reducer in handleAction I get this error:

"Reducer "selectedReddit" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined."

If I debug I see redux tries to get a initial state by calling the wrapped reducer with undefined state and a specific system action type. Because the type does not match the wrapped one the inner reducer never runs and no state default is created.

If I use handleActions (m) with default state it works fine. Same function with default state in arguments and classic action-type check is also fine.

Anyway,is handleAction usable like this? Readme doesn't really specifiy use case.

handle error in createAction

I already checked out createAction file for more information, but it seems don't have any mechanisms to handle error with FSA error action in createAction function. It can't mutate any values outside of payload.

But I thought that it's a common case to handle error in a actionCreator, like below:

// With babel - optional: ["runtime"]
export const search = createAction(SEARCH_USER, async username => {
  try {
    const data = await getGithubInfo(username);
    return data;
  } catch (err) {
    // handle error here
  }
});

It doesnโ€™t make sense to abort error handling support here.

Any ideas?

Do I need to understand flux to use these?

I started reading the docs for flux standard actions, and they make a lot of references to flux. I'm just wondering if it will hinder my understanding of redux-actions if I don't go learn Flux, which I would rather not do.

handleAction should throw when reducer is not a function.

At the moment handleAction falls back to just returning the current state instead of throwing an exception when the passed in reducer is not a function. This is very surprising, especially because the documentation does not mention it. IMHO it would make more sense to assume the passed in reducer (or the properties of the reducer map) are always functions and blow up if they are not.

how to import it?

import createAction from 'redux-actions';

or

import { createAction } from 'redux-actions';

??
Why is this missing in the readme?

Can't use enum (TypeScript) as type identifier

I want to use enum for defining action types๏ผŒsuch as

enum ActionTypes {
  ADD,
  DELETE
}

const add = createAction(ActionTypes.ADD, item => item)
const reducer = handleActions({
  [ActionTypes.ADD](state, item) {
    return [...state, item]
  }
}, initialState)

After compile, ActionTypes.ADD will transform to number 0.
But the key of handlers will become string '0'.
Because '0' !== 0, the demo above will not work.

Should print warning message if type is undefined

Consider this code, it's commonly used in my project:

import * as actionTypes from './actionTypes.js'
export default handleActions({
  [actionTypes.ACT_1]: (state, action) => {},
  [actionTypes.ACT_2]: (state, action) => {},
})

If there's a typo in actionTypes variable(ACE_1 for instance), there's no warning, linters can't tell the error too. But it's easy to print warning message using redux-actions.

I'd like to send a PR if it's okay to you.

Proposal: mechanism for handling multiple actions with the same reducer.

Hi all!

I'd like to propose a new feature to allow handling multiple actions with the same reducer in the case that someone has very general, over-arching properties of their state.

For example, when using redux on its own I've found it useful to have a loading property which gets reduced like this:

function loading(state = false, action) {
  switch(action.type) {
  case LOAD_SOMETHING_START:
  case LOAD_SOMETHING_ELSE_START:
    return true;

  case LOAD_SOMETHING_COMPLETE:
  case LOAD_SOMETHING_ELSE_COMPLETE:
    return false;

  default:
    return state;
  }
}

I find this preferable to invoking an action to update loading within a composite/async action using redux-thunk because I would prefer not to have my state's other properties know about the loading property and keep that logic central to the reducer for loading.

Initially I'd like to propose being able to define an action handler with a name that contains a delimiter like |. To illustrate with the previous example:

handleActions({
  'LOAD_SOMETHING_START | LOAD_SOMETHING_ELSE_START': () => true,
  'LOAD_SOMETHING_COMPLETE | LOAD_SOMETHING_ELSE_COMPLETE': () => false
}, false);

Alternatively, if it would be preferable not to expose the details about how to delimit action names, a function combineActions() might help:

const startActions = combineActions('LOAD_SOMETHING_START', 'LOAD_SOMETHING_ELSE_START');
const completeActions = combineActions('LOAD_SOMETHING_COMPLETE', 'LOAD_SOMETHING_ELSE_COMPLETE');

handleActions({
  [startActions]: () => true,
  [completeActions]: () => false
}, false);

What do you think? I'd be thrilled to submit a PR for this if we agree it would be worthwhile.

flux-standard-action dependency not necessary

handleAction use flux-standard-action method isError

import { isError } from 'flux-standard-action';

the method is simple, but it will import some lodash method when compile by webpack.

function isError(action) {
  return action.error === true;
}

I suggest remove the flux dep for descrease the compilse file size.

Why the extra ...state in the action map?

I am wondering why we are required to merge in the current state in every reducer function.

const initialState = {
  selectedTagIds: [],
  tags: getTagsForLanguage('en')
}

const reducer = handleActions({
  [ADD_FILTER_TAG]: (state, { payload }) => ({ ...state, selectedTagIds: [...state.selectedTagIds, payload] }),
  [REMOVE_FILTER_TAG]: (state, { payload }) => ({ ...state, selectedTagIds: state.selectedTagIds.filter(id => id !== payload) }),
  [CLEAR_FILTER]: (state) => ({ ...state, selectedTagIds: [] }),
}, initialState)

If handleActions was something like...

function handleActions(actionsMap, initialState) {
  return (state = initialState, action) => {
    const reduceFn = actionsMap[action.type]
    if (reduceFn) {
      return {...state, ...reduceFn(state, action)}
    }

    return state
  }
}

... you could write

const reducer = handleActions({
  [ADD_FILTER_TAG]: (state, { payload }) => ({ selectedTagIds: [...state.selectedTagIds, payload] }),
  [REMOVE_FILTER_TAG]: (state, { payload }) => ({ selectedTagIds: state.selectedTagIds.filter(id => id !== payload) }),
  [CLEAR_FILTER]: (state) => ({ selectedTagIds: [] }),
}, initialState)

It makes it less verbose and harder to mess up imho

.babelrc cause error on babel6

There is a .babelrc published on npm, which is configured for babel5. It will cause error on babel 6, like react-native >=0.16.0

Is it ok to add it into '.npmignore' and does not publish it on npm?

npm package redux-actions contains old code.

npm package redux-actions contains old code, for ex. it hasn't "Handle FSA errors where the payload is an Error object. Set error." in createAction.js could you please update npm package. Thanks.

handleActions naming is confusing

Since handleActions returns a reducer, a proper name for it would be createReducer. I've tried to teach redux to a friend and it wasn't immediately apparent that handleActions returns a reducer. What do you think? I'm not adamant on createReducer, as it doesn't differentiate from handleAction. I just think that handleActions might not be the proper name for it.

ES6 Symbols break handleActions

handleActions doesn't correctly match actions with types that are Symbols, e.g.

const TEST_ACTION = Symbol('TEST_ACTION')
const OTHER_TEST_ACTION = 'OTHER_TEST_ACTION'
const reducer = handleActions({
  [TEST_ACTION]: () => 'foo',
  [OTHER_TEST_ACTION]: () => 'bar',
}, 'baz')

let state = 'test'
state = reducer(state, {type: TEST_ACTION})
console.log(state) // test (unexpected)
state = reducer(state, {type: OTHER_TEST_ACTION})
console.log(state) // bar (fine)

TEST_ACTION is broken, OTHER_TEST_ACTION is fine.

Error while persisting cache: TransformError

Hi,
i have this issue:

Error while persisting cache: TransformError: 
/Users/saro/Projects/openshift/reactNative/node_modules/redux-actions/lib/index.js:
[BABEL] /Users/saro/Projects/openshift/reactNative/node_modules/redux-actions/lib/index.js: 
Using removed Babel 5 option: 
/Users/saro/Projects/openshift/reactNative/node_modules/redux-actions/.babelrc.stage - 
Check out the corresponding stage-x presets http://babeljs.io/docs/plugins/#presets

Any suggestions?

action.meta by default should return timestamp (when action creator was executed)

In the project I am working on, I find that timestamp is needed so often that it makes sense to add timestamp (when the createAction function was executed) as default for action.meta. If you think it's a good idea too I can make this happen via pull request.

ie.

 if (typeof metaCreator === 'function') {
   action.meta = metaCreator(...args);
 } else {
  action.meta = {
    timestamp: Date.now()
  }
}

Make defaultState non-optional

Since we have to return a non-undefined state in redux, we should probably make the defaultState parameter for handleActions required. Thoughts?

[Question] How do I dispatch multiple actions in one action?

Hi.

Say I have one action initialize, for this as for many actions I am dispatching an action:start, action:success and action:failure. Most of these have counterparts in the reducers where they update properties like isFetching, isSaving, etc.

If I use redux-actions instead of redux-thunk then how do I let my reducers know the correct state at the correct time? If I can only dispatch one event at the end of one action then I can't dispatch multiple actions/events from one action ..

Should we use toString() instead of creating constants?

With this line (see below for code) being added to createAction, should we use toString on the action creator to reference actions instead of creating constants?

export default function createAction(type, actionCreator, metaCreator) {
  // code removed for brevity 

  const actionHandler = (...args) => {
    // removed for brevity

    return action;
  };

  // this line is what I'm referring to
  actionHandler.toString = () => type;

  return actionHandler;
}

Basically, is there any reason I should be creating and exporting constants for action types, or should I just export action creators, and code that needs to reference the type can just use myActionCreator.toString()?

overriding the payload creator and new error is not automatically caught.

export const isLoading = createAction('IS_LOADING',(isLoadingFlag,message) => {

  return {
      isLoading:isLoadingFlag,
      message:message,
  }
})


/// creation action without payload creator

export const isLoadingWithDefault = createAction('IS_LOADING')


// Using the action creators

this.props.isLoading(new Error("Message!!!!!")) // => error doesn't exist is isn't populated and payload:object

this.props.isLoadingWithDefault(new Error("Message!!!")) // => error:true payload: is the error object

payloadCreator is executed even when an Error is passed

const favoriteEnd = createAction(types.FAVORITE_END, (id) => ({ id }))
favoriteEnd(15) // payload.id === 15
favoriteEnd(new Error('foo')) // payload.id === error

while I'd expect

favoriteEnd(new Error('foo')) // payload === error

Am I missing something ?

Not calling reducer with failed promise

I'm using redux-actions with redux-promise. When my promise succeeds, it hits my handleActions reducer as expected, but when it fails, nothing happens. The action is fired off but my handler never sees the failed FSA.

From devtools I see that the FSA has error property set to true as expected, but my reducer below does not get called.

const reducers = handleActions({
  [FOO_ACTION]: (state, action) => {
    console.log(action); // when promise fails, I don't see this!
    return state;
  },
}, initialState);

Then I tried something like this but it didn't work. I'm pretty sure this is not how we're supposed to use handleActions.

const reducers = handleActions({
  [FOO_ACTION]: handleAction(FOO_ACTION, {
    next: (state, action) => {
      console.log('woo hoo:', action);
      return state;
    },
    throw: (state, action) => {
      console.log('aww man:', action);
      return state;
    },
  }),
}, initialState);

Could someone shed some more light on how to handle failed promises?

How to set error to true?

When creating an FSA-compliant action that represents an error (error property set to true), how can I do that? Sorry if it's an obvious answer.

How can I set initial state for reducers from async requests?

Hi! I am new to React and redux. And would appericate some help or direction where to go next. Here few questions I have:

  1. How can I set initial state for reducers from async requests?
  2. I'd like to create an app with JWT auth. I store jwt token in the localStorage and would like to handle expiration. I'd like to handle 401, remove jwt token from localStorage and ask user to login. How can I do that properly?
    Thanks!

Possible feature: have handleAction() transfer payload to state when reducer is undefined

This could be a really bad idea, but I thought I'd run it by you. I often find that I'm just wanting to write a quick reducer that just moves the action's payload to the state. Being able to just type:

const reducer = handleAction(ACTION_TYPE, initialState);

instead of

const reducer = handleAction(ACTION_TYPE, (_, {payload}) => payload, initialState);

would be really nice. Just a thought.

Multiple handlers per action

How about this?

const reducer = handleActions({
  SELECT_PRODUCT: [select, setColor],
  UNSELECT_PRODUCT: [unselect, unsetColor]
}, initialState);

How to use combineReducers to add multiple reducers that use the same action type?

I'm using combineReducers and i'm wondering how I can use handleActions to have two different store keys be updated by the one action type. My requirement is that the one action type be used to update different keys inside the store, for example I have a transactions array which must add a new transaction then I must update the balance of the account the transaction relates to.

This doesn't seem to work, or am I doing this wrong?

import { combineReducers } from 'redux';
import { handleActions } from 'redux-actions';

const ADD_TRANSACTION = 'ADD_TRANSACTION';
let defaultTransactionsState = [];
let defaultAccountsState = [];

// add transaction to transactions state
let transactions = handleActions({
  [ADD_TRANSACTION]: (state, action) => ([action.payload, state...])
}, defaultTransactionsState);

let accounts = handleActions({
  [ADD_TRANSACTION]: (state, action) => {
    // update the balance of account based on transaction being added
    let payload = action.payload;
    let accountToEdit = state.find((account) =>  account.id === payload.accountId);
    let newBalance = accountToEdit.balance + (payload.inAmount - payload.outAmount);

    return state.map(account =>
      account.id === accountToEdit.id
        ? {...account, balance: newBalance}
        : account
    );
  }
}, defaultAccountsState);

combineReducers({
  transactions,
  accounts
});

identity function in createAction only handles the first parameter

The createAction function returns an action creator with the signature function(...args). However, if you do not pass an actionCreator method to the createAction function, then the "identity" function is used.

The identity function is this: (t) => t, which does not do an argument spread and, since it is called with function.apply, it only handles the first argument passed in to the action creator, even though the action creator is designed around supporting n arguments.

createAction - need a means to set action.meta if payload is an error

export const FAILED_REQUEST_ORDER = ${GET_FUNCTIONALITY}_FAILED;
export const failedOrder = createAction(FAILED_REQUEST_ORDER);

// in calling code

// ...
.catch(error) {
const errorMeta = {
'endpoint': endpoint,
'options': options
};
dispatch(failureAction(error, errorMeta));
}

I would like to dispatch an error object as a payload, but also have meta data information. I can hack around it, but I think it makes sense for createAction to provide a means to set meta separately from payload. This is important for error handling. Thanks for your time.
-- currently I can't perform the code above, even though I think it should be able to do so) -- a hack exists where I do this:

.catch((error) => {
  const errorMeta = {
    'endpoint': endpoint,
    'options': options
  };
  let failureActionObject = failureAction(error);
  failureActionObject.meta = errorMeta;
  dispatch(failureActionObject);
});

no-reserved-keys rule

To prevent no-reserved-keys eslint rule error (which is on by default at a lot of companies)
Every time i need to write in handleAction(s) something like this

// eslint-disable-line no-reserved-keys

or this

...
  ['throw'](state, { payload }) { ...
...

may be it will be more likely to give an alias for throw like error , onError etc...

Identity function, hidden gotchas and 300-400ms to dispatch your actions

Just want to discuss this, since was confused by default actionCreator factory behaviour. As per docs if I define my action crator like that:

export const toggleBaseline = makeActionCreator('Dbg.TOGGLE_BASELINE')

identity function will be used for payload. I assumed that it's fine to create Action Creators that don't have a payload in this manner and it was wrong assumption. Read below why.

After creating it I passed it to my component like that:

export default connect(state => state.debug, {
  toggleBaseline,
})(DebugGrid)

Then inside DebugGrid component I just hooked it to onClick handler:

<input type="checkbox" onChange={props.toggleBaseline}

All seemed fine, do you see a problem at this point? I didn't see any =) And if you don't see it also then we have a problem and need to do something about it. This is main point of this issue.

Then I opened Redux Dev Tools, clicked on my checkbox and saw this:

image

That was a moment of "whait a minute..." aha, right since Action Creator uses identity function and I pass it "as-is" to reduce boilerplate to my component event handler it grabs React's synthetic event to it's params, but why it becomes so slow, 400ms for an action dispatch?

Then I realized that default settings in Redux Dev Tools is to serialize state and that synthetic event object must be huge so serialization of it takes 300-400ms.

If I haven't used Dev Tools I would have not discovered this untill much later when I would be out of context and probably would spend days to figure this out.

So then I figured that default "safe" way to define Action Creators is like this:

makeActionCreator('Dbg.TOGGLE_BASELINE', () => {})

It looks a little weird to me, am I missing something? Thanks!

Add GUID to actions

What do you think about adding a GUID field to each action to allow unique identification. This could be useful for:

  1. Linking errors to the original actions that created them
  2. Helping problem analysis in production systems after the fact
  3. Tooling for time-travel development tools

You could put it into the meta property, but I think this could prove useful as a first class concept.

Create a version of `handleActions` which supports async actions too

We want to be able to support handlers in the form of:

{
    begin: (state, action) => {},
    end: {
      next: (state, action) => {},
      throw: (state, action) => {},
    }
  }

In order to do so, we have to inspect themeta field of the action and switch on the async field there. We also have to make sure that the handlers receive all arguments the original action receives, so that we can do optimistic updates easily.

In case an async handler receives a non-async action it should just handle it the same way it would handle the end status of an async action.

Builder/Factory pattern for better type propagation in TypeScript/Flow

Current handleActions(reducerMap, ?defaultState) signature doesn't allow the propagation of payload types from actions into reducers, as it is a dictionary type.

A builder or factory pattern like the following would allow for better type propagation

let increment = createAction<void>('INCREMENT');
let decrement = createAction<number>('DECREMENT');

ReducerBuilder()
.addReducer(increment, (state, action) => {})
.addReducer(decrement, (state, action) => {})
.toReducerMap();

The reason being the actions could be typed as Action<void> and Action<number> respectively, and .addReducer can be typed as

function addReducer<TState, TPayload>(action: Action<TPayload>, handler: (state: TState, action: Action<TPayload>)=>{});

This would automated propagate the type into the reducer.

Allow to pass down a matcher to match an action

Would be useful to accept a matcher to match our action before reducing the state.

Something like

export default function handleMatchingAction(matcher, reducers) {
  return (state, action) => {
    // If action does not match, return previous state
    if (!matcher(action)) return state;

    const handlerKey = isError(action) ? 'throw' : 'next';

    // If function is passed instead of map, use as reducer
    if (isFunction(reducers)) {
      reducers.next = reducers;
    }

    // Otherwise, assume an action map was passed
    const reducer = reducers[handlerKey];

    return isFunction(reducer)
      ? reducer(state, action)
      : state;
  };
}
export default function handleAction(type, reducers) {
  return handleMatchingAction(action => action.type === type, reducers)
}

Reducer composition pattern + redux-actions

Say I've got a basket which you can add items to or remove items from. If I add an item which already exists in the basket, I update the quantity property instead of adding a new entry in the basket. I use the reducer composition pattern to delegate the responsibility of updating the quantity to a separate function which handles properties within the item. Here's the code:

const basketItem = (state, action) => {
    switch (action.type) {
        case ADD_TO_BASKET:
            if (state.id !== action.payload.id) {
                return state;
            }


            return Object.assign({}, state, {
                quantity: state.quantity + action.payload.quantity
            });
        default:
            return state;
    }
}

let basket = handleActions({
    ADD_TO_BASKET: (state, action) => {
        let itemIndex = state.findIndex(item => {
            return item.id === action.payload.id;
        })

        if (itemIndex === -1) {
            //if the item doesn't exist in the basket already return the new item with the existing array
            return [...state, action.payload];
        } else {
            return state.map(i => basketItem(i, action));
        }
    },
    REMOVE_FROM_BASKET: (state, action) => {
        let index = state.findIndex(item => {
            return item.id === action.item.id
        })
        return [...state.slice(0, index), ...state.slice(index + 1)];
    }
}, []);

So my questions are:

  • is it possible to set the default state within the parameters using es6 instead of as the second parameter of handleActions? i.e. (state = [], action)
  • Does it make sense to do it in this way? One of the main reasons of using redux-actions was to reduce boilerplate and I'm ending up adding a separate handler for properties within the item

Thanks

Match updated Observer interface

https://github.com/zenparsing/es-observable#observer

interface Observer {

    // Recieves the next value in the sequence
    next(value);

    // Recieves the sequence error
    error(errorValue);

    // Receives the sequence completion value
    complete(completeValue);
}

handleAction() / handleActions() should use the same naming scheme:

const reducer = handleAction(ACITON_TYPE, {
  // Receives normal actions
  next(state, action);

  // Receives `error: true` actions
  error(state, action);

  // Receives `meta.sequence: 'complete'` actions
  complete(state, action);
});

Repo still active?

Is this repo still being maintained? @acdlite

I would like to see some changes like #48. Currently waiting for it for a while :(

Set payload equal to error if payload is `instanceof Error`

I already made a note of this in #43, but I wanted to promote it to its own issue.

I personally think that if you pass an error in as the payload, it should bypass your custom payloadCreator logic and just set the payload equal to the passed-in error. Otherwise, you have to add an error check in each of your action creators to achieve the same effect.
Example:

const createCoolAction = createAction(COOL_ACTION_TYPE, spec => {
  const {zipCode, id} = spec;
  return {body: {zipCode, id}};
});

So, if I do something like, createCoolAction(new Error('Something bad happened')), the payload will be set to {body: {zipCode: undefined, id: undefined}} instead of just the error object itself. To fix this, I could add an error check, but I don't want to have to do this in every one of my action creators.

I'd be happy to make an MR for this.

handleAction/handleActions: should set a default `throw` function

For async action, rejected promise then wrap to FSA: {error: true, payload: [Error Object]}, always we should {return state}.

FSA says if the status is error, the payload SHOULD be an error object, i can't understand why handleAction/handleActions: If a single reducer is passed, it is used to handle both normal actions and failed actions.

createActions

Just as there's a handleActions, perhaps there should be a createActions as sugar for creating multiple actions?

createActions(
  {
    [type1]:  payload1Creator,

    [type2]:  {
                "payload":  payload2Creator,
                "meta":     meta2Creator,
              }
  }
);

This seems a bit nicer (and less redundant) than

{
  [type1]: createAction(type1, payload1Creator),
  [type2]: createAction(type2, payload2Creator, meta2Creator),
}

[suggestion] createActions: Default action to empty object

Currently to get a default state from a createActions-returned reducer you must use:

const store = Redux.createStore(
  reducer,
  reducer(undefined, {}),
  Redux.applyMiddleware(logger)
)

If the reducer returned by createActions defaulted the action to {}, we can now do:

const store = Redux.createStore(
  reducer,
  reducer(), // yay! no more action.type errors!
  Redux.applyMiddleware(logger)
)

handleActions doesn't work

I tried using

const INCREMENT = 'logos/counter/INCREMENT'
const RESET = 'logos/counter/RESET'
export const counterReducer = handleActions({
  INCREMENT: (state, action) => {
    return state + action.payload
  },
  RESET: (state, action) => ({
    counter: 0,
  }),
}, 0)

and the INCREMENT part was never called

however

export const counterReducer = (state=0, action) => {
  switch(action.type) {
    case INCREMENT:
      return state + action.payload
    case RESET:
      return 0
    default:
      return state
  }
}

worked just fine

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.