2

I was wondering how people handle form validation. Currently I have inputs that have "isValid()" method on them and in the form component, I have to call

if(this.refs.username.isValid()
   && this.refs.firstName.isValid()
   && this.refs.lastName.isValid()
   && this.refs.email.isValid()
   && this.refs.password.isValid()
)

and that's just the beginning of the boilerplate. If I could iterate through this.props.children and call isValid on them that would go a long way but I can't seem to make that work.

I also can't seem to iterate through this.refs and do it dynamically like that either. I think. Pretty sure I tried that.

But basically if I can't interrogate my component's children and call methods on them then there is going to be a ton of boiler plate code in my/everyone's app.

Has anyone dealt with this yet?

Thanks,

r

EDIT - some code to demonstrate what I've tried

React.Children.map(this.props.children, function (
    var valid = child.isValid();
});

Here child has props, ref, and type. This is helpful in general but not in my situation. I want to have access to the actual instance so I can call an is valid function on it.

EDIT again

I appreciate the pointer to another answer, however, I don't feel it is a similar question. I'm not asking HOW to validate, I'm asking whether anyone has found any good ways to wrap up validation. The answer given in the other post is basically just like my example above, very verbose and repetitive, they only show one field on a form so it doesn't look too bad but trust me after a couple of forms you are going to want to kill yourself.

So to clarify, I'm asking, given the repetitive nature of asking every child component if they are in a valid state, and if not, what error do they have and then aggregating that information, is there a better way. Perhaps if you could dynamically iterate through the children you could wrap the functionality up, but I have not been able to do that.

EDIT again

Here is a repo where I was messing with this stuff.

https://github.com/reharik/react-demo/tree/master/src

It's basically an editable display form or whatever. You go to the page and can view the data but if you want to edit it click the button. Edit the form and submit. That's just what I was playing with, it could just as easily be a "RHForm" that is used for all regular forms.

it's pretty simple the RHInput validates on change and also has an IsValid() method. Currently the app.jsx has to call isValid() on all it's children. If you look at RHEditableForm you'll see that this would be a perfect place to dynamically call IsValid() on whatever happens to be in there. This could be reused by all forms and I'd never/rarely have to write validation logic. Also since this is where the "OK" button is it also seems like the correct place to put validation.

9
  • Maybe look at: facebook.github.io/react/docs/top-level-api.html#react.children. Please add the code you've tried so we can help. Commented Apr 1, 2015 at 0:37
  • thanks for the response. I just tried that method ( which I didn't know about, thank you ) however, I don't see how it's any different than doing an _.map. I get an object back but it does not have any of the methods that are on the child. I do get the ref name but I don't see how to use that to get the actual child object. I'll show some code above. Commented Apr 1, 2015 at 0:56
  • possible duplicate of How to properly validate input values with React.JS? Commented Apr 1, 2015 at 1:14
  • Ahh .. no, the children helpers won't be of any help. They only represent what will be created later, not actual instances. You can use ref: jsfiddle.net/wiredprairie/wk8eo9v4 Commented Apr 1, 2015 at 1:48
  • yes that will work. It'll be better than typing it out. It would be great if I could have a form element with a cancel and save button that then had nested inputs. Perhaps I should consider using flux for this. I mean I"m using flux for data, but I might could fire action every time an input changes with the validity etc of the input. but I wonder if that's not going to be action explosion. Commented Apr 1, 2015 at 2:17

1 Answer 1

0

Your question intrigued me, so far I haven't run into a problem like this, nonetheless the problem you raised is a legit one. So, after playing a little bit with react, I kinda found a solution that avoids looping through refs or children (actually if loops over children but not when validating).

The solution I found is to use react component wrappers over each form field, and a react element for the form itself. When rendered, the form react component clones each child with an extra onComponentMounted property. It's called by the form fields when they are mounted. From here, things are simple. The onComponentMounted callback will add the field to a "fields" state property, property that will be iterated when the form is submitted; controls that expose an "isValid" method will be asked to validate.

This approach allows for easy form constructions like the following:

React.render(<ValidatingForm>
        <TextField name="firstName" />
        <TextField name="lastName"/>
        <TextField name="email" />
        <TextField name="password" />
        <button type="submit">Signup</button>
        </ValidatingForm>, document.getElementById('form1'));

The full source can be found here: http://jsfiddle.net/6tjz2b6r/. For simplicity there's only one control supported: TextField; however, other types of controls can be easily added.

Sign up to request clarification or add additional context in comments.

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.