Giter VIP home page Giter VIP logo

redux-act's People

Contributors

abraaoalves avatar alexgalays avatar antonkri97 avatar comerc avatar ej9x avatar gotrecillo avatar mastilver avatar mdwagner avatar megawac avatar npmcdn-to-unpkg-bot avatar pauldijou avatar ptico avatar rstuven avatar samiskin avatar sompylasar avatar tenga avatar zachstoltz 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

redux-act's Issues

CRUD Example

Do you have a quick code sample you can show that implements CRUD usage? Or really, any LOAD and UPDATE usage is fine. I'm not sure if the typical redux actions of MODEL_CREATE_REQUEST, MODEL_CREATE_SUCCESS, MODEL_CREATE_ERROR still apply when using redux-act. If so, how, and if not, well...how?

Any way to do type coercion on default value in createReducer?

Hey there,

I have a case where I can't be sure if my reducer will be instantiated with an array or an object. I'd like to coerce the array into an object if necessary.

It would look something like this (in vanilla redux):

function myReducer (state={}, action) {
    var newState = {}
    if (Array.isArray(state)) {
        state.forEach(function(item){
            newState[item.id || bsonId()] = item
        });
    } else {
        newState = state
    }
    if (action.type === 'HELLO WORLD') {
        return {newState, hello: 'world'}
    }
    // etc....

    return newState
}

I couldn't think of a way to dynamically set the default reducer value with redux-act. Do you have any suggestions for how to do this? Maybe the create reducer api needs to be expanded slightly?

const reducerMap = createReducer({
  [increment]: (state) => state + 1,
  [add]: (state, payload) => state + payload
}, function(initialValue){var newInitialValue = {}  ...etc....  return initialValue });

Thanks!
Thomas

Question: how to test an app that's using redux-act?

I'm trying to test an Angular 1.x app which is using redux-act. The problem is that when I run unit tests, redux-act throws a tantrum saying that I have duplicate action types in my code.

When tests are run, services keep re-initializing and call same reduxAct.createAction multiple times, which results in "Duplicate action type: XXX" due to this line.

Wouldn't it be a good idea to expose types as a public property or to have some kind of a hasType/clearAllTypes API that could be called on afterEach in tests?

Cannot seem to access state.indexof

Hi,
I have a state that looks like:

 cart:
    "ITEMKEY123":
         product: {product meta here }
         qty: 1

I would like to when adding an item in the "cart" to check if the key exist and then if it already exist, update the qty.

My actions look like:

export const addToCart = createAction('ADD_TO_CART',( product, qty ) => {
      return { product, qty };
});

My Reducer looks like:

 export default createReducer({
     [actions.addToCart]: (state, {product, qty}) => {
         return u({
            [product.$key]: {
                product: product,
                qty:qty,
                tax_rate: product.tax_rate,
                sale_price:product.sale_price,
            }
        }, state)
    },
}, state = {});

I figured I would search for the key in the state and if present change the qty of the object.
But if I do something like:
state.indexOf(product.$key)
I get

State.indexOf is not a function

Default action handler?

In vanilla redux, you can write a reducer:

(state, action) => {
    switch (action.type) {
        case "SOME_ACTION": return {...state};
        default: return {...state, someOtherThing: 3}
    }
}

What is the equivalent of this 'default' action handler in redux-act?

'Or' in createReducer?

Is there a way to specify multiple action creator triggers for one function in createReducer?

createReducer({
[actionOne] OR [actionTwo]: (state, payload) => doSomething(state, payload),
}, defaultState)

... or do I have to repeat code for every one of them?

createReducer({
[actionOne]: (state, payload) => doSomething(state, payload),
[actionTwo]: (state, payload) => doSomething(state, payload),
}, defaultState)

You get this kind of behavior easily with fallthrough for the standard switch-based reducer...

Issue using assignTo with multiple functions?

I had a great idea for binding the actions functions to both a store, and another function to send the payloadedAction over a websocket. But experimenting with it, I had to wonder if this functionality works as intended, or if I'm using it wrong?

