Search code examples
reactjsreduxreact-reduxredux-thunk

redux-thunk - not dispatching even though I used mapDispatchToProps


I have a weird problem with my redux action.

I have two functions A(), B() inside the same component which call an action function ac() that uses a thunk to do async call to the server.

I used mapDispatchToprops to map ac() to the component.

When I invoke A() it works like a charm, the action is dispatched and state is updated. But if I invoke B() which invokes the same ac() in the same way the action is not dispatched. It is as if I am calling a normal function so the thunk inside is not executed.

Am I missing something here?

EDIT: generateAgreement() works but signAgreement() doesn't, even though they call the same action updateAgreements()

generateAgreement = async evt => {
    evt.preventDefault();

    const selectedAgreement = this.props.myAgreements[evt.target.id];

    this.props.updateAgreements(
      Object.assign(
        {},
        {
          myAgreements: this.props.myAgreements,
          selectedAgreement
        }
      ),
      this.props.user.token,
      "generate-agreement",
      {
        agreementId: selectedAgreement.id
      },
      actionTypes.GENERATE_AGREEMENT
    );
  };

  signAgreement = async evt => {
    evt.preventDefault();

    const selectedAgreement = this.props.myAgreements[evt.target.id];

    this.props.updateAgreements(
      Object.assign(
        {},
        {
          myAgreements: this.props.myAgreements,
          selectedAgreement
        }
      ),
      this.props.user.token,
      "sign-agreement",
      {
        agreementId: selectedAgreement.id
      },
      actionTypes.SIGN_AGREEMENT
    );
  };

Solution

  • I figured out the problem. This is one of the classic examples to avoid using object destructuring all over the place.

    In my case, in my parent component 1 I imported from the actions.js file as follows:

    Component_1.js

    import { updateAgreements } from "../redux/actions.js"
    
    ...
    
    render() {
        return <Child 
            updateAgreements={updateAgreements}
        />
    }
    
    const mapDispatchToProps = {
       updateAgreements
    }
    ...
    

    And in parent component 2 I have the following code which is the reason generateAgreement worked as expected:

    Component_2.js

    import { updateAgreements } from "../redux/actions.js"
    
    ...
    
    render() {\
        const { updateAgreements } = this.props;
        return <Child 
            updateAgreements={updateAgreements}
        />
    }
    
    const mapDispatchToProps = {
       updateAgreements
    }
    ...
    

    Notice that in component_1 updateAgreements is taken from the import statement and in component_2 it is taken from the props.

    I have seen a lot of people warning about overusing destructuring now I see how it can cause subtle bugs like this.