tgun926
tgun926

Reputation: 1633

Redux - conditional dispatching

Classic problem - I want to validate a form before submitting it.

My submit button triggers an action (simple dispatch or thunk). If the form is valid, submit it - else, trigger an error message.

The simple solution: dispatch an action e.g. VALIDATE_AND_SUBMIT, which in the reducer will validate the form, and submit or set an error state.

I feel like these are two different actions: VALIDATE

{
   type: "VALIDATE",
   formData
}

This should validate and set errors.

{
   type: "SUBMIT",
   // get form data and errors from state
}

SUBMIT - should submit provided there's no error state.

Even if I use redux-thunk, I can't get feedback from the first VALIDATE action. Is my thought process anti-pattern here? How can I validate before submitting a form?

Upvotes: 4

Views: 9953

Answers (3)

Michael Peyper
Michael Peyper

Reputation: 6944

I think part of your issue is think of actions as something that is happening rather than something has caused the state to change.

"Validate" is not an action. "Validation failed" is the action.
"Submitting" the data is not an action. "Data was submitted" is the action.

So if you structure your thunk with that in mind, for example:

export const validateAndSubmit = () => {
    return (dispatch, getState) => {
        let formData = getState().formData

        if (isValid(formData)) {
            dispatch({type: "VALIDATION_PASSED"})
            dispatch({type: "SUBMISSION_STARTED"})

            submit(formData)
                .then(() => dispatch({type: "SUBMITTED" /* additional data */}))
                .catch((e) => dispatch({type: "SUBMISSION_FAILED", e}))
        }
        else {
            dispatch({type: "VALIDATION_FAILED" /* additional data */})
        }
    }
}

Upvotes: 15

aaa
aaa

Reputation: 601

Classical and whole solution:

Hold the entire form in your state, for example:

{
  valid: false,
  submitAttempted: false,
  username: '',
  email: '',
}

Add onInput event to your form inputs and track their state validating on every change.

So when the user submits, you can check the valid state and react.

redux-form was built just for that.

Assuming you don't want to hold the entire form state

In this case, you'll have to validate and then submit.

Here's an example assuming using react-redux with mapStateToProps and mapDispatchToProps

// action in component
submitButtonAction() {
  props.validate();
  if(props.formValid) props.submitForm();
}

// JSX
<FormSubmitButton onClick={this.submitButtonAction} />

Upvotes: 0

challenger
challenger

Reputation: 2214

why don't validate form before dispatching, and dispatch the appropriate action? or you can use redux middle-ware click here

Upvotes: 0

Related Questions