// in an Actions file
assignAll(Actions, [console.log.bind(console, 'Foo: '), store])

//when an action is triggered, our logger fires
Foo:  Object {type: "SET_STATE", payload: "SET_STATE", meta: Object}

// but the action has been dispatched (or reduced) in a weird way
store.getState()
Object {0: "S", 1: "E", 2: "T", 3: "_", 4: "S", 5: "T", 6: "A", 7: "T", 8: "E", game: Object, players: Array[0], round: Object}

Full source is here: https://github.com/deanius/react-trivia/tree/bindActionIssue

Reusing Reducers and Actions

Hi,

Is it supported, and is there an example of reducer and action reuse with redux-act?

For example, if I defined counterReducer twice in combineReducers.

combineReducers({
counter1: counterReducer,
counter2: counterReducer
})

Is it possible to dispatch an action to target a specific reducer without duplicating action creators and reducers?

Typings

It seems there are not any available typings for this library, which is quite a shame as it looks quite nice.

Defining functions inside the action?

Right now it seems actions are always tied to their respective reducers. Actions can be re-used, but their reducing functions have to be duplicated. Is there any way that reducing functions could be tied to an action from the get go?

Custom descriptors for batched actions

Would it be possible to extend the batch method to accept an optional description to use instead of (or appended to) "Batch"? This would improve readability of logs where multiple distinct batch actions are being dispatched.

Feature request: .on improvement

export default createReducer<typeof defaultState>({}, defaultState)
  .on(setCanCount, (state, payload) => ({
    ...state,
    canCount: payload
  }))
  .on(someOther, (state, payload) => ({
    ...state,
    ...payload
  }))

Uppercase action constants not being used for action type

import { createAction, createReducer } from 'redux-act'

export const j5success = createAction('J5_SUCCESS')
export const j5start = createAction('J5_START')
export const j5fail = createAction('J5_FAIL')

I would have expected the above actions to plain strings as their output without any appended id. Aka createAction('J5_START') should yield an action with type 'J5_START'.

Instead this is what I'm seeing:

image

Question: Asserting action type when unit-testing

I've started using this for a new project and I should say, I love it!

However currently have an issue when I'm asserting the action type of an action created by redux-act.
I can see that createAction is creating a unique type for the action in the format of [0] name of action with 0 being any number.

Unlike traditional redux where action types are hand picked, here we cannot predict (or control at test time) the exact name that is chosen for an action and hence not able to assert it.

Any view on this?

createReducer not responding to outside actions

Hey there,

I'm not able to get my reducer made using createReducer to respond to outside actions. I'm not sure if I'm doing something wrong. Here's my code:

//./caretPosition.js
import { createAction, createReducer } from 'redux-act'

// ------------------------------------
// Actions
// ------------------------------------
export const clearCaret = createAction('clearCaret')
export const updateCaret = createAction('updateCaret')


var { updateSelectionLayer } = require('./selectionLayer'); //important, keep this here in the order of the file and let it use the commonjs syntax! 
// ------------------------------------
// Reducer
// ------------------------------------
export default createReducer({
  [updateSelectionLayer]: () => {
    //clear the caret if the selection layer is updated!
    return -1
  },
  'redux-form/INITIALIZE': (state) => {
    debugger;
    return state
  },
  ['@@INIT']: (state) => {
    debugger;
    return state
  },
  [clearCaret]: () => {
    return -1
  },
  [updateCaret]: ({start}, payload) => {
    return payload
  },
}, 0)

in the above code, neither 'redux-form/INITIALIZE' nor '@@init' are triggering the debugger, but the [clearCaret] works fine.

Am I missing something here?

Thanks!
Thomas

Is there a way to access the store from createAction?

For example, I have this action creator init(), and I can't know the state when I dispatch it. In a normal action creator, I could return a function (dispatch, getState)=>{}.

