Ron Smith
Ron Smith

Reputation: 307

How to organize the business logic in React+Redux+thunk

I work on a front end which uses react + redux.

As we all know, redux creates a container component which is responsible for hosting the business logic. Practically, we will provide mapStateToProps and mapDispatchToProps to the connect function, with mapDispatchToProps we can dispatch events to the reducer.

There is wizard functionality that has many kinds of type, and each one has more than 10 steps, so I want to organize the "next step", "previous step" command and calling the child element function such as validation when the buttons are clicked, but I think "ref" is not the recommended way to do this. But with the original design of redux, I must dispatch event in below code

 const mapDispatchToProps = (dispatch, ownProps) => ({
    onNext: () => {
        dispatch(nextStep());
    }
}

Where and how to call the validation of child control is an issue, with redux design, maybe we should handle it in action creator, but I think it is a action with asyn request or just a plain object, it should not process the logic, since we introduce the container object to handle "how does it works".

So I expose a controller in child container as below:

export {
  childContainer,
  childNavController
};

The child container used to render the child element and logic, childNavController to expose validation function. but in this way we don't have access to dispatch object, so I do it below:

 const mapDispatchToProps = (dispatch, ownProps) => ({
    onNext: () => {
        dispatch(nextStep(wizardCreator));
    }
}

const wizardCreator= (step) => {
  // according to the step return different controller instance
  return childNavController;
};

In the action creator file:

const nextStep=(childCreator)=>{
   return function (dispatch, getState) {
     return Promise.resolve().then(()=>{
        const currentState = getState();
        const controller=childCreator(currentState.step);
        // this make the business also can work with dispatch object
        controller.validation(dispatch, getState);
     });
   }
}

This is a way make sense, but I also thought it is strange, no OO, no elegant design, just to get it work.

Does anyone have a suggestion about how it should be designed for this scenario?

Upvotes: 2

Views: 1197

Answers (1)

Iván Wolf
Iván Wolf

Reputation: 21

It is not mandatory to use mapDispatchToProps in order to dispatch action inside a component. Just for calling connect(null)(Component) the component receives the dispatch function as a prop. Then you could define a method and do de logic for validation before dispatching the action you need.

For example,

import React from 'react';
import { connect } from 'react-redux';

const Container = (props) => {
  const onClick = () => {
    // some logic
    if (valid) props.dispatch(someAction())
  }
  return <button onClick={onClick}>Next</button>
}

export default connect()(Container);

Upvotes: 1

Related Questions