Redux: dispatch(action) calls reducer twice but this.props.function not

Created on 22 Oct 2015  路  2Comments  路  Source: reduxjs/redux

Hello,
I got a strange problem and I have no idea what causes this.
The approach that I am using is the mapStateToProps / mapDispatchToProps.

The strang thing is:

  • When I call the action through the function I am passing in through mapDispatchToProps, the reducer gets only called once.
  • When I am using the this.props.dispatch(action) the reducer gets called twice.

The logger shows that the state is changed to true but then the reducers gets called again and its set back to false again.

For better understanding, here's the code a code sample.

Action creator:

//../actions/shellActions
import { TOGGLE_SIDEBAR } from '../constants/actionTypes';
export function toggleNavigation() {
    return {
        type: TOGGLE_SIDEBAR
    }
}

Reducer

//../reducers/navigationReducer
import { TOGGLE_SIDEBAR } from '../constants/actionTypes';

export default function toggleSidebar(state:boolean=false, action:any) {
    let hideSidebar = !state;
    switch (action.type) {        
        case TOGGLE_SIDEBAR:
            return hideSidebar;
        default:
            return state;
    }
}

//../reducers/rootReducer
import { default as toggleSidebar } from './navigationReducer';

const rootReducer: Redux.Reducer = combineReducers({
    toggleSidebar: toggleSidebar
});

export default rootReducer;

Container

import * as React from 'react';
import { connect } from 'react-redux';
import { toggleNavigation } from '../actions/shellActions';

class App extends React.Component<any, any> {
    constructor(props) {
        super(props);
    }

    onToggle() {
        //this.props.toggleNavigation(); This gets called once
        this.props.dispatch(toggleNavigation()); // This gets called twice
    }

    render() {
        return (
            <div className={ isSidebarVisible ? "body-container" : "body-container sidebar-open"}>
                <button onClick={ this.onToggle.bind(this) }>Toggle</button>

            </div>
        );
    }
}


function mapStateToProps(state: RootState):AppProp {
    return {
        isSidebarVisible: state.toggleSidebar
    };
}

function mapDispatchToProps(dispatch) {
    const actions: AppProp = {
        dispatch: dispatch,
        toggleNavigation: toggleNavigation
    };

    return bindActionCreators(actions, dispatch);
}

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

Maybe I did something wrong.
Thanks

question

Most helpful comment

If you're using bindActionCreators and mapDispatchToProps, the action creators _are already bound_. There is no need to call dispatch() on their return values. The whole point of bindActionCreators() is _not_ to call dispatch(). You should either bindActionCreators() and call them as is, or not use it, and call dispatch().

All 2 comments

If you're using bindActionCreators and mapDispatchToProps, the action creators _are already bound_. There is no need to call dispatch() on their return values. The whole point of bindActionCreators() is _not_ to call dispatch(). You should either bindActionCreators() and call them as is, or not use it, and call dispatch().

Thank you for the explanation @gaearon.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mickeyreiss-visor picture mickeyreiss-visor  路  3Comments

jbri7357 picture jbri7357  路  3Comments

amorphius picture amorphius  路  3Comments

dmitry-zaets picture dmitry-zaets  路  3Comments

jimbolla picture jimbolla  路  3Comments