The main use case for this is api/socket calls that are based on the current state of the app. There's usually workarounds except in a specific case I'm dealing with.

Discuss createReducer's default state mutability

o/ @pauldijou

First of all, thanks for this amazing library :)

I'm opening this issue so we can discuss createReducer's default state mutability.

Recently, I accidentally updated my default state from within a reducer function, effectively creating a memory leak.

Similarly to the following piece of code:

const addItem = createAction('Add an item');

const initialState = {
  foo: {
    items: [],
  },
};

createReducer({
  [addItem]: (state, payload) => {
    const items = state.foo.items;

    items.push(payload);

    return {
      foo: {
        items,
      },
    };
  },
}, initialState)

Because I use redux in a node.js web application, a store is created for every HTTP request it receives, and so, every new store, that was created as HTTP requests were handled, had a default state that was updated from the previous request.

So, that's for my mistake - I miss working with you by the way, you probably never would have let me do such a rookie mistake.

Naively, I think redux-act probably could help the developers not do the same mistake I did.

Indeed, this would have never happenned if the createReducer function either:

- Deep cloned the default state object

I would never have updated the default state object, though I probably would never have noticed that I was wrongly using redux update pattern.

- Deep froze the default state object

I would have never been able to modify the default state object, it would have failed silently, or thrown a TypeError if I was doing 'use strict' in my reducer function.

Now, I understand that it's the developer's responsability to not mutate the default state and JavaScript is mutable by default, but as redux-act is an opiniated lib aiming at making redux less error-prone, I was thinking that, maybe, redux-act could help me on this.

Let me just quote the project's FAQ

You never know what the new dev on your project might do... Maybe (s)he will not realize that [...] and now everything is broken and a wormhole will appear and it will be the end of mankind. Let's prevent that!

What do you think?

Thanks for reading :)

Useful reading on the topic, for those it may concern:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePatterns.html

Duplicate action type

Hi,

When use redux-act with next.js in my project, after page changes i receive this error:

TypeError: Duplicate action type: REQUEST_PAGES
    at check (/home/xxx/www/ucavtor/node_modules/redux-act/lib/types.js:33:11)
    at createAction (/home/xxx/www/ucavtor/node_modules/redux-act/lib/createAction.js:50:22)
    at Object.<anonymous> (/home/xxx/www/ucavtor/site/actions/pagesActions.js:17:29)
    at Module._compile (module.js:660:30)
    at Module._compile (/home/xxx/www/ucavtor/site/node_modules/source-map-support/source-map-support.js:492:25)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Module.require (module.js:604:17)

I think that problem is in HMR.

have someone any idea how i can fix that? At this moment i restart server after any changes.

Not needed property - meta: undefined

screenshot 330

export const request = createAction('SEARCHRESULTS_REQUEST_ITEMS');
export const success = createAction('SEARCHRESULTS_SUCCESS_RESPONSE_ITEMS');

...

dispatch(success(items));

Is really looks like not needed, please fix that.

How to assign async functions to store?

I could not run assignAll after I added an async function.

Uncaught TypeError: actions[action].assignTo is not a function

Do I have to manually call dispatch on my async functions?

createAsyncAction idea

Here is some idea of API for async actions creation:

import {createAction, createAsyncAction} from 'redux-act';

// createAsyncAction 1st argument is function that returns promise. 
const fetchComments = createAsyncAction((id) => {
  return fetch(`api/post/${id}/comments/`);
});

// action will be used like fetchComments(41);

// reducer will have .onAsync method and it'll be called 2 times
// 1st time with loading = true and empty err / result
// 2nd time with loading = false and error or result data basing on if promise was rejected or not
reducer.onAsync(fetchComments, (state, loading, error, result) => {
  return {
    ...state,
    comments: {
      loading,
      error,
      result
    }
  }
})

// leter on I can:
fetchComments.asignTo(store);
fetchComments(42);

What do you think?

Enchancements

Hi, I found you library very similar to my vision. I'm going to make some improvements to API and behaviour, if you open to request, I wiil be glad to contributing to you project

