Search code examples
reactjsreduxreact-reduxredux-thunk

Actions not dispatching


When I run an action creator to create my thunk, it does not run the dispatch functions.

For testing, I put a button in my root component's render method, my root component is connected thusly (removed extraneous things):

import { loadAndSetCurrentUser } from '../Actions/SedFF';
import { setSysMenuExpand, setNavMenuExpand, setLoginDialogVisibility } from '../Actions/UI';

render() {
    return (
        <button onClick={() => 
            loadAndSetCurrentUser("[email protected]")}>LASCU</button>
    )
}

const mapStateToProps = function (state) {
    return {
        UI: state.UI,
        sedff: state.SedFF,
    }
}

const mapDispatchToProps = {
    loadAndSetCurrentUser,
}


export default withStyles(styles, { withTheme: true })(withRouter(connect(mapStateToProps, mapDispatchToProps)(WebFF)));

My Actions Creators file looks like this:

export function loadAndSetCurrentUser(username) {
    console.log("LASCU: " + username);
    return (dispatch, getState) => {
        console.log("in dispatch");
        dispatch(this.requestingUserData(username)); 

        const user = getState().Users[username];
        if (user) {
            // if already in store, just change the current username  
            //FUTURE: check date against user mod date in database
            dispatch(setCurrentUsername(username));
            dispatch(userDataLoadComplete());
        } else {
            // user not in store, need to check database //TODO:
            fetch('https://jsonplaceholder.typicode.com/users?username=Bret')
                .then(response => response.json())
                // .then(json => delay(3000, json))
                .then(json=> dispatch(ingestUserData(json)))
                .then(() => dispatch(userDataLoadComplete()));
        }
    }
}

export function requestingUserData(username) {
    console.log("RUD");
    return { type: REQUESTING_USER_DATA, username };
}

export function setCurrentUsername(username) {
    return { type: SET_CURRENT_USERNAME, username }
}

export function ingestUserData(userData) {
    return (dispatch) =>
        {
            console.log("IUD");
            console.log(userData);
            dispatch({ type: SET_USER_DATA, userData })
        }
}

export function userDataLoadComplete() {
    return { type: USER_DATA_LOAD_COMPLETE };
}

And my reducers are bone-stock, looking like this:

export function SedFF(state = initialSedFFState, action) {
    let newState = _.cloneDeep(state);
    switch (action.type) {
        case SET_CURRENT_USERNAME:
            newState.currentUsername = action.username
            return newState;
        case LOAD_USER_DATA:
            //TODO: 
             return newState;
        case REQUESTING_USER_DATA:
            newState.isFetchingUserData = true;
            return newState;
        case RECEIVED_USER_DATA:
            //TODO:
            newState.isFetchingUserData = false;
            return newState
        case USER_DATA_LOAD_COMPLETE:
            //TODO:
            newState.isFetchingUserData = false;
            return newState

... etc, etc...

        default:
            return state
    }
}

When I hit the LASCU button, I get the following output: LASCU: [email protected] coming from my action creator (noted on the second line of the action creator file above). I do NOT get the in dispatch output on the 4th line of my action creator file. I do NOT get any actions firing.

I'm unsure why the dispatch is not firing.

I will note that on a different component (a sub-component), I can get it to fire the entire thing, but I'm unable to find any differences. The only real difference appear to be that I don't have the router in the export line: export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(SystemMenu));

For what it's worth, my thunk middleware is connected at the App.js (parent of my root component) like so:

const store = createStore(
    RootReducer, 
    initialState, 
    composeEnhancer(applyMiddleware(thunk))
);

class App extends React.Component {

    render() {
        return (
            <Provider store={store}>
                <CssBaseline />
                <BrowserRouter>
                    <WebFF />
                </BrowserRouter>
            </Provider>
        );
    }
}


export default withStyles(styles, { withTheme: true })(App);

Thoughts? Help?


Solution

  • Looking at the render method given in the question, the issue appears to be that you're calling the original imported function, not the bound function from props. In other words, changing to this.props.loadAndSetCurrentUser() should work correctly. Note that you shouldn't be importing the store directly into a component file.

    For more details, please see the React-Redux usage guide docs page on "Dispatching Actions with mapDispatch".