24

This question relates to Redux Form v6.0.0 (in time of writing this question it is v6.0.0-alpha.15).

How can I get form validation status (like pristine, submitting, invalid) from outside of form component ?

Let me give an example. This is "classical redux-form" pseudo-structure:

<Form(MyExampleForm)>
    <MyExampleForm>
        <input name="title" ... />
        <submit-button />

...where <submit-button> in JSX looks like this:

<button type="submit" disabled={pristine || submitting || invalid} >Save</button>

But in my application, my submit button must be outside of the form, placed on different place in the application (let's say in application header, on the top of whole application).

  1. How can I get those pristine, submitting, invalid from outside of Redux-Form? (Without really nasty hacking, if possible :-))
  2. How can I submit that form?
2
  • don't know about redux-form, but, submitting a form with a button outside it already sounds hacky... why this requirement? Commented Jul 6, 2016 at 12:31
  • 2
    @jordi-castilla > Please don't look for the problem in the assignment, but try to find a solution. Answer to your question is already in question. (Because of UI, 'save buttons' are central in whole application and placed in application header - on the very top of application.) Commented Jul 6, 2016 at 13:06

7 Answers 7

14

Just decorate another component with same form name and you have access to same state variables there. Also you can pass it onSubmit function from parent and be able to submit all the Field values from wherever you define them as they are all from redux state, not HTML of current form instance. (it is kind of "hacky" way, but it feels right)

The submit function is defined from parent, not shared in state, so you can have it different for every instance.

class MySubmitForm extends React.Component {
    render() {
        return (
            <button
                onClick={this.props.handleSubmit}
            >
                {this.props.pristine ? 'pristine' : 'changed'}
            </button>
        )
    }
}

export default reduxForm({
    form: 'myFormName'
})(MySubmitForm);
Sign up to request clarification or add additional context in comments.

3 Comments

@oldo.nicho I think in current version you should be able to easily use global action creators to control it. It was not available in time when I wrote the answer. redux-form.com/6.5.0/docs/api/ActionCreators.md
Very nice - you're right. The more I learn about this library the more I'm impressed by it!
I'm not sure this works anymore. The click handler returns a Synthetic click event. I'd recommend @FerA320's answer if you're using 7.x.x
4
+125

redux-form works with React Redux to enable an html form in React to use Redux to store all of its state.

If "outside of Redux-Form" means still redux application, you can try to store those properties in state by dispatching some actions.

In forms: you're detecting whats happening (when its invalid etc), dispatch an action to modify a state, In "outside" part: you're passing a proper property to component (with those you need) and depends on that you disable a button.

Comments

3

in latest redux-form version 6.0.2:

  1. it is possible to access form state pristine, submitting, invalid via selectors http://redux-form.com/6.0.2/docs/api/Selectors.md/

  2. it is possible to export redux-form action creators http://redux-form.com/6.0.2/docs/api/ActionCreators.md/

2 Comments

@Soson it doesn't seem like submitting is available via selector? Or am I looking at the wrong place?
Though incorrect But useful piece of information related to this context
2

Maybe you can have a look at the Instance API of redux-forms. It provides access to a submit() method on an instance of your decorated form component. There is also a pristine Boolean property and an invalid Boolean property available (there is a request to expose the submitting property too).

There is an example here : http://redux-form.com/5.3.1/#/examples/submit-from-parent?_k=jgv0m4 (example is for 5.3.1, but the process is similar with v6 using the Instance API)

The basic idea is that by adding a ref="myExampleForm" to your form, you can pass it around with this.refs.myExampleForm. You can then check properties of the instance or call the submit() method (or any other method exposed).

Comments

2

Now is easier to do this. You can call the Submit action in the standalone component that has the button.

See this example: https://redux-form.com/7.1.2/examples/remotesubmit/

Comments

1

If we are talking about just submitting the form, then you should provide {withRef: true} option to your redux connect() function.

Consider Row component that has child RowDetail component which has information that should be saved from Row.

RowDetail in this case could be created like this:

import { connect } from 'react-redux';
import { reduxForm } from 'redux-form';

const RowDetailForm = reduxForm({form: 'row-detail-form'})(RowDetail);

export default connect(mapStateToProps, null, null, {withRef: true})(RowDetailForm);

Then, in your parent component (Row) you create your form with ref attribute:

<RowDetailForm ref={'rowDetailForm'} .../>  

Submitting now is 'easy':

onSave() {
  this.refs.rowDetailForm.getWrappedInstance().submit();
}

If we are talking about pristine and other form properties, then you could try to get them from your mapStateToProps function in your parent component.

const rowDetailFormName = 'row-detail-form';
const mapStateToProps = (state) => ({
  rowDetailForm: state.form[rowDetailFormName]
});

But this way seems a bit hacky because as I understand redux-form API all form states were never meant to be accessed directly. Please correct me if I am wrong

Comments

0

I had to tackle this issue recently. I ended up passing a callback to the form, which is invoked every time the properties I'm interested in change. I use the componentDidUpdate life cycle method to detect changes.

This should work on any version of the library.

Here is a post with sample code - http://nikgrozev.com/2018/06/08/redux-form-with-external-submit-button/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.