Purpose of `off` function in `createReducer`

As I understood off function in createReducer is supposed to remove some action handler on some condition. In my opinion this is wrong approach because this should be handled by state.

Instead of writing:

const reducer = createReducer(function (on, off) {
  on(increment, state => {
    // Just for fun, we will disable increment when reaching 2
    // (but we will still increment one last time)
    if (state === 2) {
      off(increment);
    }
    return state + 1;
  });
}, 0);

we should write:

const reducer = createReducer(function (on, off) {
  on(increment, state => state > 2 ? state : state + 1);
}, 0);

I do not see other off usages.

Removing off will allow to simplify createReducer signature to:

const reducer = createReducer(increment, state => state > 2 ? state : state + 1, 0);

Allow the on function accept multiple action creators

Consider following situation:

import {createActionAsync} from 'redux-act-async' // https://github.com/FredericHeem/redux-act-async

const create = createActionAsync('CREATE', createUser)
const update = createActionAsync('UPDATE', updateUser)

const initialState = {
  saving: false
}

const reducer = createReducer(function (on) {
  on(create.request, update.request, (state) => ({
    ...state,
    saving: true
  }))
}, initialState)

Enhancement: Spread payload by default

Is there any possibility of spreading ...payload to the reducer by default?

Having the change in syntax between single and multiple arguments is inelegant:

const foo = createAction('foo');
const bar = createAction('bar', (...args) => args);

const reducer = createReducer({
    [foo]: (state, a) => {...},
    [bar]: (state, [a, b, c]) => {...}
});

dispatch(foo('a'));
dispatch(bar('a', 'b', 'c'));

Whereas it would be really killer to have the 1:1 correspondence. Maybe it is just me, but this is what I intuitively thought would happen before I read the docs.

const foo = createAction('foo');
const bar = createAction('bar');

const reducer = createReducer({
    [foo]: (state, a) => {...},
    [bar]: (state, a, b, c) => {...}
});

dispatch(foo('a'));
dispatch(bar('a', 'b', 'c'));

This is completely backward compatible.

Redux Logger incorrectly exported

I was trying to use the logger as documented with Redux logger however I got a 'Cannot read property 'reduxLogger' of undefined.

Looking at the source code it seems that logger might be incorrectly exported?

export { default as loggers } from './loggers';

Since logger is in its own folder now, I'm guessing this is just an update that needs to be made?

Allow a variety of action type names

const isSerializable = (typeof description === 'string') && /^[A-Z_]+$/.test(description)

I notice this calls only CONSTANT_STYLE strings serializable. However, I'm starting to think that I want to name my actions differently, for example, actions that affect the game key of the state could be called game.begin/game.end.

Is there a reason for keeping things so locked down to the Abramov-school of action types? Or can this library enable some broader conventions ? Curious for your thoughts, my want would be to permit valid JS identifiers, or a few of them separated by dots. The CSS-ers may also want to allow dashes.

Object.assign and cross-browser compatibility

o/ @pauldijou

I was wondering if you would consider adding a new babel plugin to transform Object.assign to a inline helper,
as it's an es2015 feature and the browser support, though ~correct, is not wide enough to be safely used in production.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Browser_compatibility

We've been dodging this issue by patching globals so far, but we'd like to move away from that.

More than happy to open a PR to make use of transform-object-assign, or discuss this further :)

Thank you for your time,

Conflict with hot reload

I am using https://github.com/milankinen/livereactload for hot reloading my code during development. And I am using redux-act with serializable actions so I can store reliably export and import my state with the dev tools during development.

Trouble is: When my code get's reloaded, it throws TypeError: Duplicate action type, because actions are added again. Like most hot reloading solutions, livereactload offers a hook to run on reload but those hooks are run after the module is ran, so the error is already thrown and using types.clear() in the hook would be too late.

Any idea how to solve this?

How to use types.disableChecking() ?

