question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

handleActions returning defaultState even when state passed is not undefined

See original GitHub issue
import { handleActions } from 'redux-actions';

const getInitialState = () => {
    return ['red'];
};

const reducer = handleActions({
    test: (state, action) => {
        return action.payload.a ? undefined : ['yellow'];
    },
    test2: (state) => {
        return ['1'];
    }
}, getInitialState());

const reducer2 = handleActions({
    test: (state, action) => {
        return action.payload.a ? undefined : ['yellow'];
    }
}, getInitialState());

console.log(reducer(['green'], {
    type: 'test',
    payload: {
        a: 1
    }
}));
// ['red']

console.log(reducer2(['green'], {
    type: 'test',
    payload: {
        a: 1
    }
}));
// undefined

The first console statement returns the defaultState which is ['red'] whereas the second console statement returns undefined even though they both respond to the same action and have same action handling logic. Can someone tell me why is this happening?

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:22 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
amit1911commented, Mar 4, 2017

The issue is not with this library, it’s actually because of reduce-reducers which is being used by handleActions. reduce-reducers reduces multiple reducers into one reducer by the following code

export default function reduceReducers(...reducers) {
  return (previous, current) =>
    reducers.reduce(
      (p, r) => r(p, current),
      previous
    );
}

So the reason why test case A fails is because since the first reducer inside handleActions returns undefined, the second reducer will get undefined as the initial state and will return the default state. But if we push the test reducer to the end inside handleActions, then it will receive the actual state and will return undefined. So the following test case will pass.

it('A', () => {
        const reducer = handleActions({
            test2: (state) => {
                return ['1'];
            },

            // add this at the end
            test: (state, action) => {
                return action.payload.a ? undefined : ['yellow'];
            }
        }, defaultState);

        expect(reducer(['green'], { type: 'test', payload: { a: 1 } })).to.deep.equal(undefined);
    });

So I don’t think there is anything to fix here since reducers should not be returning undefined in the first place, but it’ll be good if an error is thrown when a reducer returns undefined so that the user knows there is a problem, otherwise the reducer might return incorrect state which might lead to unexpected results in the application

0reactions
mslippercommented, Jan 16, 2018

@amit1911 thanks for doing the digging here. Are you still interested in implementing a PR that does error checking for cases like this, or shall I try my hand at it?

Read more comments on GitHub >

github_iconTop Results From Across the Web

handleAction(s) - redux-actions
The third parameter defaultState is required, and is used when undefined is passed to the reducer. EXAMPLE. handleAction(. 'APP/COUNTER/INCREMENT',. (state ...
Read more >
How to reset the state of a Redux store? - Stack Overflow
Our fix was to not set the state to undefined but rather still use the ... you call RESET action, you reducer will...
Read more >
Why is my useSelector returning undefined but my state is ...
This mutates the state. Never do that! The whole point of a reducer is that it returns a new state and does not...
Read more >
redux-standard-actions - npm
Returns an object mapping action types to Flux Standard Action creators. ... a default state which is used when an undefined state is...
Read more >
Redux update an item in an array of objects
If a Redux reducer directly mutates, and returns, the state object passed into it, ... objects, arrays, maps, sets or even custom defined...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found