Remote Submit Example

This example demonstrates how a form may be submitted by dispatching a SUBMIT action from an unrelated component or middleware.

The "Submit" button you see here is not connected to the form component in any way; it only dispatches an action via Redux.

Notice that for this to work, the submit function must be given to the form component via either a config value passed to reduxForm() or via a prop.

Running this example locally

To run this example locally on your machine clone the redux-form repository, then cd redux-form to change to the repo directory, and run npm install.

Then run npm run example:remoteSubmit or manually run the following commands:

cd ./examples/remoteSubmit
npm install
npm start

How to use the form below:

  • Usernames that will pass validation: john, paul, george, or ringo.
  • Valid password for all users: redux-form.

Form

No submit button in the form. The submit button below is a separate unlinked component.

Values

undefined

Code

submit.js

import { SubmissionError } from 'redux-form'

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

function submit(values) {
  return sleep(1000) // simulate server latency
    .then(() => {
      if (![ 'john', 'paul', 'george', 'ringo' ].includes(values.username)) {
        throw new SubmissionError({ username: 'User does not exist', _error: 'Login failed!' })
      } else if (values.password !== 'redux-form') {
        throw new SubmissionError({ password: 'Wrong password', _error: 'Login failed!' })
      } else {
        window.alert(`You submitted:\n\n${JSON.stringify(values, null, 2)}`)
      }
    })
}

export default submit

RemoteSubmitForm.js

import React from 'react'
import { Field, reduxForm } from 'redux-form'
import submit from './submit'

const renderField = ({ input, label, type, meta: { touched, error } }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} placeholder={label} type={type}/>
      {touched && error && <span>{error}</span>}
    </div>
  </div>
)

const RemoteSubmitForm = (props) => {
  const { error, handleSubmit } = props
  return (
    <form onSubmit={handleSubmit}>
      <Field name="username" type="text" component={renderField} label="Username"/>
      <Field name="password" type="password" component={renderField} label="Password"/>
      {error && <strong>{error}</strong>}
      <div>
        No submit button in the form. The submit button below is a separate unlinked component.
      </div>
    </form>
  )
}

export default reduxForm({
  form: 'remoteSubmit',  // a unique identifier for this form
  onSubmit: submit       // submit function must be passed to onSubmit
})(RemoteSubmitForm)

RemoteSubmitButton.js

import React from 'react'
import { connect } from 'react-redux'
import { submit } from 'redux-form'

const style = {
  padding: '10px 20px',
  width: 140,
  display: 'block',
  margin: '20px auto',
  fontSize: '16px'
}

const RemoteSubmitButton = ({ dispatch }) =>
  <button
    type="button"
    style={style}
    onClick={() => dispatch(submit('remoteSubmit'))}>Submit</button>
//                                  ^^^^^^^^^^^^ name of the form

export default connect()(RemoteSubmitButton)