It is does not work:

  if (module.hot) {
    module.hot.accept('src/ducks', () => {
      // Disable all type checking meaning you can now have several actions
      // with the same type. This is needed for HMR (Hot Module Replacement)
      // but never never never enable it in production
      types.disableChecking();
      const nextRootReducer = require('src/ducks/index').default;
      store.replaceReducer(nextRootReducer);
      // Set back type checking
      types.enableChecking();
    });
  }

I see error:

[HMR] TypeError: Duplicate action type

Please give to me example.

Why metadata?

Starting to use your wonderful library. Have only done basic Redux so far, but already hate all the boilerplate.

I was wondering if you had an example or two on the purpose of metadata in actions and reducers? I understand it's for "extra" data that isn't explicitly needed for the action. However, Redux (http://redux.js.org/docs/basics/Actions.html) seems to make no mention of it. And, I've seen it mentioned else, but haven't found an example of its use.

Could you give tangible and/or real-world example of metadata and its applicability?

using actions with middleware

Hey man, thanks for the library! I was wondering how we can handle simple conditionals like these

function middleware (stuff) {
  return ({ dispatch }) => next => action => {
    if (action.type === SOME_ACTION) {
      // do something
    }
  }
}

A createReducer seems not appropriate for the use case here.

createReducer accepts an undefined action

Hey there,

I've recently been dealing with a strange issue caused by circular dependencies where the action creator I pass into createReducer actually turns out to be undefined: https://github.com/erikras/ducks-modular-redux/issues/24

I know it isn't the most likely scenario, but I think it would be a good sanity check if redux-act would throw an error if one of the action creators it is handling is undefined.

For example, this doesn't throw any error:

createReducer({
  [undefined]: () => {
    return {
      hello: 'world'
    }
  }, {})

Let me know what you think,
Thanks!
Thomas

How to process NotFound action

If I send a action with no register in reducer, How to catch it in redux-act?

Normal:

switch (action.type) {
  case 'MY_ACTION':
    // ...
  default:
    // I need process this
    return formReducer(state, action)
}

Redux act

createReducer({
  MY_ACTION: () => {},
  ???
})

allow for composing reducers returned by createReducer?

Hi, I'm wondering if this is a general pattern:

After creating a reducer via combineReducers, where each sub-reducer minds its own part of the state tree, I want to apply some preReducers that do 'global' state mutations and which pre-empt the behavior of the others. I've written this code:

(origReducer, preReducers = []) => {
  // return a reducer which calls origReducer only if none of the prereducers has changed the state
  return (state, action) => {
    for(let reducer of preReducers) {
      let newState = reducer(state, action)
      if (newState != state) return newState
    }

    return origReducer(state, action)
  }
}

My question is do you think this is deserving of its own name or case in this library? Example use cases are global reducers that might move parts of the state tree around, or otherwise break the narrow guidelines laid down by combineReducers. Thanks, Dean

Issue in Readme.md

Hi gyes.
It seems that you need to correct your code right here.

// Little bonus, if you need to support metadata around your action,
// like needed data but not really part of the payload, you add a second function
const metaAction = createAction('desc', arg => arg, arg => {meta: 'so meta!'});

Transpiler compile it to something like that

var metaAction = createReducer('desc', function (arg) {
  return arg;
}, function (arg) {
  meta: 'so meta!';
});

So I assume that you forget the braces because you need to make it expression.
Something like this.

arg => ({meta: 'so meta!'})

Wondering if anyone has experienced issues with this approach

Hey there,

I'm currently using redux-act in a small project and finding it to be very nice to work with. I like how little boilerplate needs to be written, which in turn makes things all the more easier for me to understand.

That said, I haven't used it on a larger/more complex project, and I'm wondering if there are any downsides to using the redux-act approach? I know that it is all redux under the hood, but I'm mostly worried about compatibility issues, like other libraries or patterns that can't be used in conjunction with the redux-act way of creating reducers/actionsCreators.

Thanks for the library and your advice,
Thomas

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.