Redux action and async/await functions have different behavior at class component and functional

Viewed 564

I've been working on a Next.js app with these dependencies:

"react": "^16.9.0",
"react-redux": "^5.0.7",
"redux": "^4.0.4",

One of my redux action that creates the stepsNameThatMustBeShown (a property of redux state) is:

export const setInitialSteps = () => {
     //.....
     // some codes that creates the stepsNameThatMustBeShown array
     //....
    return {
        type: ActionTypes.SET_QUICK_RESUME_GENERATOR_MODAL_INITIAL_STEPS,
        data: stepsNameThatMustBeShown
    }
};

And I used this snippet in two different places in my app, in a class component and a functional component.

<button onClick = {
    async () => {
      await this.props.setInitialSteps();
      if (this.props.stepsNameThatMustBeShown.length > 1) {
        this.props.setCurrentStep(this.props.stepsNameThatMustBeShown[0]);                                                               
        this.props.setQuickResumeDisplayStatus(true);                                                                    
        this.props.setUnUpdatedStepsName([...this.props.stepsNameThatMustBeShown]);
      }
    }}>
      Open
</button>
//....
//...


 const mapStateToProps = (state) => {
    return {
        stepsNameThatMustBeShown: state.quickResumeGeneratorModal.stepsNameThatMustBeShown,
    };
};


function mapDispatchToProps(dispatch) {
   return {
            setQuickResumeDisplayStatus: bindActionCreators(setQuickResumeDisplayStatus, dispatch),
            setInitialSteps: bindActionCreators(setInitialSteps, dispatch),
            setCurrentStep: bindActionCreators(setCurrentStep, dispatch),
            setUnUpdatedStepsName: bindActionCreators(setUnUpdatedStepsName, dispatch),
        }
    }

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

Obviously, I didn't use this.props in a functional component. All those functions in the code snippet are redux actions. In the code snippet, I updated the property of the redux state and I used it right after it updated. In the class component async and await keywords work as we expected, but in the functional component await keyword doesn't work correctly. I read some related questions that exist in this community but none of them couldn't help me to resolve my problem.

1 Answers

You need to use react-redux 7.1 or later in order to use const dispatch = useDispatch() in your functional component and then call dispatch() in your onClick handler.

In your functional component use:

const dispatch = useDispatch()

and then your handler will look like below:

<button onClick = {
    async () => {
      const action = this.props.setInitialSteps(); // <======
      dispatch(action); // <=====
      if (this.props.stepsNameThatMustBeShown.length > 1) {
        this.props.setCurrentStep(this.props.stepsNameThatMustBeShown[0]);                                                               
        this.props.setQuickResumeDisplayStatus(true);                                                                    
        this.props.setUnUpdatedStepsName([...this.props.stepsNameThatMustBeShown]);
      }
    }}>
      Open
</button>

Again all the async stuff that you have is not needed here in your use case.

Related